From: Lukas Jiriste Date: Thu, 30 May 2024 08:17:06 +0000 (+0200) Subject: Implement waiting for death/fed in the main X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=6980661;p=42%2Fphilosophers.git Implement waiting for death/fed in the main This is only half the protocol implementation. It is complicated because I cannot use signal handlers to clean after the philosopers. The basic idea is that an end condition posts the death semaphore. It is that used and posted imediately by the threads waiting for it. In main thread waiting for death this ends the thread_fed. The thread then waits for all philosophers to switch to not alive so that it can post the term semaphore without any printing. The term semaphore has to be posted because philosophers may be waiting for it and would be stuck there forever. To be implemented in next commit: In philosopher thread the death semahore couses the alive var to switch to 0. Additionally the philosopher posts the end semaphore which (when all philos do so) signals to the main process it can post the term semaphore. --- diff --git a/philo_bonus/hunger_watcher.c b/philo_bonus/hunger_watcher.c index 03edef8..3dbe35f 100644 --- a/philo_bonus/hunger_watcher.c +++ b/philo_bonus/hunger_watcher.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/24 08:49:46 by ljiriste #+# #+# */ -/* Updated: 2024/05/24 15:33:10 by ljiriste ### ########.fr */ +/* Updated: 2024/05/30 10:00:31 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,6 +43,8 @@ static void *watch_for_starvation(void *philo_void) sem_wait(philo->philo_sem); time = time_till_death(philo); } + sem_wait(philo->semaphores.term); + print_timestamp(philo, "died"); philo->alive = 0; sem_post(philo->semaphores.death); sem_post(philo->philo_sem); diff --git a/philo_bonus/main.c b/philo_bonus/main.c index 924ea7b..41b985c 100644 --- a/philo_bonus/main.c +++ b/philo_bonus/main.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/22 11:19:48 by ljiriste #+# #+# */ -/* Updated: 2024/05/24 15:32:12 by ljiriste ### ########.fr */ +/* Updated: 2024/05/30 10:15:37 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -54,9 +54,54 @@ void kill_philosophers(unsigned int count, pid_t *philo_pids) } } -void handle_philosophers(__attribute__((unused)) t_sems *semaphores) +void *check_fed(void *input) { - sleep(5); + unsigned int philo_count; + int *end; + t_sems *semaphores; + + philo_count = ((t_check *)input)->philo_count; + semaphores = ((t_check *)input)->semaphores; + end = ((t_check *)input)->end; + while (philo_count > 0) + { + sem_wait(semaphores->fed); + --philo_count; + } + sem_wait(semaphores->check_end); + if (!*end) + { + sem_wait(semaphores->term); + printf("All philosophers are well fed\n"); + *end = 1; + } + sem_post(semaphores->check_end); + sem_post(semaphores->death); + return (NULL); +} + +void wait_for_end(unsigned int philo_count, t_sems *semaphores) +{ + pthread_t thread_fed; + int end; + t_check check_input; + + check_input.end = &end; + check_input.philo_count = philo_count; + check_input.semaphores = semaphores; + pthread_create(&thread_fed, NULL, check_fed, &check_input); + sem_wait(semaphores->death); + sem_wait(semaphores->check_end); + end = 1; + sem_post(semaphores->check_end); + while (philo_count > 0) + { + sem_wait(semaphores->end); + sem_post(semaphores->fed); + --philo_count; + } + sem_post(semaphores->term); + pthread_join(thread_fed, NULL); return ; } @@ -82,7 +127,7 @@ int main(int argc, char **argv) return (3); } sem_post(semaphores.term); - handle_philosophers(&semaphores); + wait_for_end(settings.philo_count, &semaphores); cleanup(philo_pids, &semaphores); return (0); } diff --git a/philo_bonus/mem_management.c b/philo_bonus/mem_management.c index b79c3d5..f7a503b 100644 --- a/philo_bonus/mem_management.c +++ b/philo_bonus/mem_management.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/28 09:39:55 by ljiriste #+# #+# */ -/* Updated: 2024/05/24 15:22:19 by ljiriste ### ########.fr */ +/* Updated: 2024/05/30 11:18:25 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,9 +29,14 @@ static int open_semaphores(unsigned int count, t_sems *semaphores) S_IRUSR | S_IWUSR, 0); semaphores->end = sem_open(END_SEM, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0); - if (semaphores->forks == SEM_FAILED || semaphores->fed == SEM_FAILED - || semaphores->death == SEM_FAILED || semaphores->term == SEM_FAILED - || semaphores->end == SEM_FAILED) + semaphores->check_end = sem_open(CHECK_END_SEM, O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, 1); + if (semaphores->forks == SEM_FAILED + || semaphores->fed == SEM_FAILED + || semaphores->death == SEM_FAILED + || semaphores->term == SEM_FAILED + || semaphores->end == SEM_FAILED + || semaphores->check_end == SEM_FAILED) return (1); return (0); } @@ -53,6 +58,7 @@ void close_semaphores(t_sems *semaphores) sem_close(semaphores->death); sem_close(semaphores->term); sem_close(semaphores->end); + sem_close(semaphores->check_end); return ; } @@ -64,6 +70,7 @@ void cleanup(pid_t *philo_pids, t_sems *semaphores) sem_unlink(DEATH_SEM); sem_unlink(TERM_SEM); sem_unlink(END_SEM); + sem_unlink(CHECK_END_SEM); free(philo_pids); return ; } diff --git a/philo_bonus/philo.h b/philo_bonus/philo.h index b31e659..0895457 100644 --- a/philo_bonus/philo.h +++ b/philo_bonus/philo.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/22 11:10:17 by ljiriste #+# #+# */ -/* Updated: 2024/05/24 15:23:21 by ljiriste ### ########.fr */ +/* Updated: 2024/05/30 10:10:11 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,7 @@ # define DEATH_SEM "philosophers_death" # define TERM_SEM "philosophers_terminal" # define END_SEM "philosophers_end" +# define CHECK_END_SEM "philosophers_check_end" // The .start member holds the result of gettimeofday // Every other member that holds time info counts @@ -46,6 +47,7 @@ typedef struct s_important_semaphores sem_t *death; sem_t *term; sem_t *end; + sem_t *check_end; } t_sems; // As mutex is not available in bonus, the idea is to have @@ -67,6 +69,13 @@ typedef struct s_philosopher t_settings settings; } t_philo; +typedef struct s_check +{ + unsigned int philo_count; + int *end; + t_sems *semaphores; +} t_check; + int parse_input(t_settings *settings, int argc, char **argv); int init(unsigned int count, pid_t **philo_pids,