<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Richard Ramsden</title>
  <link href="http://rramsden.ca/atom.xml" rel="self"/>
  <link href="http://rramsden.ca/"/>
  <updated>2011-10-23T16:24:09-07:00</updated>
  <id>http://rramsden.ca/</id>
  <author>
    <name>Richard Ramsden</name>
    
  </author>

  
  <entry>
    <title>Teensy 2.0 USB Problems</title>
    <link href="http://rramsden.ca/blog/2011/10/23/teensy-little-problem/"/>
    <updated>2011-10-23T16:06:00-07:00</updated>
    <id>http://rramsden.ca/blog/2011/10/23/teensy-little-problem</id>
    <content type="html">&lt;p&gt;A few problems I came across playing around with my new Teensy development board. Decided to
make a quick post on some solutions I found. Enjoy :)&lt;/p&gt;

&lt;h2&gt;Problem #1&lt;/h2&gt;

&lt;p&gt;Teensy USB device wasn't being recognized. You can see the list of
registred devices on Ubuntu using &lt;code&gt;lsusb&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Solution &lt;/h2&gt;

&lt;p&gt;Loaded program code may interfere with the USB registration process.
Use the RESET button then check the output of &lt;code&gt;lsusb&lt;/code&gt; again make sure the device
is being recgonized. NOTE: you may have to hold it down and plug the USB device in then release it.&lt;/p&gt;

&lt;h2&gt;Problem #2&lt;/h2&gt;

&lt;p&gt;If that wasn't enough my USB device was being registered under &lt;code&gt;/dev/hidraw0&lt;/code&gt; which
isn't recognized by the Teensy Loader Application. It only looks at /dev/ttyACM0&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;You can get around this by creating a temporary symlink &lt;code&gt;sudo ln -s /dev/hidraw0 /dev/ttyACM0&lt;/code&gt;
Just make sure you delete it when your done! This is really hacky, if someone has a better
solution please post in comments :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>ReviewBoard with Nginx</title>
    <link href="http://rramsden.ca/blog/2011/09/26/nginx-reviewboard/"/>
    <updated>2011-09-26T08:50:00-07:00</updated>
    <id>http://rramsden.ca/blog/2011/09/26/nginx-reviewboard</id>
    <content type="html">&lt;p&gt;This weekend I decided to checkout ReviewBoard a slick Web 2.0 open source Django app for doing code reviews. Unfortunately, it took me quite a bit of time to set it up from scratch with Nginx. Thus, I decided to do a quick writeup for Nginx users.
ReviewBoard's setup docs is a good starting point for getting the dependencies you need to setup a ReviewBoard website.&lt;/p&gt;

&lt;p&gt;Once you have ReviewBoard installed you can generate a website using &lt;code&gt;rb-site install&lt;/code&gt;. I setup my website under /var/www/review.mysite.com but you can set it up anywhere if you prefer another location.
The next step is to launch the FastCGI daemon script bundled with ReviewBoard&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;rb-site manage /var/www/review runfcgi method=threaded port=3033 host=127.0.0.1 protocol=fcgi&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Once your FastCGI instance is up and running you just need to simply point Nginx at the FastCGI process&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;span class='line'&gt;18&lt;/span&gt;
&lt;span class='line'&gt;19&lt;/span&gt;
&lt;span class='line'&gt;20&lt;/span&gt;
&lt;span class='line'&gt;21&lt;/span&gt;
&lt;span class='line'&gt;22&lt;/span&gt;
&lt;span class='line'&gt;23&lt;/span&gt;
&lt;span class='line'&gt;24&lt;/span&gt;
&lt;span class='line'&gt;25&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;server {
&lt;/div&gt;&lt;div class='line'&gt;    listen 80;    
&lt;/div&gt;&lt;div class='line'&gt;    server_name review.mysite.com;
&lt;/div&gt;&lt;div class='line'&gt;    root /var/www/review.mysite.com/htdocs/;    
&lt;/div&gt;&lt;div class='line'&gt;    
&lt;/div&gt;&lt;div class='line'&gt;    location /media  {     
&lt;/div&gt;&lt;div class='line'&gt;      root /htdocs/media/;    
&lt;/div&gt;&lt;div class='line'&gt;    }
&lt;/div&gt;&lt;div class='line'&gt;   
&lt;/div&gt;&lt;div class='line'&gt;    location /errordoc {      
&lt;/div&gt;&lt;div class='line'&gt;      root /htdocs/errordocs/;    
&lt;/div&gt;&lt;div class='line'&gt;    }
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    location / {      
&lt;/div&gt;&lt;div class='line'&gt;      # host and port to fastcgi server      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_pass 127.0.0.1:3033;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_param PATH_INFO $fastcgi_script_name;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_param REQUEST_METHOD $request_method;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_param QUERY_STRING $query_string;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_param CONTENT_TYPE $content_type;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_param CONTENT_LENGTH $content_length;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_pass_header Authorization;      
&lt;/div&gt;&lt;div class='line'&gt;      fastcgi_intercept_errors off;    
&lt;/div&gt;&lt;div class='line'&gt;    }  
&lt;/div&gt;&lt;div class='line'&gt;}&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Then restart your nginx server and reviewboard should be up and running. Did I miss anything?&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>CoffeeScript and Sprockets 2.0</title>
    <link href="http://rramsden.ca/blog/2011/08/27/coffeescriot-and-sprockets/"/>
    <updated>2011-08-27T14:58:00-07:00</updated>
    <id>http://rramsden.ca/blog/2011/08/27/coffeescriot-and-sprockets</id>
    <content type="html">&lt;p&gt;Sprockets makes it really damn easy in a few lines of ruby to concatenate and serve your coffee script files.
