Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

This is layout. So much appreciate for your help. Please account for detail. Its

ID: 3594355 • Letter: T

Question

This is layout. So much appreciate for your help. Please account for detail. Its really hard for me to understand. It helps a lot.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define MAX_BR_CAP 5
#define CROSS_TIME 4
#define DIREC_PROB 0.7

#define handle_err(s) do{perror(s); exit(EXIT_FAILURE);}while(0)

typedef struct _thread_argv
{
   int vid;
   int direc;
   int time_to_cross;
} thread_argv;


typedef struct _bridge {
   int dept_idx;
   int num_car;
   int curr_dir;
} bridge_t;

void bridge_init();
void bridge_destroy();
void dispatch(int n);
void *OneVehicle(void *argv);
void ArriveBridge(int vid, int direc);
void CrossBridge(int vid, int direc, int time_to_cross);
void ExitBridge(int vid, int direc);

pthread_t *threads = NULL;   /* Array to hold thread structs */
thread_argv *args = NULL;   /* Array to hold thread arguments */
int num_v = 30;           /* Total number of vehicles to be created */

bridge_t br;           /* Bridge struct shared by the vehicle threads*/

int main(int argc, char *argv[])
{
   int sched_opt;
   int i;

   if(argc < 2)
   {
       printf("Usage: %s SCHED_OPT [SEED] ", argv[0]);
       exit(EXIT_SUCCESS);
   }

   /* Process Arguments */
   sched_opt = atoi(argv[1]);
   if(argc == 3)
       srand((unsigned int)atoi(argv[2]));
   else
       srand((unsigned int)time(NULL));

   /* Allocate memory for thread structs and arguments */
   if((threads = (pthread_t *)malloc(sizeof(pthread_t) * num_v)) == NULL)
       handle_err("malloc() Failed for threads");
   if((args = (thread_argv *)malloc(sizeof(thread_argv) * num_v)) == NULL)
       handle_err("malloc() Failed for args");

   /* Init bridge struct */
   bridge_init();

   /* Create vehicle threads */
   switch(sched_opt)
   {
       case 1 : dispatch(5); break;
       case 2 : dispatch(10); break;
       case 3 : dispatch(30); break;
       default:
           fprintf(stderr, "Bad Schedule Option %d ", sched_opt);
           exit(EXIT_FAILURE);
   }
  
   /* Join all the threads */
   for(i = 0; i < num_v; i++)
       pthread_join(threads[i], NULL);

   /* Clean up and exit */
   bridge_destroy();

   exit(EXIT_SUCCESS);
}

/**
*   Create n vehicle threads for every 10 seconds until the total
*    number of vehicles reaches num_v
*   Each thread handle is stored in the shared array - threads
*/
void dispatch(int n)
{
int k, i;
  
   for(k = 0; k < num_v; k += n)
   {
       printf("Dispatching %d vehicles ", n);

       for( i = k; i < k + n && i < num_v; i++)
       {
           /* The probability of direction 0 is DIREC_PROB */
           int direc = rand() % 1000 > DIREC_PROB * 1000 ? 0 : 1;

           args[i] = (thread_argv){i, direc, CROSS_TIME};
           if(pthread_create(threads + i, NULL, &OneVehicle, args + i) != 0)
               handle_err("pthread_create Failed");
       }
      
       printf("Sleep 10 seconds "); sleep(10);
   }
}

void *OneVehicle(void *argv)
{
   thread_argv *args = (thread_argv *)argv;

   ArriveBridge(args->vid, args->direc);
   CrossBridge(args->vid, args->direc, args->time_to_cross);
   ExitBridge(args->vid, args->direc);

   pthread_exit(0);
}

void bridge_init()
{
   br.dept_idx = 0;
   br.curr_dir = 0;
   br.num_car = 0;

   return;
}

void bridge_destroy()
{
   return;
}

void ArriveBridge(int vid, int direc)
{
   return;
}

void CrossBridge(int vid, int direc, int time_to_cross)
{
   fprintf(stderr, "vid=%d dir=%d starts crossing. Bridge num_car=%d curr_dir=%d ",
       vid, direc, br.num_car, br.curr_dir);
   sleep(time_to_cross);
   return;
}

void ExitBridge(int vid, int direc)
{
   fprintf(stderr, "vid=%d dir=%d exit with departure idx=%d ",
       vid, direc, br.dept_idx);
   return;
}

The goal of this exercise to give you some experience writing concurrent programs using the Pthreads multi-threaded programming library. You have been hired by MetroTrans to synchronize traffic over a one-lane bridge on a public highway. Traffic may only cross the bridge in one direction at a time. Moreoverthe bridge is really old and hasn't been repaired for lack of funds, so MetroTrans has decided to impose the restriction that there should never be more than 5 vehicles on the bridge at any given time. (If this limit is exceeded the bridge will collapse). In this system, each vehicle is represented by one thread, which executes the procedure Onevehicle when it arrives at the bridge: OneVehicle (int direc, int time_to_cross) { ArriveBridge (vehicle_id, direc); CrossBridge (vehicle_id, direc, time_to_cross) ; ExitBridge (vehicle_id, direc) ; In the code above, vehicle_id is an integer which uniquely identifies each vehicle. (The vehicles arriv- ing at the bridge should be assigned vehicle_ids 1,2,3... and so on. ) direc is either 0 correspond ing to east or 1 corresponding to west; it gives the direction in which the vehicle will cross the bridge. time_to_cross is the time it takes a vehicle to cross the bridge - assume that every vehicle takes 4 seconds to cross the bridge.

