/* 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 */
/* */
/* ************************************************************************** */
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 ;
}
t_philo *philo;
philo = (t_philo *)inp;
- philo->last_eaten = philo->settings->program_start;
while (!philo->settings->end)
{
philo_think(philo->settings, philo->id);
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;
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);
}
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);
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);