Hi guys,
I need help with this code, I am trying to figure out how can I add semaphores to this code in order to have just one at a time accessing the shared memory.
Thanks,
/* elevator.c
The elevator process starts a people process which runs
independently, except that the processes share some memory.
The elevator runs up and down, stopping when it has people
to pick up or let off at a floor. The people process
occasionally brings a new person into the system at a randomly
chosen floor, letting the elevator know whether that person is
going up or down.
*/
/* Program has major problem - access to shared memory needs to be
one at a time - add semaphores later. */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <signal.h>
#define FLOORS (5)
#define ELEVATOR_SPEED (3)
void elevator();
void people();
struct shared_info {
int going_up[FLOORS];
int going_down[FLOORS];
int total_number;
};
struct shared_info * people_data; /* data shared by parent and child */
int shared_memory_id;
void handle(int sig)
{
/* Remove the shared memory segment from the system. */
shmctl(shared_memory_id, IPC_RMID, NULL);
exit(0);
}
void main(void)
{
int floor;
pid_t fork_return;
/* Get and attach the shared memory segment. */
shared_memory_id = shmget(IPC_PRIVATE, sizeof(struct shared_info),
0600);
if (shared_memory_id < 0) {
perror("Cannot get shared memory");
exit(1);
}
/* Ensure that shared memory segment gets removed when
we go away. */
signal(SIGINT, handle);
signal(SIGQUIT, handle);
people_data = (struct shared_info *) shmat( shared_memory_id,
0, 0);
if((void *)people_data < (void *) 0){
perror("Cannot attach shared memory");
exit(1);
}
/* Initialize people_data to no people in system. */
for( floor = 0; floor < FLOORS; floor++){
(people_data -> going_up)[floor] = 0;
(people_data -> going_down)[floor] = 0;
people_data -> total_number = 0;
}
/* fork the people process */
fork_return = fork();
switch(fork_return){
case 0: people();
case -1: perror("Cannot fork child");
exit(1);
default: elevator();
}
}
void elevator()
{
/* Number of people on elevator wanting to get off at each floor. */
int getting_off[FLOORS];
int total_on_board;
/* Elevator's current direction. */
#define UP (1)
#define DOWN (0)
int direction = UP;
/* Elevator's current floor. */
int floor = 0;
int new_on;
int i;
int flag1, flag2;
for(i = 0; i < FLOORS; i++)
getting_off[i] = 0;
/* Seed random numbers */
srand(getpid());
printf("Elevator starting.\n");
while( 1)
{
/* If no one wants to go anywhere... */
if( total_on_board == 0 && people_data -> total_number == 0){
/* Just sleep a bit and try again. */
sleep(1);
}
else {
/* Let people going in our direction on. */
if( direction == UP)
{
new_on = (people_data -> going_up)[floor];
(people_data -> going_up)[floor] -= new_on;
people_data -> total_number -= new_on;
total_on_board += new_on;
/* Random destination for each person. */
for( i = 0; i < new_on; i++)
getting_off[ floor +
rand()%(FLOORS - floor - 1)
+ 1]++;
}
else
{
new_on = (people_data -> going_down)[floor];
(people_data -> going_down)[floor] -= new_on;
people_data -> total_number -= new_on;
total_on_board += new_on;
/* Random destination for each person. */
for( i = 0; i < new_on; i++)
getting_off[ floor -
rand()%( floor ) - 1]++;
}
if( new_on)
printf("%d %s got on at floor %d.\n",
new_on,
new_on > 1 ? "people" : "person",
floor);
/* If nothing is going to happen in the direction
we are going, then change direction. */
flag1 = 0;
flag2 = 0;
if(direction == UP){
for(i = floor; i < FLOORS; i++)
if(getting_off[i] ||
people_data -> going_up[i] ||
people_data -> going_down[i])
{
flag1 = 1;
break;
}
if( !flag1 )
direction = DOWN;
}
else{
for(i = floor; i >= 0; i--)
if(getting_off[i] ||
people_data -> going_up[i] ||
people_data -> going_down[i])
{
flag2 = 1;
break;
}
if( !flag2 )
direction = UP;
}
/* Travel to next floor. */
/* Elevator is not instantaneous. */
if( flag1 || flag2) {
sleep(ELEVATOR_SPEED);
direction == UP ? floor++ : floor--;
if( floor == FLOORS - 1)
direction = DOWN;
if( floor == 0)
direction = UP;
/* If anyone wants off here, let them off. */
if( getting_off[floor])
printf("Elevator lets %d off at floor %d.\n",
getting_off[floor], floor);
people_data -> total_number -= getting_off[floor];
getting_off[floor] = 0;
}
}
}
}
void people()
{
int floor;
srand( getpid());
while(1)
{
/* Sleep a while */
sleep( rand() % 10 );
/* Generate a new person. */
if( rand() % 2 == 0){
/* Going down. */
floor = rand() % (FLOORS - 1) + 1;
people_data -> going_down[ floor ] ++;
printf("New person going down at floor %d.\n", floor);
}
else {
floor = rand() % (FLOORS - 1);
(people_data -> going_up)[ floor ]++;
printf("New person going up at floor %d.\n", floor);
}
people_data -> total_number++;
}
}
<< moderator edit: added code tags: [code][/code] >>