It supports multiple template engines ERB, JavaScript, CSS, SCSS, etc you can
even add a dash of ERB &amp;lt;%= %&gt; to your coffeescript source files by naming your file source.coffee.erb and sprockets will automagically compile it
down with ERB then CoffeeScript and concatenate  it with other dependencies!&lt;/p&gt;

&lt;p&gt;For the project I was working on I couldn't depend on Node.js for dependency management since I was creating a front-end browser game. At first I decided to implement my own hacked up solution in Ruby to substitute and concatenate coffee script source files...
it wasn't pretty :( After moving to sprockets I was able to refactor a few hundred lines into three :)
For example, suppose you have a file that contains sprockets &lt;code&gt;require&lt;/code&gt; syntax called Main.coffee&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;#= require &amp;quot;src/one&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;#= require &amp;quot;src/two&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;#= require &amp;quot;src/three&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;no&quot;&gt;MyApp&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;?=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Then all you need to do is create a Sprockets::Environment instance and add the source path&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sprockets&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sprockets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;src/coffee&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;example.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Main.coffee&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Tada! It just works :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Producer-consumer problem in C</title>
    <link href="http://rramsden.ca/blog/2011/08/27/producer-consumer-problem-in-c/"/>
    <updated>2011-08-27T14:10:00-07:00</updated>
    <id>http://rramsden.ca/blog/2011/08/27/producer-consumer-problem-in-c</id>
    <content type="html">&lt;p&gt;For my Operating Systems class CSCI360 we had to write the classic Producer-consumer problem in C using semaphores.
This is a classic problem/solution to preventing race conditions over a shared resource.&lt;/p&gt;

&lt;p&gt;For those of you who don't know what a semaphore is it's simply a variable that acts as a counter ( with two operations up/down )
which puts a process to sleep if it tries to down/decrement a 0 valued semaphore.
The process will receive a wakeup signal once the 0 valued semaphore is up/incremented by another process.&lt;/p&gt;

&lt;p&gt;In the producer-consumer example below we have a critical region (some shared buffer) that needs to be
controlled using semaphores to prevent race conditions.
We create two semaphores one called EMPTY which represents the number of empty slots available
for the producer and another semaphore called FULL to represent the number of slots occupied with items.&lt;/p&gt;

&lt;p&gt;If there are no items in our buffer a consumer will goto sleep since it will try to down the FULL counter which will
be 0 because there are no items occupying any slots for it to consume.
Once the producer creates an item it will down EMPTY and up FULL; vice-versa.
In the case of the consumer when it consumes items it will up EMPTY and down FULL.
This might seem a little confusing at first so I created a diagram to
illustrate the process (note: producer/consumer are NOT running in parallel in this diagram).&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://img.skitch.com/20110827-q7hd4p6n938dfnix18arm2sjwa.jpg' width='' height='' alt='' title=''&gt;&lt;/p&gt;

&lt;p&gt;It is important to note that EMPTY and FULL alone do not prevent race conditions.&lt;br/&gt;
This doesn't cover the case when the buffer is neither full nor empty.
This means we need a third semaphore to lock the shared buffer to prevent consumers and producers from accessing
the shared buffer at the same time.&lt;/p&gt;

&lt;p&gt;We call a semaphore with a single counter (initialized to 1)
a binary semaphore or more commonly referred to as a mutex or lock. Using a mutex initialized to
1 when a consumer wishes to consume an item it simply needs to down the mutex before consuming
the item which will prevent other producers/consumers from manipulating the shared buffer.
There are two main semaphore implementations in UNIX-based systems: System V (available in older-systems) and POSIX.
For my example program I used System V implementation.&lt;/p&gt;

&lt;h2&gt;Producer.c&lt;/h2&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1175897.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#include &amp;quot;shared.h&amp;quot;

void insert_item(int item, int semid, int *shared_buffer) {
  int index = get_buffer_size(shared_buffer);
  shared_buffer[index] = item; 
}

int produce_item() {
  return 0xFF; // nothing dynamic just write a static integer a slot
}

int main(int argc, const char *argv[])
{
  int *shared_buffer = create_shared_mem_buffer();
  int semid = create_semaphore_set();

  clear_buffer(shared_buffer); // prepare buffer for jobs

  int item = 0;

  while(1) {
    item = produce_item();
    semop(semid, &amp;amp;downEmpty, 1);
    semop(semid, &amp;amp;downMutex, 1);
    insert_item(item, semid, shared_buffer);
    debug_buffer(shared_buffer);
    semop(semid, &amp;amp;upMutex, 1);
    semop(semid, &amp;amp;upFull, 1);
  }
 
  return EXIT_SUCCESS;
}&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;h2&gt;Consumer.c&lt;/h2&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1175900.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#include &amp;quot;shared.h&amp;quot;

