Skip to content

Commit

Permalink
feat: complete project
Browse files Browse the repository at this point in the history
  • Loading branch information
drawbu committed Apr 29, 2024
1 parent 1ed393f commit f92e6b7
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
60 changes: 55 additions & 5 deletions src/panoramix.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,54 @@ static void *run_villager(villager_t *villager)
printf("Villager %lu: Going into battle!\n", villager->id);

while (villager->fights < villager->gaule->nb_fights) {
// drink le water
pthread_mutex_lock(&villager->gaule->mutex);
villager->fights++;
/* villager->gaule->pot_size--; */
printf(
"Villager %lu: I need a drink... I see %lu servings left.\n",
villager->id, villager->gaule->pot_size);
villager->id, villager->gaule->pot);

if (villager->gaule->pot == 0) {
printf(
"Villager %lu: Hey Pano wake up! We need more potion.\n",
villager->id);
sem_post(&villager->gaule->sem_druid);
sem_wait(&villager->gaule->sem_villagers);
}
villager->gaule->pot--;
pthread_mutex_unlock(&villager->gaule->mutex);

// bagarre
villager->fights++;
printf(
"Villager %lu: Take that roman scum! Only %lu left.\n",
villager->id, villager->gaule->nb_fights - villager->fights);
}

// a mimir
printf("Villager %lu: I'm going to sleep now.\n", villager->id);
return villager;
}

static void *run_druid(gaule_t *gaule)
{
printf("Druid: I'm ready... but sleepy...\n");
while (true) {
sem_wait(&gaule->sem_druid);
if (gaule->refills >= gaule->nb_refills) {
printf("Druid: I'm out of viscum. I'm going back to... zZz\n");
break;
}
gaule->pot = gaule->pot_size;
gaule->refills++;
printf(
"Druid: Ah! Yes, yes, I'm awake! Working on it! Beware I can "
"only make %lu more refills after this one.\n",
gaule->nb_refills - gaule->refills);
sem_post(&gaule->sem_villagers);
}
return gaule;
}

int panoramix(int argc, char **argv)
{
gaule_t gaule = {0};
Expand All @@ -85,19 +120,34 @@ int panoramix(int argc, char **argv)
// Initalize mutex and villagers
if (pthread_mutex_init(&gaule.mutex, NULL) != 0)
return perror("mutex"), Error;
pthread_mutex_lock(&gaule.mutex);
if (sem_init(&gaule.sem_druid, 0, 0) == -1 ||
sem_init(&gaule.sem_villagers, 0, 0) == -1)
return perror("sem_init"), Error;

gaule.pot = gaule.pot_size;

for (size_t i = 0; i < gaule.nb_villagers; i++) {
villager_t *vil = gaule.villagers + i;
*vil = (villager_t){.id = i, .gaule = &gaule};
if (pthread_create(
&vil->thread, NULL, (void *(*)(void *)) & run_villager, vil))
return perror("pthread_create"), Error;
}
pthread_mutex_unlock(&gaule.mutex);

// drouid
pthread_t druid = {0};
if (pthread_create(&druid, NULL, (void *(*)(void *)) & run_druid, &gaule))
return perror("pthread_create"), Error;

// catch me if you can
for (size_t i = 0; i < gaule.nb_villagers; i++)
if (pthread_join(gaule.villagers[i].thread, NULL))
return perror("pthread_join"), Error;

pthread_cancel(druid);
if (pthread_join(druid, NULL))
return perror("pthread_join"), Error;

pthread_mutex_destroy(&gaule.mutex);
free(gaule.villagers);
return Valid;
Expand Down
8 changes: 8 additions & 0 deletions src/panoramix.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

typedef struct gaule_s gaule_t;
Expand All @@ -30,6 +31,13 @@ typedef struct gaule_s {
pthread_mutex_t mutex;
villager_t *villagers;
pthread_t tdruid;

// 👉 👈
sem_t sem_druid;
sem_t sem_villagers;

unsigned long pot;
unsigned long refills;
} gaule_t;

int panoramix(int argc, char **argv);

0 comments on commit f92e6b7

Please sign in to comment.