prod_cons.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <errno.h>
00005 #include "prod_cons.h"
00006 
00007 
00008 prod_cons_t *create_prod_cons(int sz) {
00009         prod_cons_t *prod_cons = malloc(sizeof(prod_cons_t));
00010 
00011 
00012         prod_cons->buffer = calloc(sz, sizeof(int));
00013         prod_cons->buf_size = sz;
00014         pthread_mutex_init( &(prod_cons->prod_mutex), NULL);
00015         pthread_mutex_init( &(prod_cons->cons_mutex), NULL);
00016         // The buffer starts with all positions free
00017         sem_init( &(prod_cons->prod_sem), 0, sz);
00018         // The buffer starts without any filled positions
00019         sem_init( &(prod_cons->cons_sem), 0, 0);
00020         prod_cons->prod_pos = 0;
00021         prod_cons->cons_pos = 0;
00022         
00023 
00024         return prod_cons;
00025 }
00026 
00027 
00028 void put(prod_cons_t *prod_cons, void *val) {
00029         int status = -1;
00030         
00031         // Wait for a free position
00032         do {
00033                 // In NPTL, sem_wait can be interrupted by a signal.
00034                 // If it occours, it will return with error.
00035                 status = sem_wait( &(prod_cons->prod_sem) );
00036                 if (status < 0) {
00037                         int saved_errno = errno;
00038                         if (saved_errno != EINTR) {
00039                                 printf("WARNING: %s (%d): ", __FILE__, __LINE__);
00040                                 errno = saved_errno; // printf can overwirte errno
00041                                 perror("sem_wait(): ");
00042 #ifdef DEBUG
00043                         } else {
00044                                 printf("%s (%d): sem_wait(): interrupted by signal\n", __FILE__, __LINE__);
00045 #endif                          
00046                         }
00047                 }
00048         } while (status < 0);
00049                 
00050         pthread_mutex_lock( &(prod_cons->prod_mutex) ); 
00051         prod_cons->buffer[prod_cons->prod_pos] = val;
00052         prod_cons->prod_pos = (prod_cons->prod_pos+1) % prod_cons->buf_size;
00053         pthread_mutex_unlock( &(prod_cons->prod_mutex) );
00054         
00055         // Let the consumer get another position
00056         sem_post( &(prod_cons->cons_sem) );
00057         
00058 }
00059 
00060 
00061 void *get(prod_cons_t *prod_cons) {
00062         void *val = NULL;
00063         int status = -1;
00064 
00065         // Wait for someting to be consumed
00066         do {
00067                 // In NPTL, sem_wait can be interrupted by a signal.
00068                 // If it occours, it will return with error.
00069                 status = sem_wait( &(prod_cons->cons_sem) );
00070                 if (status < 0) {
00071                         int saved_errno = errno;
00072                         if (saved_errno != EINTR) {
00073                                 printf("WARNING: %s (%d): ", __FILE__, __LINE__);
00074                                 errno = saved_errno; // printf can overwirte errno
00075                                 perror("sem_wait(): ");
00076 #ifdef DEBUG
00077                         } else {
00078                                 printf("%s (%d): sem_wait(): interrupted by signal\n", __FILE__, __LINE__);
00079 #endif                          
00080                         }
00081                 }
00082         } while (status < 0);
00083         
00084         pthread_mutex_lock( &(prod_cons->cons_mutex) );
00085         val = prod_cons->buffer[prod_cons->cons_pos];
00086         
00087         // Coutinho: clean the consumed position
00088         prod_cons->buffer[prod_cons->cons_pos] = NULL;
00089 
00090         prod_cons->cons_pos = (prod_cons->cons_pos+1) % prod_cons->buf_size;
00091         pthread_mutex_unlock( &(prod_cons->cons_mutex) );
00092         
00093         // Free one buffer's position
00094         sem_post( &(prod_cons->prod_sem) );
00095         return val;
00096 }
00097 
00098 
00099 void destroy_prod_cons(prod_cons_t *prod_cons) {
00100 
00101         // Coutinho: XXX: For now we are destroying the buffer even if there's someting inside
00102         sem_destroy( &(prod_cons->prod_sem) );
00103         sem_destroy( &(prod_cons->cons_sem) );
00104         free(prod_cons->buffer);
00105         free(prod_cons);
00106         
00107 }
00108 

Generated on Tue Jan 17 19:18:38 2006 for Void by  doxygen 1.4.6