/**
 * seeds.c
 * programik przedstawiajacy dzialanie watkow w C
 *
 * @author	jan komadowski
 * @email	lookout@losoft.org
 *
 */
 
#include <stdio.h>
#include <string.h>
#include <pthread.h>

int grain; // ziarno na polu
int granary; // ziarno w spichlerzu

// struktura wlasciwosci zbieracza
struct collector
{
	char name[32]; // nazwa zbieracza
	int seeds; // ilosc zebranych ziaren
	int performance; // wydajnosc
};

void* collect_seeds (void* collector_data)
{
	// pobranie danych zbieracza
	struct collector *data;
	data = (struct collector *) collector_data;
	
	// zebranie ziarna
	int collected;
	collected = data->performance;
	if (collected <= grain) {
		grain = grain - collected;
	} else {
		collected = grain;
		grain = 0;
	}
	
	// aktualizacja danych zbieracza
	data->seeds = data->seeds + collected;
	printf ("%s zebral %i\n", data->name, collected);
	
	// zwrocenie ilosci zebranych ziaren
	return (void*) collected;
}

int main (int argc, char *argv[])
{
	// ustalenie ilosci ziarna
	if (argc == 2 && atoi(argv[1]) > 0) {
		grain = atoi(argv[1]);
	}
	if (grain == 0)
		grain = 1000;
	granary = 1; // nie wymietli wszystkiego ; )
	
	// mieszadlo liczb losowych
	srand (time (0));
	
	// ustalanie danych zbieraczy
	struct collector collector1;
	strncpy (collector1.name, "Dziwigor", sizeof (collector1.name) - 1);
	collector1.seeds = 0;
	collector1.performance = rand() % 10 + 1; // losowanie wydajnosci

	struct collector collector2;
	strncpy (collector2.name, "Niesiebud", sizeof (collector2.name) - 1);
	collector2.seeds = 0;
	collector2.performance = rand() % 10 + 1;
	
	printf ("Ziarno na polu: %i ziaren\n", grain);
	printf ("Ziarno w spichlerzu: %i ziaren\n", granary);
	printf ("Zaczely sie zniwa\n\n");
	
	int collected_seeds;
	
	// wskazniki do watkow zbieraczy
	pthread_t thread1;
	pthread_t thread2;
	
	// petelka dopoki nie zostanie zebrane cale ziarno
	while (grain > 0) {
		// utworzenie watku Dziwigora
		pthread_create (&thread1, NULL, collect_seeds, (void*)&collector1);
		// pobranie zebranych ziaren
		pthread_join (thread1, (void*) &collected_seeds);
		// aktualizacja spichlerza
		granary = granary + collected_seeds;
		
		pthread_create (&thread2, NULL, (void*) collect_seeds, (void*)&collector2);
		pthread_join (thread1, (void*) &collected_seeds);
		granary = granary + collected_seeds;
		
		printf ("Pozostalo: %i ziaren\n", grain);
	}
	
	printf ("\nZniwa zakonczone\n");
	printf ("%s zebral %i\n", collector1.name, collector1.seeds);
	printf ("%s zebral %i\n", collector2.name, collector2.seeds);
	
	printf ("Ziarno na polu: %i ziaren\n", grain);
	printf ("Ziarno w spichlerzu: %i ziaren\n", granary);
}

