User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C section within the Software Development category of DaniWeb, a massive community of 397,771 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,532 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C advertiser:
Views: 1858 | Replies: 0
Reply
Join Date: Jun 2005
Posts: 1
Reputation: noman13 is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
noman13 noman13 is offline Offline
Newbie Poster

semaphores

  #1  
Jun 19th, 2005
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] >>
AddThis Social Bookmark Button
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

DaniWeb C Marketplace
Thread Tools Display Modes

Similar Threads
Other Threads in the C Forum

All times are GMT -4. The time now is 4:30 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC