From: Lukas Jiriste Date: Thu, 23 May 2024 07:52:46 +0000 (+0200) Subject: Add semaphore to each philo X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=20b3bffac789da5e1eb381a452ad6b333c311626;p=42%2Fphilosophers.git Add semaphore to each philo To react fast to starving philosopher, there has to be another thread checking the state of the philo. Because of this there has to be a mechanism to prevent data race. Because mutexes are forbidden it has to be a semaphore. This commit contains the semaphore and some code that dictates its usage. --- diff --git a/philo_bonus/philo.c b/philo_bonus/philo.c index 5acbb9e..9550f0c 100644 --- a/philo_bonus/philo.c +++ b/philo_bonus/philo.c @@ -6,19 +6,34 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 08:45:21 by ljiriste #+# #+# */ -/* Updated: 2024/05/12 21:52:05 by ljiriste ### ########.fr */ +/* Updated: 2024/05/23 09:50:14 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" #include +#include +#include -static void open_semaphores(sem_t *semaphores[sem_num]) +static void open_semaphores(t_philo *philo) { - semaphores[forks] = sem_open(FORKS_SEM, 0); - semaphores[fed] = sem_open(WELL_FED_SEM, 0); - semaphores[death] = sem_open(DEATH_SEM, 0); - semaphores[term] = sem_open(TERM_SEM, 0); + char *sem_name; + + philo->semaphores[forks] = sem_open(FORKS_SEM, 0); + philo->semaphores[fed] = sem_open(WELL_FED_SEM, 0); + philo->semaphores[death] = sem_open(DEATH_SEM, 0); + philo->semaphores[term] = sem_open(TERM_SEM, 0); + sem_name = create_philo_sem_name(philo->id); + philo->philo_sem = sem_open(sem_name, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1); + free(sem_name); + if (philo->philo_sem == SEM_FAILED) + { + sem_wait(philo->semaphores[term]); + printf("An error has occured.\n"); + sem_wait(philo->semaphores[death]); + exit(2); + } + return ; } static void philo_think(t_philo *philo) @@ -29,17 +44,14 @@ static void philo_think(t_philo *philo) static void philo_eat(t_philo *philo) { - useconds_t time_now; - sem_wait(philo->semaphores[forks]); print_timestamp(philo, "has taken a fork"); sem_wait(philo->semaphores[forks]); print_timestamp(philo, "has taken a fork"); - time_now = usecs_since_start(philo->settings.start); - if (time_now - philo->last_eaten > philo->settings.time_to_die) - die(philo); - philo->last_eaten = time_now; + sem_wait(philo->philo_sem); + philo->last_eaten = usecs_since_start(philo->settings.start); ++philo->num_eaten; + sem_post(philo->philo_sem); print_timestamp(philo, "is eating"); if (philo->settings.should_check_hunger && philo->num_eaten == philo->settings.min_eat_num) @@ -59,11 +71,16 @@ static void philo_sleep(t_philo *philo) void be_a_philosopher(t_philo *philo) { - open_semaphores(philo->semaphores); - while (1) + pid_t hunger_watcher_pid; + + open_semaphores(philo); + hunger_watcher_pid = create_hunger_watcher(philo); + while (is_alive(philo)) { philo_think(philo); philo_eat(philo); philo_sleep(philo); } + destroy_hunger_watcher(hunger_watcher_pid); + exit(0); } diff --git a/philo_bonus/philo.h b/philo_bonus/philo.h index 7f1e43e..8b3a1d6 100644 --- a/philo_bonus/philo.h +++ b/philo_bonus/philo.h @@ -60,6 +60,7 @@ typedef struct s_philosopher unsigned int id; useconds_t last_eaten; sem_t *semaphores[sem_num]; + sem_t *philo_sem; t_settings settings; } t_philo;