-1

How can i solve the following problem implementing semaphore synchronization...

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:

        | ! + ^ |                   
        | ! + ! |
        | v + ! |
 --------------------------
   <----|NW + NE|  <----
        |   +   |
 ++++++++++++++++++++++++++                 
        |   +   |
  ----> |SW + SE| ---->
 --------------------------
        | ! + ^ |
        | ! + ! |
        | v + ! |



Right: NW
Straight: NW-SW
Left: NW-SW-SE 

whoever arrives at the intersection first proceeds first.

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.

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.

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.

Other routines gostraight, turnright and turnleft that may or may not be helpful in implementing this solution. I can use them or discard them.

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.

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

Following are the routines for that i have..

    #include <types.h>
    #include <lib.h>
    #include <test.h>
    #include <thread.h>



    /*
    * 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 < 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]: https://i.stack.imgur.com/1389H.gif
don great
  • 53
  • 1
  • 11
  • sorry about that my mistake that i was not detailed in asking the question. so as you have already seen the problem statement now my question is that how many semaphores and number of threads i should create to solve this problem. Will i need 1 semaphore each car? I guess serge already answered to this questions. But still i would really appreciate if some one can explain it with a code example. – don great Oct 11 '12 at 18:14

1 Answers1

0

Taking to account that you have only four regions in your crossing that a car may occupy you need four semaphores and four threads to solve your problem. Let's put all cars that arrives to the crossing into the single FIFO queue regardless of the direction a car is going. This will ensure that cars are passing the crossing in order of arrival. Then each thread picks up a car from the queue, determines a path and pends on the first semaphore in the path. After acquiring a semaphore it checks if this is the last area in the path and then it releases a semaphore as the car reached the destination border of the crossing. Otherwise, the thread pends on a next semaphore in its path. After acquiring a next semaphore it releases the semaphore of the previously occupied area. When a thread routed the car to the crossing boundary it restarts from the queue polling.

Couple of notes. This approach will work even with U-turns. The 'traffic jam' is possible like in a real life when we have 4 cars in the crossing and each car is waiting for the next area to be free. You can avoid jams by limiting the number of threads to three

Serge
  • 6,088
  • 17
  • 27
  • Thank you so much for your answer. But what if i want a car who wants to turn right should be allowed to make a right turn even if there is a car already waiting to take a left turn. If possible can you give me a code example. – don great Oct 11 '12 at 18:16