Implement waiting for death/fed in the main
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 30 May 2024 08:17:06 +0000 (10:17 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 30 May 2024 09:18:40 +0000 (11:18 +0200)
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.

philo_bonus/hunger_watcher.c
philo_bonus/main.c
philo_bonus/mem_management.c
philo_bonus/philo.h

index 03edef835e6b56749498977f16db8e3e38ffb01e..3dbe35fdfa55b1333ffc2d16519727f70deaa2bd 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
index 924ea7bef462755b3fb30c315340a4c9284daccc..41b985cc652ac0e87abe9102a41c42bb340525db 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
 }
index b79c3d55c10047224ef369e055310067fe7a4f03..f7a503b8910c9ddce86dccdae86682e096345bdd 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 ;
 }
index b31e6591b14c7afc6de0cb7663af4b814cc51d82..0895457c13fbfc82216f092f95c9fcc4bffe637d 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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,