Make main wait for a possible philo death
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 5 Sep 2024 09:32:45 +0000 (11:32 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 5 Sep 2024 09:32:45 +0000 (11:32 +0200)
This makes main less demanding as it also enters sleep when no
philosopher's death is near.

philo/main.c

index 11c1ceb3e50b80546eceb68ba0babcb81ae2f9c7..2e7558326e00481d0403aaa95708e864642298ec 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/22 11:19:48 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/05/09 12:31:31 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/09/05 11:32:29 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -41,17 +41,28 @@ static int  seat_philosophers(t_diner *diner, pthread_t *threads)
        return (0);
 }
 
-static int     is_dead(t_philo *philo)
+static void    get_closest_to_death(t_diner *diner,
+                               size_t *philo_ind_out, useconds_t *closest_death_time)
 {
-       mutex_lock(&philo->philo_lock);
-       if (usecs_since_start(philo->settings->start) - philo->last_eaten
-               > philo->settings->time_to_die)
+       size_t          i;
+       t_philo         *philo;
+       useconds_t      death_time;
+
+       i = 0;
+       while (i < diner->setting.philo_count)
        {
+               philo = diner->philos + i;
+               mutex_lock(&philo->philo_lock);
+               death_time = philo->last_eaten + diner->setting.time_to_die;
                mutex_unlock(&philo->philo_lock);
-               return (1);
+               if (i == 0 || death_time < *closest_death_time)
+               {
+                       *philo_ind_out = i;
+                       *closest_death_time = death_time;
+               }
+               ++i;
        }
-       mutex_unlock(&philo->philo_lock);
-       return (0);
+       return ;
 }
 
 static int     all_full(t_diner *diner)
@@ -76,22 +87,19 @@ static int  all_full(t_diner *diner)
 
 static enum e_end      watch_philosophers(t_diner *diner)
 {
-       size_t  i;
+       size_t          philo_ind;
+       useconds_t      closest_death_time;
 
        while (1)
        {
-               i = 0;
-               while (i < diner->setting.philo_count)
+               get_closest_to_death(diner, &philo_ind, &closest_death_time);
+               if (closest_death_time < usecs_since_start(diner->setting.start))
                {
-                       if (is_dead(diner->philos + i))
-                       {
-                               mutex_lock(&diner->setting.end_lock);
-                               diner->setting.end = 1;
-                               mutex_unlock(&diner->setting.end_lock);
-                               print_timestamp(diner->philos + i, "died");
-                               return (death);
-                       }
-                       ++i;
+                       mutex_lock(&diner->setting.end_lock);
+                       diner->setting.end = 1;
+                       mutex_unlock(&diner->setting.end_lock);
+                       print_timestamp(diner->philos + philo_ind, "died");
+                       return (death);
                }
                if (all_full(diner))
                {
@@ -100,6 +108,7 @@ static enum e_end   watch_philosophers(t_diner *diner)
                        mutex_unlock(&diner->setting.end_lock);
                        return (well_fed);
                }
+               usleep(closest_death_time - usecs_since_start(diner->setting.start));
        }
 }