Add semaphore to each philo
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 23 May 2024 07:52:46 +0000 (09:52 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 23 May 2024 07:52:46 +0000 (09:52 +0200)
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.

philo_bonus/philo.c
philo_bonus/philo.h

index 5acbb9ef33146d0a7c7f20defbb6f6389ebab810..9550f0c5c519e1a1a976a412a789eba2bcd47c47 100644 (file)
@@ -6,19 +6,34 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
 
-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);
 }
index 7f1e43e3edd7a81664db6b0b509d917acc9659c6..8b3a1d6c7d7d5bad7bfc8fc3d92e6ea8489f0a61 100644 (file)
@@ -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;