| #include <pthread.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <unistd.h> |
| #include <stdbool.h> |
| #include <string.h> |
| #define NUM_THREADS 11 |
| |
| struct bin { |
| bool ready; |
| int food[NUM_THREADS+1]; |
| int trash[NUM_THREADS+1]; |
| pthread_mutex_t mutex; |
| }; |
| |
| struct party_ticket { |
| long threadid; |
| struct bin *party; |
| }; |
| |
| struct bin *party; |
| |
| void eat(long tid) |
| { |
| bool eat_in_order = true; |
| long t; |
| |
| /* If anyone ate out of place lets take notice of that... */ |
| for (t=0; t < tid; t++) { |
| if (party->food[t]) |
| eat_in_order = false; |
| } |
| |
| if (party->food[tid]) |
| party->food[tid] = 0; |
| } |
| |
| void cleanup(long tid) |
| { |
| bool clean_follow = true; |
| long t; |
| |
| for (t=0; t < tid; t++) { |
| if (!party->trash[t]) |
| clean_follow = false; |
| } |
| |
| party->trash[tid] = 1; |
| } |
| |
| void *thread_party(void *t) |
| { |
| long tid = (long)t; |
| |
| pthread_mutex_lock(&party->mutex); |
| eat(tid); |
| |
| if (tid % 2 == 1) |
| sleep(1); |
| |
| cleanup(tid); |
| pthread_mutex_unlock(&party->mutex); |
| |
| pthread_exit(NULL); |
| } |
| |
| void show_party(struct bin *party) |
| { |
| long t; |
| |
| printf("FOOD: [ "); |
| |
| for (t=0; t < NUM_THREADS; t++) { |
| if (party->food[t]) |
| printf("*"); |
| else |
| printf(" "); |
| } |
| printf(" ]\n"); |
| |
| printf("TRASH: [ "); |
| for (t=0; t < NUM_THREADS; t++) { |
| if (party->trash[t]) |
| printf("*"); |
| else |
| printf(" "); |
| } |
| printf(" ]\n"); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| pthread_t threads[NUM_THREADS]; |
| int ret; |
| long t; |
| pthread_attr_t attr; |
| void *status; |
| |
| party = malloc(sizeof(struct bin)); |
| if (!party) |
| return -ENOMEM; |
| memset(party, 0, sizeof(struct bin)); |
| for (t=0; t <= NUM_THREADS; t++) { |
| party->food[t] = 1; |
| party->trash[t] = 0; |
| } |
| party->ready = true; |
| |
| printf("Before party:\n"); |
| show_party(party); |
| |
| pthread_mutex_init(&party->mutex, NULL); |
| |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
| |
| for (t=0; t < NUM_THREADS; t++) { |
| ret = pthread_create(&threads[t], &attr, thread_party, (void *)t); |
| if (ret){ |
| printf("ERROR; return code from pthread_create() is %d\n", ret); |
| exit(-1); |
| } |
| } |
| |
| pthread_attr_destroy(&attr); |
| for (t=0; t < NUM_THREADS; t++) |
| pthread_join(threads[t], &status); |
| |
| printf("\nAfter party:\n"); |
| show_party(party); |
| |
| pthread_mutex_destroy(&party->mutex); |
| pthread_exit(NULL); |
| |
| free(party); |
| } |