Refactor functions to comply with the Norm
authorLukas Jiriste <ljiriste@student.42prague.com>
Tue, 19 Mar 2024 14:40:23 +0000 (15:40 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 22 Mar 2024 10:01:34 +0000 (11:01 +0100)
philo/main.c

index 35519388e22e5f51523a8d585b4429b64ad1b6e8..c9f0f96b55c3fc6d7f945f5ca645dde220885c69 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/05 12:49:40 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/19 14:39:29 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/19 15:39:58 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -43,7 +43,8 @@ void  thread_print(t_settings *set, size_t id, const char *message)
                pthread_mutex_unlock(&set->terminal);
                return ;
        }
-       printf("%li %li %s\n", (cur_time_sus() - set->program_start) / 1000, id, message);
+       printf("%li %li %s\n", (cur_time_sus() - set->program_start) / 1000,
+               id, message);
        pthread_mutex_unlock(&set->terminal);
        return ;
 }
@@ -81,7 +82,6 @@ void  *be_a_philosopher(void *inp)
        t_philo *philo;
 
        philo = (t_philo *)inp;
-       philo->last_eaten = philo->settings->program_start;
        while (!philo->settings->end)
        {
                philo_think(philo->settings, philo->id);
@@ -257,11 +257,11 @@ int       init_settings(int argc, char **argv, t_settings *set)
        return (parse_input(argc, argv, set));
 }
 
-
 //     "pthread_detach(threads[count]);" should be sufficient
 //     instead of pthread_join(thread[count], NULL) but valgrind
 //     then shows leaks
-void   cleanup(pthread_mutex_t *forks, t_philo *philos, pthread_t *threads, t_settings *set)
+void   cleanup(pthread_mutex_t *forks, t_philo *philos, pthread_t *threads,
+               t_settings *set)
 {
        size_t  count;
 
@@ -279,64 +279,111 @@ void     cleanup(pthread_mutex_t *forks, t_philo *philos, pthread_t *threads, t_sett
        return ;
 }
 
-void   create_philos(t_philo *philos, pthread_t *threads, size_t count)
+void   create_philos(t_philo *philos, pthread_t *threads, t_settings *set)
 {
+       size_t  count;
+
+       count = set->philo_count;
        while (count > 0)
        {
                --count;
+               philos[count].last_eaten = set->program_start;
                pthread_create(threads + count, NULL, be_a_philosopher, philos + count);
        }
        return ;
 }
 
-void   check_death(t_philo *philos, t_settings *set)
+int    philo_died(t_philo *philo, t_settings *set)
 {
-       suseconds_t     oldest;
-       suseconds_t     now;
        size_t          i;
-       int                     all_full;
+       suseconds_t     now;
 
-       while (1)
+       i = 0;
+       now = cur_time_sus();
+       while (i < set->philo_count)
        {
-               i = 0;
-               now = cur_time_sus();
-               all_full = set->min_eats_num > 0;
-               oldest = philos[0].last_eaten;
-               while (i < set->philo_count)
+               if ((now - philos[i].last_eaten) > set->time_to_die)
                {
-                       if((now - philos[i].last_eaten) > set->time_to_die)
-                       {
-                               pthread_mutex_lock(&set->terminal);
-                               printf("%li %lu %s\n", (cur_time_sus() - set->program_start) / 1000, i + 1, g_die_str);
-                               set->end = 1;
-                               pthread_mutex_unlock(&set->terminal);
-                               return ;
-                       }
-                       if (oldest > philos[i].last_eaten)
-                               oldest = philos[i].last_eaten;
-                       all_full = (all_full && (philos[i].times_eaten >= set->min_eats_num));
-                       ++i;
+                       pthread_mutex_lock(&set->terminal);
+                       printf("%li %lu %s\n", (cur_time_sus() - set->program_start)
+                               / 1000, i + 1, g_die_str);
+                       set->end = 1;
+                       pthread_mutex_unlock(&set->terminal);
+                       return (1);
                }
-               if (all_full)
+               ++i;
+       }
+       return (0);
+}
+
+int    all_full(t_philo *philos, t_settings *set)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < set->philo_count)
+       {
+               if (philos[i].times_eaten < set->min_eats_num)
+                       return (0);
+               ++i;
+       }
+       return (1);
+}
+
+suseconds_t    time_to_starve(t_philo *philos, t_settings *set)
+{
+       suseconds_t     furthest_eaten;
+       size_t          i;
+
+       i = 0;
+       while (i < set->philo_count)
+       {
+               if (furthest_eaten > philos[i].last_eaten)
+                       furthest_eaten = philos[i].last_eaten;
+               ++i;
+       }
+       return (set->time_to_die - (cur_time_sus() - furthest_eaten));
+}
+
+void   check_death(t_philo *philos, t_settings *set)
+{
+       while (!philo_died(philos, set))
+       {
+               if (all_full(philos, set))
                {
                        pthread_mutex_lock(&set->terminal);
-                       printf("%li %s\n", (cur_time_sus() - set->program_start) / 1000, g_fed_str);
+                       printf("%li %s\n", (cur_time_sus() - set->program_start) / 1000,
+                               g_fed_str);
                        set->end = 1;
                        pthread_mutex_unlock(&set->terminal);
                        return ;
                }
-               now = cur_time_sus();
-               usleep(set->time_to_die - (now - oldest));
+               usleep(time_to_starve(philos, set));
        }
 }
 
-int    handle_single_philo(t_settings *set)
+void   handle_single_philo(t_settings *set)
 {
        set->program_start = cur_time_sus();
        thread_print(set, 1, g_think_str);
        thread_print(set, 1, g_fork_str);
        usleep(set->time_to_die);
        thread_print(set, 1, g_die_str);
+       return ;
+}
+
+int    special_cases(t_settings *set)
+{
+       if (set->end)
+       {
+               printf("0 %s\n", g_fed_str);
+               return (1);
+       }
+       if (set->philo_count == 1)
+       {
+               handle_single_philo(set);
+               return (1);
+       }
        return (0);
 }
 
@@ -352,13 +399,8 @@ int        main(int argc, char **argv)
                printf("Invalid input arguments.\n");
                return (1);
        }
-       if (settings.end)
-       {
-               printf("0 %s\n", g_fed_str);
+       if (special_cases(&settings))
                return (0);
-       }
-       if (settings.philo_count == 1)
-               return (handle_single_philo(&settings));
        threads = malloc(sizeof(pthread_t) * settings.philo_count);
        forks = init_forks(settings.philo_count);
        philos = build_philos(forks, &settings);
@@ -368,8 +410,7 @@ int main(int argc, char **argv)
                return (2);
        }
        settings.program_start = cur_time_sus();
-       create_philos(philos, threads, settings.philo_count);
-       usleep(settings.time_to_die / 10);
+       create_philos(philos, threads, &settings);
        check_death(philos, &settings);
        cleanup(forks, philos, threads, &settings);
        return (0);