#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#define NUM_THREADS	31

enum thead_id_status {
	THREAD_AT_HOME = 0,
	THREAD_AT_PARTY = 1,
	THREAD_DONE = 2,
};

struct bin {
	bool ready;
	int food[NUM_THREADS+1];
	int trash[NUM_THREADS+1];
	int tid_status[NUM_THREADS+1];
	pthread_mutex_t mutex;
};

struct party_ticket {
	long threadid;
	struct bin *party;
};

struct bin *party;

static void sleep_random(void)
{
	unsigned int val;

	val = 10000LL * rand() / RAND_MAX;
	srand(getpid());
	usleep(val);
}

void eat(long tid)
{
	bool eat_in_order = true;
	long t;

	pthread_mutex_lock(&party->mutex);
	/* If anyone ate out of place lets take notice of that... */
	for (t=0; t < NUM_THREADS; t++) {
		if (t == tid)
			continue;
		if (party->tid_status[t] >= THREAD_AT_PARTY &&
		    party->food[t])
			eat_in_order = false;
	}

	sleep_random();

	if (party->food[tid])
		if (eat_in_order)
			party->food[tid] = 0;
	pthread_mutex_unlock(&party->mutex);
}

void cleanup(long tid)
{
	bool clean_follow = true;
	long t;

	for (t=0; t < NUM_THREADS; t++) {
		if (t == tid)
			continue;
		if (party->tid_status[t] >= THREAD_DONE &&
		    !party->trash[t])
			clean_follow = false;
	}

	if (clean_follow)
		party->trash[tid] = 1;
}

void *thread_party(void *t)
{
	long tid = (long)t;

	party->tid_status[tid] = THREAD_AT_PARTY;

	eat(tid);

	if (tid % 2 == 1)
		sleep_random();

	cleanup(tid);

	party->tid_status[tid] = THREAD_DONE;

	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");
}

#define pthread_mutex_protects_3(mutex, var1, var2, var3)

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->tid_status[t] = THREAD_AT_HOME;
	}
	party->ready = true;

	printf("Before party:\n");
	show_party(party);

	pthread_mutex_init(&party->mutex, NULL);
	pthread_mutex_protects_3(&party->mutex,
				 party->food,
				 party->trash,
				 party->tid_status);

	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);
}
