- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <semaphore.h>
- #include <pthread.h>
- #define FAM_SIZE 3 /* For Daddy, Mommy, and Nanny */
- #define cls() printf( "\033[H\033[J" )
- #define position(row,col) printf( "\033[%d;%dH", (row), (col) )
- #define positionFlush(row,col) printf( "\033[%d;%dH\n", (row), (col) )
- //?
- #define semaphore_init(s,v) sem_init( &s, 0, v )
- #define semaphoreWait(s) sem_wait( &s )
- #define semaphoreSignal(s) sem_post( &s )
- #define semaphore_release(s) sem_destroy( &s )
- typedef sem_t semaphore;
- semaphore one;
- semaphore mutex;
- semaphore chopstick[FAM_SIZE];
- int screenRow[FAM_SIZE] = {6, 6, 10};
- int screenCol[FAM_SIZE] = {31, 49, 40};
- int chopstickRow[3]= {9, 4,9};
- int chopstickCol[3] = { 35,47,45 };
- char chopstickSym[3] = { '/', '/', '\\'};
- void sleeping(int n)
- {
- semaphoreWait(one);
- position(screenRow[n], screenCol[n]);
- printf( "\033[33mS\033[0m" );
- positionFlush(13,1);
- semaphoreSignal(one);
- }
- void hungryWaiting(int n)
- {
- semaphoreWait(one);
- position( screenRow[n], screenCol[n] );
- printf( "\033[34mH\033[0m" );
- positionFlush( 13, 1 );
- semaphoreSignal(one);
- }
- void startEating(int n)
- {
- semaphoreWait(one);
- position(chopstickRow[n], chopstickCol[n]);
- printf("%c",' ');
- positionFlush(13,1);
- semaphoreSignal(one);
- }
- void eating( int n)
- {
- semaphoreWait(one);
- position( screenRow[n], screenCol[n] );
- printf( "\033[31mE\033[0m" );
- position( screenRow[n] + 1, screenCol[n] - 1 );
- positionFlush( 13, 1 );
- semaphoreSignal( one );
- }
- void doneEating(int n)
- {
- semaphoreWait(one);
- position(chopstickRow[n], chopstickCol[n]);
- printf( "\033[32m%c\033[0m", chopstickSym[n] );
- positionFlush(13,1);
- semaphoreSignal(one);
- }
- void aquire_chopstick( int n)
- {
- /* Pick up chopsticks*/
- /* Needs to prevent deadlock
- To prevent deadlock, alternating the order by which they pick up the chopstick
- Evens pick up on the right first
- Odd pick up on the left first
- Asymmetric solution
- This insures that not everyone is holding one chopstick waiting on the second forever!
- */
- if( n % 2 == 0)
- {
- /*If even */
- semaphoreWait(chopstick[n]);
- startEating(n);
- semaphoreWait(chopstick[(n+1) % FAM_SIZE]);
- startEating( (n+1) % FAM_SIZE);
- }
- else
- {
- /* if odd */
- semaphoreWait(chopstick[(n+1) % FAM_SIZE]);
- startEating( (n+1) % FAM_SIZE);
- semaphoreWait(chopstick[n]);
- startEating(n);
- }
- }
- void release_chopsticks( int n)
- {
- // release chopstick
- /* To release the chopstick, semaphore signal on each */
- /* Here order doesn't matter */
- doneEating(n);
- semaphoreSignal( chopstick[n] );
- doneEating( (n+1)% FAM_SIZE);
- semaphoreSignal( chopstick[ (n+1) % FAM_SIZE] );
- }
- void family( int *familyData)
- {
- int n = familyData[0];
- /* Simulates a family endlessly eating, sleeping, and being hungry
- for a month.*/
- while(1)
- {
- sleep(10);
- /* Hungry section - draw hungry */
- hungryWaiting(n);
- sleep(2);
- //try to get locks on chopsticks
- aquire_chopstick(n);
- eating(n);
- sleep(3);
- /* Eating startEating draws it to the screen*/
- sleep(3);
- /* increment count for times eaten and eat for random time then release chopsticks */
- release_chopsticks(n);
- sleep(2);
- /* once chopsticks are released, draw sleeping */
- sleeping(n);
- sleep(2);
- /*sleep for random time */
- }
- }
- void initScreen(void)
- {
- int i;
- cls(); //clear the screen
- position( 6,37);
- printf("\\ /");
- position(7, 38);
- printf("\\_____/");
- for (i=0; i<FAM_SIZE; i++)
- {
- position( screenRow[i], screenCol[i]);
- printf("%d", i);
- printf("(%d)",0);
- position( chopstickRow[i], chopstickCol[i]);
- printf( "%c", chopstickSym[i]);
- }
- positionFlush(13,1);
- }
- int main()
- {
- pthread_t fam[FAM_SIZE];
- int i, status, duration;
- int family_data[FAM_SIZE][2];
- /* initialize all chopsticks 0,1,2 to 1 -- meaning to start, they are
- all available */
- for ( i = 0; i < FAM_SIZE; i++ )
- {
- if ( semaphore_init( chopstick[i], 1 ) < 0 )
- {
- printf("cannot create chopstick semaphore\n" );
- exit( 1 );
- }
- }
- if ( semaphore_init( one, 1 ) < 0 )
- {
- printf("cannot create screen semaphore\n" );
- exit( 1 );
- }
- if ( semaphore_init( mutex, 1 ) < 0 )
- {
- printf("cannot create mutex semaphore\n" );
- exit( 1 );
- }
- initScreen();
- for ( i = 0; i < FAM_SIZE; i++ )
- {
- family_data[i][0] = i;
- family_data[i][1] = duration;
- if ( pthread_create( &fam[i], NULL, (void *(*)(void *)) &family, &family_data[i] ) != 0 )
- {
- printf("cannot create thread for family %d\n", i );
- exit( 1 );
- }
- }
- /*
- * Wait for the family to finish.
- */
- for ( i = 0; i < FAM_SIZE; i++ )
- {
- pthread_join( fam[i], NULL );
- }
- /*
- * Release semaphore resources.
- */
- for ( i = 0; i < FAM_SIZE; i++ )
- {
- semaphore_release( chopstick[i] );
- }
- semaphore_release( one );
- semaphore_release( mutex );
- return (EXIT_SUCCESS);
- }