From: Lukas Jiriste Date: Thu, 13 Jun 2024 16:32:21 +0000 (+0200) Subject: Fix deadlock, introduce another bug X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=6ec9922e7bb5943c13c4b3afdf5bf6a5d0cb0d01;p=42%2Fphilosophers.git Fix deadlock, introduce another bug The deadlock would happen in the case that 2 philosophers starve at almost the same time. Their starvation_watchers both leave their loop and one continues as usual - posting death and turning its philo dead. The philos, that didn't yet turn dead through the end watcher but the one starvation watcher that triggered but didn't win the terminal has the philo locked (it would turn the philo dead if it got the term) but that makes the end watcher unable to make the philo dead. This is solved by introducing another lock so that the philo is locked even though the end watcher is not. The problem now is that neither normal (not double) death ends the philos nor the "well fed" end. --- diff --git a/philo_bonus/helpers.c b/philo_bonus/helpers.c index 44c7980..5413ef0 100644 --- a/philo_bonus/helpers.c +++ b/philo_bonus/helpers.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 09:13:40 by ljiriste #+# #+# */ -/* Updated: 2024/05/30 14:45:17 by ljiriste ### ########.fr */ +/* Updated: 2024/06/13 17:48:39 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,7 +50,7 @@ void report(t_philo *philo, const char *str) return ; } -static const char *philo_sem_name_base = "philosophers_philo_"; +static const char *philo_name_base = "philosophers_philo_"; char *create_philo_sem_name(unsigned int id) { @@ -60,13 +60,43 @@ char *create_philo_sem_name(unsigned int id) char *id_str; id_str = ft_uitoa_base(id, "0123456789"); - name = malloc(ft_strlen(philo_sem_name_base) + ft_strlen(id_str) + 1); + name = malloc(ft_strlen(philo_name_base) + ft_strlen(id_str) + 1); if (!name) return (NULL); i = 0; - while(philo_sem_name_base[i]) + while(philo_name_base[i]) { - name[i] = philo_sem_name_base[i]; + name[i] = philo_name_base[i]; + ++i; + } + j = 0; + while (id_str[j]) + { + name[i + j] = id_str[j]; + ++j; + } + name[i + j] = '\0'; + free(id_str); + return (name); +} + +static const char *philo_block_name_base = "philosophers_philo_block_"; + +char *create_philo_block_sem_name(unsigned int id) +{ + char *name; + size_t i; + size_t j; + char *id_str; + + id_str = ft_uitoa_base(id, "0123456789"); + name = malloc(ft_strlen(philo_block_name_base) + ft_strlen(id_str) + 1); + if (!name) + return (NULL); + i = 0; + while(philo_block_name_base[i]) + { + name[i] = philo_block_name_base[i]; ++i; } j = 0; diff --git a/philo_bonus/philo.c b/philo_bonus/philo.c index a8b62f8..9bb0e93 100644 --- a/philo_bonus/philo.c +++ b/philo_bonus/philo.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 08:45:21 by ljiriste #+# #+# */ -/* Updated: 2024/05/30 14:43:45 by ljiriste ### ########.fr */ +/* Updated: 2024/06/13 17:45:30 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,14 +21,20 @@ static int open_semaphores(t_philo *philo) philo->philo_sem_name = create_philo_sem_name(philo->id); if (!philo->philo_sem_name) return (1); - philo->philo_sem = sem_open(philo->philo_sem_name, O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR, 1); + philo->philo_block_sem_name = create_philo_block_sem_name(philo->id); + if (!philo->philo_block_sem_name) + return (1); + philo->philo_sem = sem_open(philo->philo_sem_name, + O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1); + philo->philo_block_sem = sem_open(philo->philo_block_sem_name, + O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0); 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); philo->semaphores.end = sem_open(END_SEM, 0); if (philo->philo_sem == SEM_FAILED + || philo->philo_block_sem == SEM_FAILED || philo->semaphores.forks == SEM_FAILED || philo->semaphores.fed == SEM_FAILED || philo->semaphores.death == SEM_FAILED @@ -80,7 +86,13 @@ static void clear_philo(t_philo *philo) sem_close(philo->philo_sem); sem_unlink(philo->philo_sem_name); } + if (philo->philo_block_sem_name && philo->philo_block_sem != SEM_FAILED) + { + sem_close(philo->philo_block_sem); + sem_unlink(philo->philo_block_sem_name); + } free(philo->philo_sem_name); + free(philo->philo_block_sem_name); return ; } diff --git a/philo_bonus/philo.h b/philo_bonus/philo.h index 2f6cf26..e85b78e 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/30 13:15:08 by ljiriste ### ########.fr */ +/* Updated: 2024/06/13 17:48:39 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -66,7 +66,9 @@ typedef struct s_philosopher useconds_t last_eaten; t_sems semaphores; char *philo_sem_name; + char *philo_block_sem_name; sem_t *philo_sem; + sem_t *philo_block_sem; t_settings settings; } t_philo; @@ -88,6 +90,7 @@ int is_alive(t_philo *philo); void report(t_philo *philo, const char *str); void print_timestamp(t_philo *philo, const char *str); char *create_philo_sem_name(unsigned int id); +char *create_philo_block_sem_name(unsigned int id); int create_watchers(t_philo *philo, pthread_t watchers[2]); void destroy_watchers(pthread_t watchers[2]); diff --git a/philo_bonus/watchers.c b/philo_bonus/watchers.c index 0ae0db2..0774a44 100644 --- a/philo_bonus/watchers.c +++ b/philo_bonus/watchers.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/24 08:49:46 by ljiriste #+# #+# */ -/* Updated: 2024/05/30 14:25:33 by ljiriste ### ########.fr */ +/* Updated: 2024/06/13 18:25:35 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,16 +43,18 @@ static void *watch_for_starvation(void *philo_void) sem_wait(philo->philo_sem); time = time_till_death(philo); } + sem_post(philo->philo_block_sem); sem_wait(philo->semaphores.term); + sem_wait(philo->philo_block_sem); if (philo->alive) { print_timestamp(philo, "died"); philo->alive = 0; sem_post(philo->semaphores.death); - sem_post(philo->semaphores.end); + sem_post(philo->philo_block_sem); + sem_wait(philo->semaphores.term); } - else - sem_post(philo->semaphores.term); + sem_post(philo->semaphores.term); sem_post(philo->philo_sem); return (NULL); } @@ -64,9 +66,9 @@ void *watch_for_end(void *philo_void) philo = (t_philo *)philo_void; sem_wait(philo->semaphores.death); sem_post(philo->semaphores.death); - sem_wait(philo->philo_sem); + sem_wait(philo->philo_block_sem); philo->alive = 0; - sem_post(philo->philo_sem); + sem_post(philo->philo_block_sem); sem_post(philo->semaphores.end); return (NULL); }