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
00017 sem_init( &(prod_cons->prod_sem), 0, sz);
00018
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
00032 do {
00033
00034
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;
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
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
00066 do {
00067
00068
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;
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
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
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
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