home *** CD-ROM | disk | FTP | other *** search
/ ftp.disi.unige.it / 2015-02-11.ftp.disi.unige.it.tar / ftp.disi.unige.it / pub / .person / GianuzziV / SO1 / scambio.c < prev    next >
C/C++ Source or Header  |  2005-04-02  |  5KB  |  153 lines

  1. /*****************************************************
  2.  * scambio.c                                         *
  3.  *                                                   *
  4.  * Uso di condition variable wait.                   *
  5.  * Scrive quanto tempo ci vuole per scambiare dati   *
  6.  * fra 2 thread                                      *
  7.  *                                                   *
  8.  *  gcc -D_REENTRANT -o scambio scambio.c -lpthread  *
  9.  *                                                   *
  10.  *****************************************************/
  11.  
  12. #define COUNT 1000
  13. #include <pthread.h>
  14. #include <stdio.h>
  15. #include <sys/time.h>
  16. #include <unistd.h>
  17.  
  18. long int count=0;
  19. long int totale=0;
  20. void PrintAverage() {
  21.   printf("\nRound trip time medio = %ld\n\n", totale / count );
  22. }
  23.  
  24. /***************************************
  25.  * out = out - in.                     *
  26.  * Out e' supposto essere >= in.       *
  27.  ***************************************/
  28. tvsub( out, in )
  29. register struct timeval *out, *in;
  30. {
  31.     if( (out->tv_usec -= in->tv_usec) < 0 )   {
  32.         out->tv_sec--;
  33.         out->tv_usec += 1000000;
  34.     }
  35.     out->tv_sec -= in->tv_sec;
  36. }
  37.  
  38. /********************************************
  39.  * Global value and condition to wait on    *
  40.  ********************************************/
  41. typedef struct {
  42.     pthread_mutex_t     mutex;  /* Protects access to value */
  43.     pthread_cond_t      cond;   /* Signals change to value */
  44.     int                 value;  /* Access protected by mutex */
  45. } cond_struct_t;
  46. cond_struct_t data = {
  47.     PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
  48.  
  49.  
  50. /**********************************************************
  51.  * Thread start routine. It will set the main thread's predicate
  52.  * and signal the condition variable.
  53.  **********************************************************/
  54. void * wait_thread (int *hibernation)
  55. {
  56.     int status;
  57.  
  58.     sleep (*hibernation);
  59.  
  60.     while(1) {  /* the while loop ends when the main thread terminates */
  61.  
  62.       /****  Wait for me to get the data ****/
  63.       status = pthread_mutex_lock (&data.mutex);
  64.          if (status  = 0) {fprintf(stderr,"Lock error \n"); exit(-1);}
  65.  
  66.          while (data.value == 1) {
  67.        status = pthread_cond_wait(&data.cond, &data.mutex);
  68.        if (status  = 0) {fprintf(stderr,"Wait error \n"); exit(-1);}
  69.          }
  70.       status = pthread_mutex_unlock (&data.mutex);
  71.       if (status  = 0) {fprintf(stderr,"Unlock error \n"); exit(-1);}
  72.  
  73.       /**** OK, now I have the data.  Send it back to the other thread */      
  74.       status = pthread_mutex_lock (&data.mutex);
  75.          if (status  = 0) {fprintf(stderr,"Lock error \n"); exit(-1);}
  76.          data.value = 1;             /* Set predicate */
  77.          status = pthread_cond_signal (&data.cond);
  78.          if (status  = 0) {fprintf(stderr,"Signal error \n"); exit(-1);}
  79.  
  80.       status = pthread_mutex_unlock (&data.mutex);
  81.       if (status  = 0) {fprintf(stderr,"Unlock error \n"); exit(-1);}
  82.     }
  83.     pthread_exit(0);
  84. }
  85.  
  86. int main (int argc, char *argv[])
  87. {
  88.     int status;
  89.     pthread_t wait_thread_id;
  90.     struct timespec timeout;
  91.     int hibernation = 1;
  92.  
  93.     struct timezone tz;                 /* for timing */
  94.     register struct timeval start;      /* for timing */
  95.     register struct timeval stop;       /* for timing */
  96.     int i;
  97.  
  98.     /* Create wait_thread.  */
  99.     status = 
  100.        pthread_create (&wait_thread_id, NULL, (void *) wait_thread, 
  101.                &hibernation);
  102.     if (status  = 0) {fprintf(stderr,"Create error \n"); exit(-1);}
  103.  
  104.     /****** Insert comments to not do one RT outside the timing loop */
  105.     status = pthread_mutex_lock (&data.mutex);
  106.     if (status  = 0) {fprintf(stderr,"Lock error \n"); exit(-1);}
  107.     
  108.     while (data.value == 0) {
  109.       status = pthread_cond_wait(&data.cond, &data.mutex);
  110.       if (status  = 0) {fprintf(stderr,"Wait error \n"); exit(-1);}
  111.     }
  112.  
  113.     data.value = 0;
  114.     status = pthread_cond_signal (&data.cond);
  115.     status = pthread_mutex_unlock (&data.mutex);
  116.     if (status  = 0) {fprintf(stderr,"Unlock error \n"); exit(-1);}
  117.     /****** End of insert comments to not do one RT outside the timing loop  */
  118.  
  119.  
  120.     for(i=0;i<COUNT;i++) {
  121.       gettimeofday( &start, &tz );
  122.       
  123.       /****  Wait for me to get the data ****/
  124.       status = pthread_mutex_lock (&data.mutex);
  125.          if (status  = 0) {fprintf(stderr,"Lock error \n"); exit(-1);}
  126.       
  127.          while (data.value == 0) {
  128.        status = pthread_cond_wait(&data.cond, &data.mutex);
  129.        if (status  = 0) {fprintf(stderr,"Wait error \n"); exit(-1);}
  130.          }
  131.       status = pthread_mutex_unlock (&data.mutex);
  132.       if (status  = 0) {fprintf(stderr,"Unlock error \n"); exit(-1);}
  133.  
  134.       /**** OK, now I have the data.  Send it back to the other thread */      
  135.       status = pthread_mutex_lock (&data.mutex);
  136.          if (status  = 0) {fprintf(stderr,"Lock error \n"); exit(-1);}
  137.          data.value = 0;
  138.          status = pthread_cond_signal (&data.cond);
  139.       status = pthread_mutex_unlock (&data.mutex);
  140.       if (status  = 0) {fprintf(stderr,"Unlock error \n"); exit(-1);}
  141.       
  142.       gettimeofday( &stop, &tz );
  143.       tvsub( &stop, &start );
  144.       printf("Round trip time = %d usecs\n", 
  145.          stop.tv_sec*1000000+stop.tv_usec);
  146.       count++;
  147.       totale += stop.tv_sec*1000000+stop.tv_usec;
  148.     }
  149.     PrintAverage();    
  150.     return 0;
  151. }
  152.  
  153.