title: Semaphore locks solution in C
body: <p><strong>How can i solve the following problem implementing semaphore synchronization...</strong></p>
  
  <p>For the purposes of this problem we will model the intersection as shown above, dividing it into quarters and identifying each quarter with which lane enters the intersection through that portion. (Just to clarify: we're driving on the right side of the road.) Turns are represented by a progression through one, two, or three portions of the intersection (for simplicity assume that U-turns do not occur in the intersection). So if a car approaches from the North, depending on where it is going, it proceeds through the intersection as follows:</p>
  
  <pre><code>        | ! + ^ |                   
          | ! + ! |
          | v + ! |
   --------------------------
     &lt;----|NW + NE|  &lt;----
          |   +   |
   ++++++++++++++++++++++++++                 
          |   +   |
    ----&gt; |SW + SE| ----&gt;
   --------------------------
          | ! + ^ |
          | ! + ! |
          | v + ! |
  
  
  
  Right: NW
  Straight: NW-SW
  Left: NW-SW-SE 
  </code></pre>
  
  <p>whoever arrives at the intersection first proceeds first. </p>
  
  <p>No two cars can be in the same portion of the intersection at the same time. 
  do not pass each other going the same way. If two cars both approach from the same direction and head in the same direction, the first car to reach the intersection should be the first to reach the destination. Similarly, cars shouldn't “jump” over each other in the intersection. For example, say that a car enters the intersection and is going straight. Then another car enters the intersection from the same direction and is going left. The second car should exit the intersection after the first one. However, suppose that a car enters the intersection and is going left. If another car enters the intersection from the same direction and is going right, then it may leave the intersection earlier because the first car, even though it is ahead of the second car, may not yet be able to make the left turn.
  Each car should print a message as it approaches the intersection (approaching), enters one ore more regions of the intersection ((region1), region2 and region3), and leaves the intersection (leaving), indicating the car number, approach direction and destination direction. </p>
  
  <p>Cars approaching an intersection from a given direction should enter the intersection in the same order. Note that there should be no synchronization before a car is approaching the intersection to slow it down. In other words, do not simply print approaching just before entering region1 of the intersection e.g., there should be a synchronization primitive between the two events.
  There are no other ordering requirements. For example, there are no ordering requirements for cars approaching from different directions.
  I should allow two or more cars to be in the intersection at a time, without allowing traffic from any direction to starve traffic from any other direction.</p>
  
  <p>createcars which creates 20 cars and passes them to approachintersection which assigns each a random direction. I need to assign them a random turn direction;i can do this in approachintersection as well.</p>
  
  <p>Other routines gostraight, turnright and turnleft that may or may not be helpful in implementing this solution. I can use them or discard them.</p>
  
  <p>Here is a sample output for one car (car 8) that arrives from the East and is heading West. Note that the regions (e.g., region1) are defined relative to each car. A car going right will output region1. A car going straight will output region1 and region2. A car going left will output region1, region2 and region3.</p>
  
  <pre><code>approaching: car =  8, direction = E, destination = W
  region1:     car =  8, direction = E, destination = W
  region2:     car =  8, direction = E, destination = W
  leaving:     car =  8, direction = E, destination = W
  </code></pre>
  
  <p>Following are the routines for that i have..</p>
  
  <pre><code>    #include &lt;types.h&gt;
      #include &lt;lib.h&gt;
      #include &lt;test.h&gt;
      #include &lt;thread.h&gt;
  
  
  
      /*
      * Number of cars created.
      */
  
      #define NCARS 20
  
  
      /*
      *
      * Function Definitions
      *
      */
  
      static const char *directions[] = { "N", "E", "S", "W" };
  
      static const char *msgs[] = {
          "approaching:",
          "region1:    ",
          "region2:    ",
          "region3:    ",
          "leaving:    "
      };
  
      /* use these constants for the first parameter of message */
      enum { APPROACHING, REGION1, REGION2, REGION3, LEAVING };
  
      static void
      message(int msg_nr, int carnumber, int cardirection, int destdirection)
      {
          kprintf("%s car = %2d, direction = %s, destination = %s\n",
                  msgs[msg_nr], carnumber,
                  directions[cardirection], directions[destdirection]);
      }
  
      /*
      * gostraight()
      *
      * Arguments:
      *      unsigned long cardirection: the direction from which the car
      *              approaches the intersection.
      *      unsigned long carnumber: the car id number for printing purposes.
      *
      * Returns:
      *      nothing.
      *
      * Notes:
      *      This function should implement passing straight through the
      *      intersection from any direction.
      *      Write and comment this function.
      */
  
      static void gostraight(unsigned long cardirection, unsigned long carnumber)
      {
          /*
           * Avoid unused variable warnings.
           */
  
          (void) cardirection;
          (void) carnumber;
      }
  
  
      /*
      * turnleft()
      *
      * Arguments:
      *      unsigned long cardirection: the direction from which the car
      *              approaches the intersection.
      *      unsigned long carnumber: the car id number for printing purposes.
      *
      * Returns:
      *      nothing.
      *
      * Notes:
      *      This function should implement making a left turn through the 
      *      intersection from any direction.
      *      Write and comment this function.
      */
  
      static void turnleft(unsigned long cardirection, unsigned long carnumber)
      {
          /*
           * Avoid unused variable warnings.
           */
  
          (void) cardirection;
          (void) carnumber;
      }
  
  
      /*
      * turnright()
      *
      * Arguments:
      *      unsigned long cardirection: the direction from which the car
      *              approaches the intersection.
      *      unsigned long carnumber: the car id number for printing purposes.
      *
      * Returns:
      *      nothing.
      *
      * Notes:
      *      This function should implement making a right turn through the 
      *      intersection from any direction.
      *      Write and comment this function.
      */
  
      static void turnright(unsigned long cardirection, unsigned long carnumber)
      {
          /*
           * Avoid unused variable warnings.
           */
  
          (void) cardirection;
          (void) carnumber;
      }
  
  
      /*
      * approachintersection()
      *
      * Arguments: 
      *      void * unusedpointer: currently unused.
      *      unsigned long carnumber: holds car id number.
      *
      * Returns:
      *      nothing.
      *
      * Notes:
      *      I need to change this function to implement sempahore synchronization. These
      *      threads are created by createcars().  Each one must choose a direction
      *      randomly, approach the intersection, choose a turn randomly, and then
      *      complete that turn.  The code to choose a direction randomly is
      *      provided, the rest is left to you to implement.  Making a turn
      *      or going straight should be done by calling one of the functions
      *      above.
      */
  
      static void approachintersection(void * unusedpointer, unsigned long carnumber)
      {
          int cardirection;
  
          /*
           * Avoid unused variable and function warnings.
           */
  
          (void) unusedpointer;
          (void) carnumber;
      (void) gostraight;
      (void) turnleft;
      (void) turnright;
  
          /*
           * cardirection is set randomly.
           */
  
          cardirection = random() % 4;
      }
  
  
      /*
      * createcars()
      *
      * Arguments:
      *      int nargs: unused.
      *      char ** args: unused.
      *
      * Returns:
      *      0 on success.
      *
      * Notes:
      *       Driver code to start up the approachintersection() threads.
      *      I can modify this code as well for my solution..
      */
  
      int createcars(int nargs, char ** args)
      {
          int index, error;
  
          /*
           * Avoid unused variable warnings.
           */
  
          (void) nargs;
          (void) args;
  
          /*
           * Start NCARS approachintersection() threads.
           */
  
          for (index = 0; index &lt; NCARS; index++) {
  
                  error = thread_fork("approachintersection thread",
                                      NULL,
                                      index,
                                      approachintersection,
                                      NULL
                                      );
  
                  /*
                   * panic() on error.
                   */
  
                  if (error) {
  
                          panic("approachintersection: thread_fork failed: %s\n",
                                strerror(error)
                                );
                  }
          }
  
          return 0;
      }
  
    [1]: http://i.stack.imgur.com/1389H.gif
  </code></pre>