Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jul 1st, 2012  |  syntax: None  |  size: 5.05 KB  |  hits: 18  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <semaphore.h>
  5. #include <pthread.h>
  6.  
  7. #define FAM_SIZE 3  /* For Daddy, Mommy, and Nanny */
  8. #define cls()                   printf( "\033[H\033[J" )
  9. #define position(row,col)       printf( "\033[%d;%dH", (row), (col) )
  10. #define positionFlush(row,col)  printf( "\033[%d;%dH\n", (row), (col) )
  11.  
  12. //?
  13. #define semaphore_init(s,v)     sem_init( &s, 0, v )
  14. #define semaphoreWait(s)                sem_wait( &s )
  15. #define semaphoreSignal(s)              sem_post( &s )
  16. #define semaphore_release(s)    sem_destroy( &s )
  17. typedef sem_t semaphore;
  18.  
  19.  
  20. semaphore one;
  21. semaphore mutex;
  22. semaphore chopstick[FAM_SIZE];
  23.  
  24. int screenRow[FAM_SIZE] = {6, 6, 10};
  25. int screenCol[FAM_SIZE] = {31, 49, 40};
  26. int chopstickRow[3]= {9, 4,9};
  27. int chopstickCol[3] = { 35,47,45 };
  28. char chopstickSym[3] = { '/', '/', '\\'};
  29.  
  30.  
  31. void sleeping(int n)
  32. {
  33.         semaphoreWait(one);
  34.         position(screenRow[n], screenCol[n]);
  35.     printf( "\033[33mS\033[0m" );
  36.         positionFlush(13,1);
  37.         semaphoreSignal(one);
  38. }
  39.  
  40. void hungryWaiting(int n)
  41. {
  42.         semaphoreWait(one);
  43.         position( screenRow[n], screenCol[n] );
  44.     printf( "\033[34mH\033[0m" );
  45.     positionFlush( 13, 1 );
  46.         semaphoreSignal(one);
  47. }
  48.  
  49.  
  50. void startEating(int n)
  51. {
  52.         semaphoreWait(one);
  53.         position(chopstickRow[n], chopstickCol[n]);
  54.         printf("%c",' ');
  55.         positionFlush(13,1);
  56.         semaphoreSignal(one);
  57. }
  58.  
  59. void eating( int n)
  60. {
  61.         semaphoreWait(one);
  62.         position( screenRow[n], screenCol[n] );
  63.     printf( "\033[31mE\033[0m" );
  64.     position( screenRow[n] + 1, screenCol[n] - 1 );
  65.     positionFlush( 13, 1 );
  66.     semaphoreSignal( one );
  67. }
  68.  
  69.        
  70.  
  71. void doneEating(int n)
  72. {
  73.         semaphoreWait(one);
  74.         position(chopstickRow[n], chopstickCol[n]);
  75.         printf( "\033[32m%c\033[0m", chopstickSym[n] );
  76.         positionFlush(13,1);
  77.         semaphoreSignal(one);
  78.        
  79. }
  80.  
  81. void aquire_chopstick( int n)
  82. {
  83.         /* Pick up chopsticks*/
  84.         /* Needs to prevent deadlock
  85.  
  86.                         To prevent deadlock, alternating the order by which they pick up the chopstick
  87.                         Evens pick up on the right first
  88.                         Odd pick up on the left first
  89.  
  90.                         Asymmetric solution
  91.  
  92.                         This insures that not everyone is holding one chopstick waiting on the second forever!
  93.  
  94.         */
  95.  
  96.         if( n % 2 == 0)
  97.         {
  98.                 /*If even */
  99.                 semaphoreWait(chopstick[n]);
  100.                 startEating(n);
  101.                 semaphoreWait(chopstick[(n+1) % FAM_SIZE]);
  102.                 startEating( (n+1) % FAM_SIZE);
  103.                
  104.         }
  105.         else
  106.         {
  107.                 /* if odd */
  108.                 semaphoreWait(chopstick[(n+1) % FAM_SIZE]);
  109.                 startEating( (n+1) % FAM_SIZE);
  110.                 semaphoreWait(chopstick[n]);
  111.                 startEating(n);
  112.                
  113.         }
  114. }
  115.  
  116. void release_chopsticks( int n)
  117. {
  118.         // release chopstick
  119.         /* To release the chopstick, semaphore signal on each */
  120.         /* Here order doesn't matter */
  121.        
  122.         doneEating(n);
  123.         semaphoreSignal( chopstick[n] );
  124.         doneEating( (n+1)% FAM_SIZE);
  125.         semaphoreSignal( chopstick[ (n+1) % FAM_SIZE] );
  126. }
  127.  
  128. void family( int *familyData)
  129. {
  130.         int n = familyData[0];
  131. /* Simulates a family endlessly eating, sleeping, and being hungry
  132. for a month.*/
  133.  
  134.  
  135.  
  136.  
  137.         while(1)
  138.         {
  139.                
  140.                 sleep(10);
  141.  
  142.                 /* Hungry section - draw hungry */
  143.                 hungryWaiting(n);
  144.                 sleep(2);
  145.  
  146.                 //try to get locks on chopsticks
  147.                 aquire_chopstick(n);
  148.                 eating(n);
  149.                 sleep(3);
  150.                 /* Eating startEating draws it to the screen*/
  151.  
  152.                
  153.                 sleep(3);
  154.                 /* increment count for times eaten and eat for random time then release chopsticks */
  155.  
  156.  
  157.                 release_chopsticks(n);
  158.                 sleep(2);
  159.                 /* once chopsticks are released, draw sleeping */
  160.                 sleeping(n);
  161.                 sleep(2);
  162.                 /*sleep for random time */
  163.         }
  164. }
  165.  
  166. void initScreen(void)
  167. {
  168.  
  169.         int i;
  170.  
  171.         cls();  //clear the screen
  172.         position( 6,37);
  173.         printf("\\       /");
  174.         position(7, 38);
  175.         printf("\\_____/");
  176.  
  177.  
  178.         for (i=0; i<FAM_SIZE; i++)
  179.         {
  180.                 position( screenRow[i], screenCol[i]);
  181.                 printf("%d", i);
  182.                 printf("(%d)",0);
  183.                 position( chopstickRow[i], chopstickCol[i]);
  184.                 printf( "%c", chopstickSym[i]);
  185.         }
  186.         positionFlush(13,1);
  187. }
  188.  
  189.  
  190.  
  191. int main()
  192. {
  193.         pthread_t fam[FAM_SIZE];
  194.         int i, status, duration;
  195.         int family_data[FAM_SIZE][2];
  196.  
  197.         /* initialize all chopsticks 0,1,2 to 1 -- meaning to start, they are
  198.         all available */
  199.     for ( i = 0; i < FAM_SIZE; i++ )
  200.     {
  201.                 if ( semaphore_init( chopstick[i], 1 ) < 0 )
  202.                 {
  203.             printf("cannot create chopstick semaphore\n" );
  204.             exit( 1 );
  205.                 }
  206.     }
  207.         if ( semaphore_init( one, 1 ) < 0 )
  208.         {
  209.                 printf("cannot create screen semaphore\n" );
  210.                 exit( 1 );
  211.     }
  212.         if ( semaphore_init( mutex, 1 ) < 0 )
  213.         {
  214.         printf("cannot create mutex semaphore\n" );
  215.         exit( 1 );
  216.     }
  217.         initScreen();
  218.         for ( i = 0; i < FAM_SIZE; i++ )
  219.     {
  220.                 family_data[i][0] = i;
  221.                 family_data[i][1] = duration;
  222.                 if ( pthread_create( &fam[i], NULL, (void *(*)(void *)) &family, &family_data[i] ) != 0 )
  223.                 {
  224.                         printf("cannot create thread for family %d\n", i );
  225.                         exit( 1 );
  226.                 }
  227.     }
  228.             /*
  229.      * Wait for the family to finish.
  230.      */
  231.     for ( i = 0; i < FAM_SIZE; i++ )
  232.     {
  233.                 pthread_join( fam[i], NULL );
  234.     }
  235.  
  236.     /*
  237.      * Release semaphore resources.
  238.      */
  239.     for ( i = 0; i < FAM_SIZE; i++ )
  240.     {
  241.                 semaphore_release( chopstick[i] );
  242.     }
  243.     semaphore_release( one );
  244.     semaphore_release( mutex );
  245.  
  246.  
  247.  
  248.  
  249. return (EXIT_SUCCESS);
  250. }