From: Lukas Jiriste Date: Tue, 19 Mar 2024 14:40:23 +0000 (+0100) Subject: Refactor functions to comply with the Norm X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=c091d1d;p=42%2Fphilosophers_old.git Refactor functions to comply with the Norm --- diff --git a/philo/main.c b/philo/main.c index 3551938..c9f0f96 100644 --- a/philo/main.c +++ b/philo/main.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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);