1 /* The classic producer-consumer example, implemented with semaphores. 2 All integers between 0 and 9999 should be printed exactly twice, 3 once to the right of the arrow and once to the left. */ 4 5 #include <stdio.h> 6 #include "pthread.h" 7 #include "semaphore.h" 8 9 #define BUFFER_SIZE 16 10 11 /* Circular buffer of integers. */ 12 13 struct prodcons { 14 int buffer[BUFFER_SIZE]; /* the actual data */ 15 int readpos, writepos; /* positions for reading and writing */ 16 sem_t sem_read; /* number of elements available for reading */ 17 sem_t sem_write; /* number of locations available for writing */ 18 }; 19 20 /* Initialize a buffer */ 21 22 void init(struct prodcons * b) 23 { 24 sem_init(&b->sem_write, 0, BUFFER_SIZE - 1); 25 sem_init(&b->sem_read, 0, 0); 26 b->readpos = 0; 27 b->writepos = 0; 28 } 29 30 /* Store an integer in the buffer */ 31 32 void put(struct prodcons * b, int data) 33 { 34 /* Wait until buffer is not full */ 35 sem_wait(&b->sem_write); 36 /* Write the data and advance write pointer */ 37 b->buffer[b->writepos] = data; 38 b->writepos++; 39 if (b->writepos >= BUFFER_SIZE) b->writepos = 0; 40 /* Signal that the buffer contains one more element for reading */ 41 sem_post(&b->sem_read); 42 } 43 44 /* Read and remove an integer from the buffer */ 45 46 int get(struct prodcons * b) 47 { 48 int data; 49 /* Wait until buffer is not empty */ 50 sem_wait(&b->sem_read); 51 /* Read the data and advance read pointer */ 52 data = b->buffer[b->readpos]; 53 b->readpos++; 54 if (b->readpos >= BUFFER_SIZE) b->readpos = 0; 55 /* Signal that the buffer has now one more location for writing */ 56 sem_post(&b->sem_write); 57 return data; 58 } 59 60 /* A test program: one thread inserts integers from 1 to 10000, 61 the other reads them and prints them. */ 62 63 #define OVER (-1) 64 65 struct prodcons buffer; 66 67 static void *producer(void * data) 68 { 69 int n; 70 for (n = 0; n < 10000; n++) { 71 printf("%d --->\n", n); 72 put(&buffer, n); 73 } 74 put(&buffer, OVER); 75 return NULL; 76 } 77 78 static void *consumer(void * data) 79 { 80 int d; 81 while (1) { 82 d = get(&buffer); 83 if (d == OVER) break; 84 printf("---> %d\n", d); 85 } 86 return NULL; 87 } 88 89 int libc_ex5(void) 90 { 91 pthread_t th_a, th_b; 92 void * retval; 93 94 init(&buffer); 95 /* Create the threads */ 96 pthread_create(&th_a, NULL, producer, 0); 97 pthread_create(&th_b, NULL, consumer, 0); 98 /* Wait until producer and consumer finish. */ 99 pthread_join(th_a, &retval); 100 pthread_join(th_b, &retval); 101 return 0; 102 } 103 #include <finsh.h> 104 FINSH_FUNCTION_EXPORT(libc_ex5, example 5 for libc); 105 106