Fix deadlock, introduce another bug bonus
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 13 Jun 2024 16:32:21 +0000 (18:32 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 13 Jun 2024 16:32:21 +0000 (18:32 +0200)
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.

philo_bonus/helpers.c
philo_bonus/philo.c
philo_bonus/philo.h
philo_bonus/watchers.c

index 44c7980f6ee513f045ee48c651f4504942c9a57a..5413ef0db7e749f74f5c2b338706a60529e96da4 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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;
index a8b62f8b46efe9d958b3a907e98b0c7012eef280..9bb0e933b19bcfd6b989d34c38ea78a1f5e9c1ae 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 ;
 }
 
index 2f6cf26c05e86a766c195228e43547a8001426bf..e85b78ecb930f934a7cfd33bb0edd1661071973e 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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]);
index 0ae0db2d129f399e0554cf4f9f4b3c940e4a4c62..0774a442ea8985a031dedfffe8640c0807fa499c 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
 }