#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> #include <pthread.h> #include <string.h> #include <stdbool.h> pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // One lock for all threads pthread_cond_t cond_soccerLeads = PTHREAD_COND_INITIALIZER; // In case there are other pair leaders for soccer pthread_cond_t cond_s = PTHREAD_COND_INITIALIZER; // Conditon to wake up soccder bunk bed pthread_cond_t cond_b = PTHREAD_COND_INITIALIZER; // Conditon to wake up baseball bunk bed pthread_cond_t cond_f = PTHREAD_COND_INITIALIZER; // Conditon to wake up football bunk bed pthread_cond_t cond_feild_clear = PTHREAD_COND_INITIALIZER; // Waiting for game to start, as a leader pthread_cond_t cond_inGame = PTHREAD_COND_INITIALIZER; // Playing a game, as a follower int num_on_feild = 0; // Number of people allowed to be on the feild int num_on_feild_actual = 0; // Number of people actually on the feild int num_s, num_b, num_f; // The number of players in the bunkbed for each sport int game_duration = 0; // in seconds bool active_soccer_game = 0; // int global_thread_id = 0; pthread_t soccer[44]; pthread_t football[44]; pthread_t baseball[36]; void *try_to_leave() { // pthread_mutex_lock(&lock); num_on_feild_actual--; printf("Player left the field. There are %i players on the field\n", num_on_feild_actual); if (num_on_feild_actual == 0) { num_on_feild = 0; pthread_cond_signal(&cond_feild_clear); printf("GAME is Over. Sent a signal let in the next leader!\n"); } pthread_mutex_unlock(&lock); } void *try_to_queue(void *arg) { int player_type = (int)arg; int *num = 0; int feild_max = 0; int num_req = 0; pthread_cond_t *cond; char gameName[10] = ""; switch (player_type) { case 0: strcpy(gameName, "SOCCER"); num = &num_s; cond = &cond_s; num_req = 2; feild_max = 22; break; case 1: strcpy(gameName, "BASEBALL"); num = &num_b; cond = &cond_b; num_req = 18; feild_max = 18; break; case 2: strcpy(gameName, "FOOTBALL"); num = &num_f; cond = &cond_f; num_req = 22; feild_max = 22; break; default: printf("Broke\n"); } pthread_mutex_lock(&lock); int myID = global_thread_id; global_thread_id++; pthread_mutex_unlock(&lock); printf("[%s Player %d] I have been created!\n", gameName, myID); int number_of_games_to_play_per_person = 2; for (int j = 0; j < number_of_games_to_play_per_person; j++) { int arrivalTime = (rand() % 5) + 1; printf("[%s Player %d] My random sleep time is %d secconds...\n", gameName, myID, arrivalTime); sleep(arrivalTime); printf("[%s Player %d] I am awake after %d secconds.\n", gameName, myID, arrivalTime); pthread_mutex_lock(&lock); (*num)++; printf("[%s Player %d] Including myself, my bed has %d people. I neeed %d people to start.\n", gameName, myID, *num, num_req); if (*num == num_req || (player_type == 0 && *num % 2 == 0) || (player_type != 0 && *num == num_req * 2)) { POINT2: if (num_on_feild == 0) { pthread_cond_broadcast(cond); printf("[%s Player %d] I am a leader and I will start my game with %d people.\n", gameName, myID, num_req); num_on_feild += num_req; (*num) -= num_req; num_on_feild_actual++; if (player_type == 0) { // You are starting a soccer game printf("[%s Player %d] This game is a soccer game, I need to wake up other soccer leaders. \n", gameName, myID); active_soccer_game = 1; pthread_cond_broadcast(&cond_soccerLeads); } game_duration = (rand() % 5) + 1; printf("%s GAME STARTED with %i players by [%s Player %d] for %i secconds. \n", gameName, num_req, gameName, myID, game_duration); pthread_mutex_unlock(&lock); sleep(game_duration); pthread_mutex_lock(&lock); active_soccer_game = 0; pthread_cond_broadcast(&cond_inGame); try_to_leave(); } else if (active_soccer_game == 1 && player_type == 0 && num_on_feild < feild_max) { // You are joning a exsiting soccer game printf("[%s Player %d] I am a fake soccer leader and I will add %i people to the soccer game which had %i people.\n", gameName, myID, num_req, num_on_feild); pthread_cond_broadcast(cond); num_on_feild += num_req; (*num) -= num_req; num_on_feild_actual++; printf("[%s Player %d] I'm waiting for the game to end...' \n", gameName, myID); pthread_cond_wait(&cond_inGame, &lock); // pthread_mutex_unlock(&lock); try_to_leave(); } else { if (player_type == 0 && (*num) > num_req && (*num) != feild_max + num_req) { printf("[%s Player %d] There %i soccer players waiting. Since there is already an leader, I will wait in a soccerLeads queue to become a fake leader. \n", gameName, myID, *num); pthread_cond_wait(&cond_soccerLeads, &lock); } else { printf("[%s Player %d] I am a leader but I cannot start a game until the feild is clear. I'm waiting to be called when it is. \n", gameName, myID); pthread_cond_wait(&cond_feild_clear, &lock); } printf("[%s Player %d] I have been realeased from my queue. Going to POINT 2.\n", gameName, myID); goto POINT2; } } else { POINT: printf("[%s Player %d] I am not a leader and I will wait in my bed for %d people. \n", gameName, myID, num_req); pthread_cond_wait(cond, &lock); if (num_on_feild_actual < num_on_feild) { num_on_feild_actual++; printf("[%s Player %d] I was woken up and I moved to the feild. I am player %i out of %i.\n", gameName, myID, num_on_feild_actual, num_on_feild); pthread_cond_wait(&cond_inGame, &lock); // pthread_mutex_unlock(&lock); printf("[%s Player %d] I have been released from the game. I am leaving the feild.\n", gameName, myID); try_to_leave(); } else { printf("[%s Player %d] I was woken up but I cannot move to the feild because it is full. I will go back to sleep. \n", gameName, myID); goto POINT; } } } printf("[%s Player %d] I am leaving the program since I have played %i games.\n", gameName, myID, number_of_games_to_play_per_person); } int main() { // Open seed file FILE *fp; char seed[5]; fp = fopen("seed.txt", "r"); // getting seed from file fscanf(fp, "%s", seed); int intseed = atoi(seed); // seed srand srand((unsigned)intseed); // close file fclose(fp); printf("Seed is %i \n", intseed); printf("Each player will play 2 games. You can end the program at any time by pressing ctrl+c. Games will start in 5 secconds...\n"); sleep(5); // soccer for (int i = 0; i < 44; i++) { pthread_create(&soccer[i], NULL, try_to_queue, (void *)0); } // baseball for (int i = 0; i < 36; i++) { pthread_create(&baseball[i], NULL, try_to_queue, (void *)1); } // football for (int i = 0; i < 44; i++) { pthread_create(&football[i], NULL, try_to_queue, (void *)2); } for (int i = 0; i < 44; i++) { pthread_join(soccer[i], NULL); } for (int i = 0; i < 36; i++) { pthread_join(baseball[i], NULL); } for (int i = 0; i < 44; i++) { pthread_join(football[i], NULL); } printf("All threads have finished\n"); }