void consume_item(int item) {
  // do something with item
}

int remove_item(int semid, int *shared_buffer) {
  int index = get_buffer_size(shared_buffer) - 1;
  int item = shared_buffer[index];
  shared_buffer[index] = 0x00;
  return item;
}

int main(int argc, const char *argv[])
{
  int *shared_buffer = create_shared_mem_buffer();
  int semid = create_semaphore_set();

  int item = 0;

  while(1) {
    semop(semid, &amp;amp;downFull, 1);
    semop(semid, &amp;amp;downMutex, 1);
    item = remove_item(semid, shared_buffer);
    debug_buffer(shared_buffer);
    semop(semid, &amp;amp;upMutex, 1);
    semop(semid, &amp;amp;upEmpty, 1);
    consume_item(item);
  } 

  return EXIT_SUCCESS;
}&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;h2&gt;Shared.h&lt;/h2&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1175904.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/ipc.h&amp;gt;
#include &amp;lt;sys/sem.h&amp;gt;
#include &amp;lt;sys/shm.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;

#define BUFFER_SIZE 5
#define EMPTY_ID 0
#define FULL_ID 1
#define MUTEX_ID 2
#define NSEM_SIZE 3

#define SHM_KEY 9
#define SEM_KEY &amp;quot;.&amp;quot;

static struct sembuf downEmpty = { EMPTY_ID, -1, 0 };
static struct sembuf upEmpty = { EMPTY_ID, 1, 0 };
static struct sembuf upFull = { FULL_ID, 1, 0 };
static struct sembuf downFull = { FULL_ID, -1, 0 };
static struct sembuf downMutex = { MUTEX_ID, -1, 0 };
static struct sembuf upMutex = { MUTEX_ID, 1, 0 };

int *create_shared_mem_buffer();
int create_semaphore_set();
int get_buffer_size(int *sbuff);
void clear_buffer(int *sbuf);&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;h2&gt;Shared.c&lt;/h2&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1175903.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#include &amp;quot;shared.h&amp;quot;

/**
 * returns current size of shared buffer
 */
int get_buffer_size(int *sbuff) {
  int i = 0;
  int counter = 0;
  for (i = 0; i &amp;lt; BUFFER_SIZE; ++i) {
    if (sbuff[i] == 0xFF) {
      counter++;
    } 
  }
  return counter;
}

void debug_buffer(int *sbuff) {
  int i = 0;
  for (i = 0; i &amp;lt; BUFFER_SIZE; ++i) {
    if (sbuff[i] == 0xFF) printf(&amp;quot;1&amp;quot;);
  }
  printf(&amp;quot;\n&amp;quot;);
}

/**
 * returns a pointer to a shared memory buffer that the
 * producer can write to.
 */
int *create_shared_mem_buffer() {
  int *shmaddr = 0; /* buffer address */
  key_t key = SHM_KEY; /* use key to access a shared memory segment */
  
  int shmid = shmget(key, BUFFER_SIZE, IPC_CREAT | SHM_R | SHM_W); /* give create, read and write access */
  if (errno &amp;gt; 0) {
    perror(&amp;quot;failed to create shared memory segment&amp;quot;);
    exit (EXIT_FAILURE);
  }

  shmaddr = (int*)shmat(shmid, NULL, 0);
  if (errno &amp;gt; 0) {
    perror (&amp;quot;failed to attach to shared memory segment&amp;quot;);
    exit (EXIT_FAILURE);
  }

  // clean out garbage memory in shared memory
  return shmaddr;
}

/**
 * only used in the producer to clean out garbage memory when
 * constructing initial buffer.
 */
void clear_buffer(int *sbuff) {
  int i = 0;
  for (i = 0; i &amp;lt; BUFFER_SIZE; ++i) sbuff[i] = 0x00;
}

/**
 * create FULL and EMPTY semaphores
 */
int create_semaphore_set() {
  key_t key = ftok(SEM_KEY, 'E');
  
  int semid = semget(key, NSEM_SIZE, 0600 | IPC_CREAT);
  if (errno &amp;gt; 0) {
    perror(&amp;quot;failed to create semaphore array&amp;quot;);
    exit (EXIT_FAILURE);
  } 

  semctl(semid, FULL_ID, SETVAL, 0);
  if (errno &amp;gt; 0) {
    perror(&amp;quot;failed to set FULL semaphore&amp;quot;);
    exit (EXIT_FAILURE);
  }

  semctl(semid, EMPTY_ID, SETVAL, BUFFER_SIZE);
  if (errno &amp;gt; 0) {
    perror(&amp;quot;failed to set EMPTY sempahore&amp;quot;);
    exit (EXIT_FAILURE);
  }

  semctl(semid, MUTEX_ID, SETVAL, 1);
  if (errno &amp;gt; 0) {
    perror(&amp;quot;failed to create mutex&amp;quot;);
  }

  return semid;
}&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;



</content>
  </entry>
  
</feed>

