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;
}
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!!
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.