diff --git a/philo/include/types.h b/philo/include/types.h index 05e4b9c..edb618b 100644 --- a/philo/include/types.h +++ b/philo/include/types.h @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/19 17:19:12 by aschenk #+# #+# */ -/* Updated: 2024/10/11 22:26:12 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:38:34 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -107,16 +107,16 @@ Structure representing the overall simulation state: haven't start eating. - t_eat: Time in milliseconds a philosopher takes to eat. - t_sleep: Time in milliseconds a philosopher sleeps after eating. - - t_think: Philosophers are altruistic in this simulation, meaning they delay - taking forks and eating for as long as possible without starving. - This behavior helps keep every philosopher alive as long as - possible, especially when there's an odd number of philosophers: - t_think = t_die - t_eat - t_sleep. + - t_think: Philosophers are altruistic in this simulation, meaning they + delay taking forks and eating for as long as possible without + starving. This behavior helps keep every philosopher alive as + long as possible, especially when there's an odd number of + philosophers: t_think = t_die - t_eat - t_sleep. - max_meals: Max. number of meals a philosopher can eat before they stop dining; `-1` means unlimited meals. - full_philos: The number of philosophers who have eaten their maximum number of meals (if specified) and have stopped eating. - - philo_dead: Flag indicating if a philosopher has died. + - stop_sim: Flag indicating if to stop the simulation. - t_start_sim: Timestamp in milliseconds for when the simulation started. - forks: Array of forks available for the philosophers. - philos: Array of philosophers participating in the simulation. @@ -127,8 +127,8 @@ Structure representing the overall simulation state: - mtx_full_philos: Mutex for checking / increasing 'full_philos'. - mtx_full_philos_init: Flag checking if 'full_philos' mutex has been initialized. - - mtx_philo_dead: Mutex for synchronizing access to the `philo_dead` flag. - - mtx_philo_dead_init: Flag checking if 'philo dead' mutex has been initialized. + - mtx_stop_sim: Mutex for synchronizing access to the `stop_sim` flag. + - mtx_stop_sim_init: Flag checking if 'stop_sim' mutex has been initialized. */ typedef struct s_sim { @@ -139,7 +139,7 @@ typedef struct s_sim int t_think; int max_meals; int full_philos; - int philo_dead; + int stop_sim; t_ull t_start_sim; t_fork *forks; t_philo *philos; @@ -148,8 +148,8 @@ typedef struct s_sim int mtx_print_init; t_mtx mtx_full_philos; int mtx_full_philos_init; - t_mtx mtx_philo_dead; - int mtx_philo_dead_init; + t_mtx mtx_stop_sim; + int mtx_stop_sim_init; } t_sim; #endif diff --git a/philo/src/2_init_sim.c b/philo/src/2_init_sim.c index 17974e8..14c1c36 100644 --- a/philo/src/2_init_sim.c +++ b/philo/src/2_init_sim.c @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/05 13:53:20 by aschenk #+# #+# */ -/* Updated: 2024/10/11 22:17:42 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:39:03 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,11 +59,11 @@ Sets initial values for the simulation state and initializes mutexes. static int init_sim_state(t_sim *sim, int argc, char **argv) { sim->full_philos = 0; - sim->philo_dead = 0; + sim->stop_sim = 0; sim->forks = NULL; sim->philos = NULL; sim->mtx_print_init = 0; - sim->mtx_philo_dead_init = 0; + sim->mtx_stop_sim_init = 0; if (init_args(sim, argc, argv)) return (1); sim->t_think = sim->t_die - sim->t_eat - sim->t_sleep; @@ -73,9 +73,9 @@ static int init_sim_state(t_sim *sim, int argc, char **argv) return (1); sim->mtx_full_philos_init = 1; sim->mtx_print_init = 1; - if (mtx_action(&sim->mtx_philo_dead, INIT)) + if (mtx_action(&sim->mtx_stop_sim, INIT)) return (1); - sim->mtx_philo_dead_init = 1; + sim->mtx_stop_sim_init = 1; return (0); } diff --git a/philo/src/3_eat.c b/philo/src/3_eat.c index 6a8b55a..d5b693a 100644 --- a/philo/src/3_eat.c +++ b/philo/src/3_eat.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* 4_eat.c :+: :+: :+: */ +/* 3_eat.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/11 16:23:15 by aschenk #+# #+# */ -/* Updated: 2024/10/11 19:54:59 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:30:19 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,7 +85,7 @@ int pick_forks_and_log(t_philo *philo) return (pick_forks(philo)); else { - usleep(900); + (void)usleep(900); return (pick_forks(philo)); } } diff --git a/philo/src/3_eat_sleep_think.c b/philo/src/3_eat_sleep_think.c index 0f4c6bb..131be87 100644 --- a/philo/src/3_eat_sleep_think.c +++ b/philo/src/3_eat_sleep_think.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* 5_eat_sleep_think.c :+: :+: :+: */ +/* 3_eat_sleep_think.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/05 18:47:34 by aschenk #+# #+# */ -/* Updated: 2024/10/11 21:33:23 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:41:10 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,23 +24,23 @@ reaches the maximum number of meals. void *eat_sleep_think(void *arg); /** -Checks whether a philo thread should stop by accessing the `philo_dead` flag. +Checks whether a philo thread should stop by accessing the `stop_sim` flag. - @param sim Pointer to the simulation struct containing the `philo_dead` flag. + @param sim Pointer to the simulation struct containing the `stop_sim` flag. @return The value of the `stop_sim` flag: `0` if no philo died (simulation can continue); `1` if a philosopher has died (simulation should stop); `2` if there is an error in mutex (un)locking. */ -static int check_death(t_philo *philo) +static int stop_sim(t_philo *philo) { int dead; - if (mtx_action(&philo->sim->mtx_philo_dead, LOCK)) + if (mtx_action(&philo->sim->mtx_stop_sim, LOCK)) return (2); - dead = philo->sim->philo_dead; - if (mtx_action(&philo->sim->mtx_philo_dead, UNLOCK)) + dead = philo->sim->stop_sim; + if (mtx_action(&philo->sim->mtx_stop_sim, UNLOCK)) return (2); return (dead); } @@ -141,7 +141,7 @@ void *eat_sleep_think(void *arg) max_meals = philo->sim->max_meals; if (handle_no_meals(philo, max_meals) == 1) return (NULL); - while (check_death(philo) == 0) + while (stop_sim(philo) == 0) { (void)pick_forks_and_log(philo); (void)eat_and_log(philo, t_eat); diff --git a/philo/src/4_monitor.c b/philo/src/4_monitor.c index e9cacdc..3d4fd05 100644 --- a/philo/src/4_monitor.c +++ b/philo/src/4_monitor.c @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/11 17:28:17 by aschenk #+# #+# */ -/* Updated: 2024/10/11 22:16:56 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:39:36 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,10 +53,10 @@ static int handle_death(t_sim *sim, t_philo *philo) if (mtx_action(&philo->mtx_last_meal, UNLOCK) || record_time_of_death(philo) || print_action(philo->timestamp_death, philo, DIE, 0) - || mtx_action(&sim->mtx_philo_dead, LOCK)) + || mtx_action(&sim->mtx_stop_sim, LOCK)) return (2); - sim->philo_dead = 1; - if (mtx_action(&sim->mtx_philo_dead, UNLOCK)) + sim->stop_sim = 1; + if (mtx_action(&sim->mtx_stop_sim, UNLOCK)) return (2); return (1); } @@ -128,7 +128,7 @@ void *monitor(void *arg) return (NULL); i++; } - usleep(100); + (void)usleep(100); } return (NULL); } diff --git a/philo/src/5_run_sim.c b/philo/src/5_run_sim.c index c6f9a12..9ad0e42 100644 --- a/philo/src/5_run_sim.c +++ b/philo/src/5_run_sim.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* 7_run_sim.c :+: :+: :+: */ +/* 5_run_sim.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/11 22:06:38 by aschenk #+# #+# */ -/* Updated: 2024/10/11 22:11:25 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:57:52 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,7 +44,7 @@ static int start_monitoring(t_sim *sim) print_err_msg(ERR_TR_CREATE); return (1); } - usleep(100); + (void)usleep(100); return (0); } @@ -75,6 +75,9 @@ static int end_monitoring(t_sim *sim) Starts the dining simulation by creating threads for each philosopher. Each thread will run the `dining` function that simulates the philosopher's behavior. +If any thread creation fails, the simulation stops, all previously created +threads are joined (cleaned up), and the simulation is terminated. + @param sim Pointer to the sim structure, which holds the philosopher data. @return `0` on success; @@ -83,13 +86,22 @@ thread will run the `dining` function that simulates the philosopher's behavior. static int start_dining(t_sim *sim) { int i; + int nr_philo; i = 0; - while (i < sim->nr_philo) + nr_philo = sim->nr_philo; + while (i < nr_philo) { if (pthread_create(&sim->philos[i].thread_id, NULL, &eat_sleep_think, &sim->philos[i])) { + mtx_action(&sim->mtx_stop_sim, LOCK); + sim->stop_sim = 1; + mtx_action(&sim->mtx_stop_sim, UNLOCK); + while (i-- >= 0) + pthread_join(sim->philos[i].thread_id, NULL); + end_monitoring(sim); + (void)usleep(100); print_err_msg(ERR_TR_CREATE); return (1); } @@ -116,6 +128,11 @@ static int end_dining(t_sim *sim) { if (pthread_join(sim->philos[i].thread_id, NULL)) { + mtx_action(&sim->mtx_stop_sim, LOCK); + sim->stop_sim = 1; + mtx_action(&sim->mtx_stop_sim, UNLOCK); + end_monitoring(sim); + (void)usleep(100); print_err_msg(ERR_TR_JOIN); return (1); } diff --git a/philo/src/utils/1_print_action.c b/philo/src/utils/1_print_action.c index a32dafa..cf5c9da 100644 --- a/philo/src/utils/1_print_action.c +++ b/philo/src/utils/1_print_action.c @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/05 13:49:37 by aschenk #+# #+# */ -/* Updated: 2024/10/11 14:42:29 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:40:16 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -123,13 +123,13 @@ compilation) before being printed to enhance readability (default: no rounding). int print_action(t_ull timestamp, t_philo *philo, t_action action, int update_timestamp) { - mtx_action(&philo->sim->mtx_philo_dead, LOCK); - if (philo->sim->philo_dead) + mtx_action(&philo->sim->mtx_stop_sim, LOCK); + if (philo->sim->stop_sim) { - mtx_action(&philo->sim->mtx_philo_dead, UNLOCK); + mtx_action(&philo->sim->mtx_stop_sim, UNLOCK); return (0); } - mtx_action(&philo->sim->mtx_philo_dead, UNLOCK); + mtx_action(&philo->sim->mtx_stop_sim, UNLOCK); if (mtx_action(&philo->sim->mtx_print, LOCK)) return (1); if (update_timestamp) diff --git a/philo/src/utils/3_time.c b/philo/src/utils/3_time.c index c7c7faa..b8432cc 100644 --- a/philo/src/utils/3_time.c +++ b/philo/src/utils/3_time.c @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/20 20:44:46 by aschenk #+# #+# */ -/* Updated: 2024/10/10 15:51:05 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:31:09 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -128,7 +128,7 @@ int precise_wait(int duration_to_wait) return (1); if (current_time >= time_stop_waiting) break ; - usleep((duration_to_wait * 1000) / SLEEP_INTERVALS); + (void)usleep((duration_to_wait * 1000) / SLEEP_INTERVALS); } return (0); } diff --git a/philo/src/utils/4_free.c b/philo/src/utils/4_free.c index 3afcb9e..0795308 100644 --- a/philo/src/utils/4_free.c +++ b/philo/src/utils/4_free.c @@ -6,7 +6,7 @@ /* By: aschenk +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/18 18:08:52 by aschenk #+# #+# */ -/* Updated: 2024/10/11 19:47:33 by aschenk ### ########.fr */ +/* Updated: 2024/10/11 23:41:25 by aschenk ### ########.fr */ /* */ /* ************************************************************************** */ @@ -95,8 +95,8 @@ void cleanup_sim(t_sim **sim_ptr) clean_philos(sim); if (sim->mtx_print_init) mtx_action(&sim->mtx_print, DESTROY); - if (sim->mtx_philo_dead_init) - mtx_action(&sim->mtx_philo_dead, DESTROY); + if (sim->mtx_stop_sim_init) + mtx_action(&sim->mtx_stop_sim, DESTROY); free(sim); *sim_ptr = NULL; }