Explanation / Answer

Added comments are in bold. Code is followed by explanation.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define MAX_BR_CAP 5                 // max 5 vehicles allowed on the bridge
#define CROSS_TIME 4                   // it takes 4sec to cross the bridge
#define DIREC_PROB 0.7 //assumed probability of direction 0 for fair traffic control policy

#define handle_err(s) do{perror(s); exit(EXIT_FAILURE);}while(0)

/* structure representing threads */

typedef struct _thread_argv
{
   int vid;
   int direc;
   int time_to_cross;
} thread_argv;

/* structure representing bridge */
typedef struct _bridge {
   int dept_idx;
   int num_car;
   int curr_dir;
} bridge_t;

void bridge_init();
void bridge_destroy();
void dispatch(int n);
void *OneVehicle(void *argv);
void ArriveBridge(int vid, int direc);
void CrossBridge(int vid, int direc, int time_to_cross);
void ExitBridge(int vid, int direc);

pthread_t *threads = NULL;   /* Array to hold thread structs */
thread_argv *args = NULL;   /* Array to hold thread arguments */
int num_v = 30;           /* Total number of vehicles to be created */

bridge_t br;           /* Bridge struct shared by the vehicle threads*/

int main(int argc, char *argv[])
{
   int sched_opt;                     // number of vehicles threads to be created
   int i;

   if(argc < 2)
   {
       printf("Usage: %s SCHED_OPT [SEED] ", argv[0]);
       exit(EXIT_SUCCESS);
   }

   /* Process Arguments */
   sched_opt = atoi(argv[1]);
   if(argc == 3)
       srand((unsigned int)atoi(argv[2]));
   else
       srand((unsigned int)time(NULL));

   /* Allocate memory for thread structs and arguments */
   if((threads = (pthread_t *)malloc(sizeof(pthread_t) * num_v)) == NULL)
       handle_err("malloc() Failed for threads");
   if((args = (thread_argv *)malloc(sizeof(thread_argv) * num_v)) == NULL)
       handle_err("malloc() Failed for args");

   /* Init bridge struct */
   bridge_init();

   /* Create vehicle threads */
   switch(sched_opt)
   {
       case 1 : dispatch(5); break;
       case 2 : dispatch(10); break;
       case 3 : dispatch(30); break;
       default:
           fprintf(stderr, "Bad Schedule Option %d ", sched_opt);
           exit(EXIT_FAILURE);
   }
  
   /* Join all the threads */
   for(i = 0; i < num_v; i++)
       pthread_join(threads[i], NULL);

   /* Clean up and exit */
   bridge_destroy();

   exit(EXIT_SUCCESS);
}

/**
*   Create n vehicle threads for every 10 seconds until the total
*    number of vehicles reaches num_v
*   Each thread handle is stored in the shared array - threads
*/
void dispatch(int n)
{
int k, i;
  
   for(k = 0; k < num_v; k += n) //threads should be created till no of vehicles become num_v
   {
       printf("Dispatching %d vehicles ", n);

      // executed to create threads from k to k+n (0-n, n+1-n+n and so on till num_v)

       for( i = k; i < k + n && i < num_v; i++)
       {
           /* The probability of direction 0 is DIREC_PROB */
           int direc = rand() % 1000 > DIREC_PROB * 1000 ? 0 : 1;

           args[i] = (thread_argv){i, direc, CROSS_TIME};     // array to store thread arg which will be passed in pthread_create
           if(pthread_create(threads + i, NULL, &OneVehicle, args + i) != 0)
               handle_err("pthread_create Failed");
       }
      
       printf("Sleep 10 seconds "); sleep(10);              // creating new threads every 10 seconds
   }
}

/* Life-cycle of one vehicle on the bridge */

void *OneVehicle(void *argv)
{
   thread_argv *args = (thread_argv *)argv;

   ArriveBridge(args->vid, args->direc);
   CrossBridge(args->vid, args->direc, args->time_to_cross);
   ExitBridge(args->vid, args->direc);

   pthread_exit(0);
}

void bridge_init()
{
   br.dept_idx = 0;
   br.curr_dir = 0;
   br.num_car = 0;

   return;
}

void bridge_destroy()
{
   return;
}

void ArriveBridge(int vid, int direc)
{
   return;
}

void CrossBridge(int vid, int direc, int time_to_cross)
{
   fprintf(stderr, "vid=%d dir=%d starts crossing. Bridge num_car=%d curr_dir=%d ",
       vid, direc, br.num_car, br.curr_dir);
   sleep(time_to_cross);
   return;
}

void ExitBridge(int vid, int direc)
{
   fprintf(stderr, "vid=%d dir=%d exit with departure idx=%d ",
       vid, direc, br.dept_idx);
   return;
}

Explanation:

_bridge : To initialize and maintain current state of the bridge

void bridge_init(): To initialize the bridge struct in the beginning
void bridge_destroy(): To destroy bridge struct in the end
void dispatch(int n): To create threads every 10 seconds equal to n
void *OneVehicle(void *argv): It creates one vehicle thread calls ArriveBridge(), CrossBridge() and ExitBridge() and then deletes thread.
void ArriveBridge(int vid, int direc): Arrival of vehicle vid on the bridge in the direction direc
void CrossBridge(int vid, int direc, int time_to_cross): Crossing of vehicle vid over the bridge in direction direc in time_to_cross seconds.
void ExitBridge(int vid, int direc): Vehicle vid exiting the bridge in the direction direc

If this helps please give a thumbs up. Good Luck!!

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote