Sur ce coup, j'ai honte, j'ai fait une FIFO avec des volatile. Allez, envoyez les insul^W remarques
Code PHP:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#define NB_ITER 10
#define BUF_SIZE 10000
typedef uint16_t data_t;
static data_t buf[BUF_SIZE];
static volatile int g_index_read;
static volatile int g_index_write;
static volatile int g_done;
typedef struct {
int total;
uint64_t sum;
} check_t;
/* producer: wait for consumer to complete its job */
static inline void wait_for_consumer(void)
{
/* the consumer doesn't write g_index_write */
int index_write = g_index_write;
while (g_index_read < index_write)
/* usleep(1) */;
}
void *consumer(void *data)
{
int consumer_total;
uint64_t consumer_sum;
check_t *ret = (check_t *)data;
printf("consumer: Starting\n");
consumer_total = 0;
consumer_sum = 0;
do {
if (g_index_read > g_index_write && g_index_read == BUF_SIZE) {
g_index_read = 0;
} if (g_index_read < g_index_write) {
consumer_total++;
consumer_sum += buf[g_index_read++];
}
} while (!g_done);
ret->total = consumer_total;
ret->sum = consumer_sum;
pthread_exit(NULL);
}
void producer(int iter, check_t *ret)
{
int i, j, nb;
int producer_total;
uint64_t producer_sum;
data_t data;
printf("producer: Starting\n");
srand(0);
producer_total = 0;
producer_sum = 0;
for (i = 0; i < iter; i++) {
nb = rand() % BUF_SIZE + 1;
producer_total += nb;
for (j = 0; j < nb; j++) {
wait_for_consumer();
/* produce data */
if (g_index_write == BUF_SIZE) {
/* buffer is full */
g_index_write = 0;
}
data = rand();
buf[g_index_write++] = data;
producer_sum += data;
}
}
wait_for_consumer();
g_done = 1;
ret->total = producer_total;
ret->sum = producer_sum;
}
int main(int argc, const char *argv[])
{
pthread_t tid;
int ret;
check_t consumer_check;
check_t producer_check;
unsigned long iter;
iter = NB_ITER;
if (argc == 2)
iter = strtoul(argv[1], NULL, 10);
g_index_read = 0;
g_index_write = 0;
g_done = 0;
/* create consumer */
ret = pthread_create(&tid, NULL, consumer, &consumer_check);
if (ret) {
fprintf(stderr, "pthread_create: %s\n", strerror(ret));
exit(1);
}
producer(iter, &producer_check);
/* wait for consumer to end */
ret = pthread_join(tid, NULL);
if (ret) {
fprintf(stderr, "pthread_join: %s\n", strerror(ret));
exit(1);
}
printf("Producer: t=%d s=%ld\n", producer_check.total, producer_check.sum);
printf("Consumer: t=%d s=%ld\n", consumer_check.total, consumer_check.sum);
return 0;
}