From 471ca75712f69148dee606c44efb9567672a503a Mon Sep 17 00:00:00 2001 From: Adam Joly Date: Mon, 12 Aug 2024 20:52:02 +0200 Subject: [PATCH] =?UTF-8?q?=E3=80=8C=E2=9C=A8=E3=80=8D=20feat:=20seems=20t?= =?UTF-8?q?o=20be=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- philo/eat.c | 23 ++++++---- philo/end_philo.c | 28 ------------- philo/init_fork.c | 29 ------------- philo/log.c | 21 +++++++++- philo/monitor.c | 48 +++++++++++++++++++++ philo/parsing.c | 45 +++++++++----------- philo/philo.h | 37 ++++++++-------- philo/philo_msg.h | 4 +- philo/philo_routine.c | 16 +------ philo/{init_philo.c => run_philo.c} | 65 +++++++++++++++++++++++------ philo/{sleep.c => usleep.c} | 26 ++++++------ philo/{utils.c => util.c} | 30 ++++++++++++- philo/util_philo.c | 53 ----------------------- 13 files changed, 219 insertions(+), 206 deletions(-) delete mode 100644 philo/end_philo.c delete mode 100644 philo/init_fork.c create mode 100644 philo/monitor.c rename philo/{init_philo.c => run_philo.c} (56%) rename philo/{sleep.c => usleep.c} (74%) rename philo/{utils.c => util.c} (66%) delete mode 100644 philo/util_philo.c diff --git a/philo/eat.c b/philo/eat.c index 365a5bb..8d31c31 100644 --- a/philo/eat.c +++ b/philo/eat.c @@ -6,32 +6,41 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/08 17:29:51 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:05:07 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 20:50:55 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" +void take_fork(t_fork *fork, int id) +{ + if (id % 2) + pthread_mutex_lock(&fork->left); + else if (!(id % 2)) + pthread_mutex_lock(fork->right); +} + bool philo_eat(t_philo *philo) { philo->state = FORK_TAKEN; take_fork(&philo->fork, philo->id); - if (get_death(false, true, philo)) + if (get_death(philo, RETURN)) return (true); log_philo(philo); if (&(philo->fork.left) == philo->fork.right) - return (true); + return (print_death(philo)); take_fork(&philo->fork, philo->id + 1); - if (get_death(false, true, philo)) - return (true); +// if (get_death(philo, RETURN)) +// return (true); log_philo(philo); philo->state = EAT; - gettimeofday(&(philo->eat), NULL); log_philo(philo); + gettimeofday(&philo->eat, NULL); if (sleep_phil(philo) == true) return (true); pthread_mutex_unlock(&philo->fork.left); pthread_mutex_unlock(philo->fork.right); - philo->meal_left--; + if (philo->data.no_meal == false && philo->meal_left > 0) + philo->meal_left--; return (false); } diff --git a/philo/end_philo.c b/philo/end_philo.c deleted file mode 100644 index cc51479..0000000 --- a/philo/end_philo.c +++ /dev/null @@ -1,28 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* end_philo.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/07/24 18:19:14 by adjoly #+# #+# */ -/* Updated: 2024/07/26 16:50:54 by adjoly ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo.h" - -void end_philo(pthread_t *thread, uint16_t philo_nbr) -{ - uint16_t i; - int r; - - i = 0; - while (i < philo_nbr) - { - r = pthread_join(thread[i], NULL); - if (r != 0) - return ; - i++; - } -} diff --git a/philo/init_fork.c b/philo/init_fork.c deleted file mode 100644 index 2189359..0000000 --- a/philo/init_fork.c +++ /dev/null @@ -1,29 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* init_fork.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/07/22 15:29:08 by adjoly #+# #+# */ -/* Updated: 2024/07/31 17:40:57 by adjoly ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo.h" -#include - -void init_fork(t_pdata data) -{ - uint8_t i; - t_philo philo[PHILO_MAX]; - - i = 0; - while (i < data.philo_nbr) - { - pthread_mutex_init(&(philo[i].fork.left), NULL); - philo[i].fork.right = &philo[(i + 1) % data.philo_nbr].fork.left; - i++; - } - init_philo(data, philo); -} diff --git a/philo/log.c b/philo/log.c index 77e5086..2395e87 100644 --- a/philo/log.c +++ b/philo/log.c @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/07 16:12:20 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:01:52 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 19:38:58 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,23 @@ #include "philo_msg.h" #include +bool print_err(uint8_t error) +{ + if (error == 0) + printf(ERR_MAX_PHIL); + else if (error == 1) + printf(ERR_MAX_DIE_TIME); + else if (error == 2) + printf(ERR_MAX_EAT_TIME); + else if (error == 3) + printf(ERR_MAX_SLEEP_TIME); + else if (error == 4) + printf(ERR_MAX_MEAL); + else if (error == 5) + printf(ERR_NB_ARG); + return (true); +} + void log_philo(t_philo *philo) { uint32_t timestamp; @@ -21,8 +38,8 @@ void log_philo(t_philo *philo) static pthread_mutex_t print = {0}; gettimeofday(&t1, NULL); - timestamp = get_time_in_ms(philo->t0, t1); pthread_mutex_lock(&print); + timestamp = get_time_in_ms(philo->t0, t1); if (philo->state == EAT) printf("%u %hu %s", timestamp, philo->id, EATING_MSG); else if (philo->state == THINK) diff --git a/philo/monitor.c b/philo/monitor.c new file mode 100644 index 0000000..a8249b4 --- /dev/null +++ b/philo/monitor.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* monitor.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: adjoly +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/12 12:13:35 by adjoly #+# #+# */ +/* Updated: 2024/08/12 20:50:17 by adjoly ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo.h" + +bool philo_check(t_philo *philo, t_pdata data) +{ + uint8_t i; + struct timeval t1; + uint8_t eaten; + + i = 0; + eaten = 0; + while (i < data.philo_nbr) + { + gettimeofday(&t1, NULL); + if (get_time_in_ms(philo[i].eat, t1) > data.die_time) + { + pthread_mutex_unlock(&philo[i].fork.left); + pthread_mutex_unlock(philo[i].fork.right); + return (print_death(&philo[i])); + } + if (philo[i].meal_left == 0) + eaten++; + if (get_death(philo, RETURN)) + return (true); + i++; + } + if (eaten == data.philo_nbr) + return (true); + return (false); +} + +void monitor(t_philo *philo, t_pdata data) +{ + while (!philo_check(philo, data)) + usleep(100); + get_death(philo, true); +} diff --git a/philo/parsing.c b/philo/parsing.c index ff4cab4..00875be 100644 --- a/philo/parsing.c +++ b/philo/parsing.c @@ -6,35 +6,20 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/08 15:30:46 by adjoly #+# #+# */ -/* Updated: 2024/08/08 17:26:05 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 19:39:43 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" #include "philo_msg.h" -bool print_err(uint8_t error) -{ - if (error == 0) - printf(ERR_MAX_PHIL); - else if (error == 1) - printf(ERR_MAX_DIE_TIME); - else if (error == 2) - printf(ERR_MAX_EAT_TIME); - else if (error == 3) - printf(ERR_MAX_SLEEP_TIME); - else if (error == 4) - printf(ERR_MAX_MEAL); - else if (error == 5) - printf(ERR_NB_ARG); - return (true); -} +bool print_err(uint8_t error); bool check_av(char **av) { if (!av) return (print_err(5)); - if (ft_strlen(av[0]) > 3) + if (ft_strlen(av[0]) > 3 || ft_atoll(av[0]) > 200) return (print_err(0)); if (ft_strlen(av[1]) > 11) return (print_err(1)); @@ -54,12 +39,27 @@ t_pdata ret_err(t_pdata data, uint8_t error) return (data); } +t_pdata meal_nb(char **av, t_pdata data) +{ + if (av[4]) + { + data.meal_nbr = ft_atoll(av[4]); + if (data.meal_nbr > 1000) + return (ret_err(data, 4)); + data.no_meal = false; + } + else + data.no_meal = true; + return (data); +} + + t_pdata fill_pdata(char **av) { t_pdata data; data.philo_nbr = 0; - if (!av && check_av(av)) + if (!av || check_av(av)) return (ret_err(data, 255)); data.philo_nbr = ft_atoll(av[0]); if (data.philo_nbr > 200) @@ -73,12 +73,7 @@ t_pdata fill_pdata(char **av) data.sleep_time = ft_atoll(av[3]); if (data.sleep_time > 2147483647) return (ret_err(data, 3)); - if (av[4]) - { - data.meal_nbr = ft_atoll(av[4]); - if (data.meal_nbr > 1000) - return (ret_err(data, 4)); - } + data = meal_nb(av, data); data.error = false; return (data); } diff --git a/philo/philo.h b/philo/philo.h index 33070ef..b04e491 100644 --- a/philo/philo.h +++ b/philo/philo.h @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/07 15:11:02 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:12:39 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 19:04:16 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,43 +58,44 @@ typedef struct s_philo t_fork fork; t_pstate state; t_pdata data; + bool *death; pthread_mutex_t *check; } t_philo; +typedef enum s_bool_death +{ + RETURN = -1, + FALSE, + TRUE +} t_bool_death; + /** - * Utils + * Parsing */ size_t ft_strlen(char *s); -uint16_t get_meal_nb(uint16_t meal_nbr, bool no_meal); -bool get_death(bool in, bool ret, t_philo *philo); +t_pdata philo_parse(char **av, int ac); long long ft_atoll(const char *nptr); -uint32_t get_time_in_ms(struct timeval t0, struct timeval t1); -uint32_t get_current_time(void); -void log_philo(t_philo *philo); -bool sleep_phil(t_philo *philo); -t_pdata philo_parse(char **argv, int ac); +uint32_t get_time_in_ms(struct timeval t0, struct timeval t1); bool print_death(t_philo *philo); -bool philo_eat(t_philo *philo); +bool get_death(t_philo *philo, t_bool_death set); + /** * Main path * by order of call */ void init_fork(t_pdata data); void init_philo(t_pdata data, t_philo *philo); +void monitor(t_philo *philo, t_pdata data); void end_philo(pthread_t *thread, uint16_t philo_nbr); -void *philo_routine(void *content); - /** * Routine func */ -void take_fork(t_fork *fork, int id); -bool eat(t_philo *philo); +void *philo_routine(void *content); -/** - * For debug purpose to be REMOVED - */ -void print_philo_data(t_pdata data); +bool philo_eat(t_philo *philo); +void log_philo(t_philo *philo); +bool sleep_phil(t_philo *philo); #endif diff --git a/philo/philo_msg.h b/philo/philo_msg.h index 64a014d..3b52cd8 100644 --- a/philo/philo_msg.h +++ b/philo/philo_msg.h @@ -6,7 +6,7 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/07 17:50:46 by adjoly #+# #+# */ -/* Updated: 2024/08/06 19:47:17 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 17:32:08 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,6 @@ # define ERR_MAX_EAT_TIME "Time to eat too long < INT_MAX\n" // err 2 # define ERR_MAX_SLEEP_TIME "Time to sleep too long < INT_MAX\n" // err 3 # define ERR_MAX_MEAL "Too much meal < 1000\n" // err 4 -# define ERR_NB_ARG "Invalid number of args 4 or 5\n" // err 5 +# define ERR_NB_ARG "Invalid number of args need to be 4 or 5\n" // err 5 #endif diff --git a/philo/philo_routine.c b/philo/philo_routine.c index 191d3a8..ae26acf 100644 --- a/philo/philo_routine.c +++ b/philo/philo_routine.c @@ -6,36 +6,24 @@ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/22 21:24:53 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:37:39 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 20:27:14 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" #include -void take_fork(t_fork *fork, int id) -{ - if (id % 2 && !(&fork->left == fork->right)) - pthread_mutex_lock(&fork->left); - else if (!(id % 2)) - pthread_mutex_lock(fork->right); -} - void *philo_routine(void *content) { t_philo *philo; philo = content; - gettimeofday(&(philo->eat), NULL); - philo->meal_left = get_meal_nb(philo->data.meal_nbr, philo->data.no_meal); if (!(philo->id % 2)) usleep(10); while (1) { - if (philo_eat(philo) == true) + if (philo_eat(philo)) break ; - if (philo->meal_left == 0) - return (NULL); philo->state = SLEEP; log_philo(philo); if (sleep_phil(philo)) diff --git a/philo/init_philo.c b/philo/run_philo.c similarity index 56% rename from philo/init_philo.c rename to philo/run_philo.c index 842a58f..6fd6e08 100644 --- a/philo/init_philo.c +++ b/philo/run_philo.c @@ -1,41 +1,80 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* init_philo.c :+: :+: :+: */ +/* run_philo.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 14:36:59 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:07:47 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 20:23:30 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" #include -void init_philo(t_pdata data, t_philo *philo) +void end_philo(pthread_t *thread, uint16_t philo_nbr) { - int r; - pthread_mutex_t check; - pthread_t thread[PHILO_MAX]; - struct timeval time; - uint8_t i; + uint8_t i; + int r; i = 0; + while (i < philo_nbr) + { + r = pthread_join(thread[i], NULL); + if (r != 0) + return ; + i++; + } +} + +void init_fork(t_pdata data) +{ + uint8_t i; + t_philo philo[PHILO_MAX]; + + i = 0; + while (i < data.philo_nbr) + { + pthread_mutex_init(&(philo[i].fork.left), NULL); + philo[i].fork.right = &(philo[(i + 1) % data.philo_nbr].fork.left); + i++; + } + init_philo(data, philo); +} + +uint16_t get_meal_nb(uint16_t meal_nbr, bool no_meal) +{ + if (no_meal == true) + return (1); + else + return (meal_nbr); +} + +void init_philo(t_pdata data, t_philo *philo) +{ + pthread_mutex_t check; + pthread_t thread[PHILO_MAX]; + uint8_t i; + bool death; + struct timeval time; + + i = 0; + death = false; pthread_mutex_init(&check, NULL); - philo[i].check = ✓ - get_death(false, false, philo); gettimeofday(&time, NULL); while (i < data.philo_nbr) { philo[i].id = i + 1; philo[i].data = data; philo[i].check = ✓ + philo[i].eat = time; philo[i].t0 = time; - r = pthread_create(&thread[i], NULL, philo_routine, &philo[i]); - if (r != 0) - break ; + philo[i].death = &death; + philo[i].meal_left = get_meal_nb(data.meal_nbr, data.no_meal); + pthread_create(&thread[i], NULL, philo_routine, &philo[i]); i++; } + monitor(philo, data); end_philo(thread, data.philo_nbr); } diff --git a/philo/sleep.c b/philo/usleep.c similarity index 74% rename from philo/sleep.c rename to philo/usleep.c index 190d0ec..a270c49 100644 --- a/philo/sleep.c +++ b/philo/usleep.c @@ -1,17 +1,24 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* sleep.c :+: :+: :+: */ +/* usleep.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/23 17:15:24 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:06:32 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 20:47:05 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" -#define SLEEP_SLICE_MS 5 + +uint32_t get_current_time(void) +{ + struct timeval time; + + gettimeofday(&time, NULL); + return (time.tv_sec * 1000 + time.tv_usec / 1000); +} uint32_t get_sleep_time(t_philo *philo) { @@ -26,21 +33,14 @@ uint32_t get_sleep_time(t_philo *philo) bool sleep_phil(t_philo *philo) { - struct timeval t1; - uint32_t sleep_time; + uint32_t sleep_time; sleep_time = get_sleep_time(philo); while (get_current_time() < sleep_time) { - if (get_death(false, true, philo)) + if (get_death(philo, RETURN)) return (true); - gettimeofday(&t1, NULL); - if (get_time_in_ms(philo->eat, t1) > philo->data.die_time) - { - get_death(true, false, philo); - return (print_death(philo)); - } - usleep(SLEEP_SLICE_MS * 1000); + usleep(1000); } return (false); } diff --git a/philo/utils.c b/philo/util.c similarity index 66% rename from philo/utils.c rename to philo/util.c index 0fba6f2..5f06e3b 100644 --- a/philo/utils.c +++ b/philo/util.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* utils.c :+: :+: :+: */ +/* util.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: adjoly +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/31 21:20:49 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:17:09 by adjoly ### ########.fr */ +/* Updated: 2024/08/12 19:28:24 by adjoly ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,3 +45,29 @@ long long ft_atoll(const char *nptr) } return (nbr * sign); } + +uint32_t get_time_in_ms(struct timeval t0, struct timeval t1) +{ + return (((t1.tv_sec - t0.tv_sec) * 1000000 + \ + t1.tv_usec - t0.tv_usec) / 1000); +} + +bool print_death(t_philo *philo) +{ + get_death(philo, TRUE); + philo->state = DEAD; + log_philo(philo); + return (true); +} + +bool get_death(t_philo *philo, t_bool_death set) +{ + bool ret; + + pthread_mutex_lock(philo->check); + if (set != RETURN) + *(philo->death) = true; + ret = *philo->death; + pthread_mutex_unlock(philo->check); + return (ret); +} diff --git a/philo/util_philo.c b/philo/util_philo.c deleted file mode 100644 index 543303f..0000000 --- a/philo/util_philo.c +++ /dev/null @@ -1,53 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* util_philo.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: adjoly +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/08/08 18:16:45 by adjoly #+# #+# */ -/* Updated: 2024/08/08 18:16:53 by adjoly ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo.h" - -uint16_t get_meal_nb(uint16_t meal_nbr, bool no_meal) -{ - if (no_meal == true) - return (1); - else - return (meal_nbr); -} - -uint32_t get_current_time(void) -{ - struct timeval time; - - gettimeofday(&time, NULL); - return (time.tv_sec * 1000 + time.tv_usec / 1000); -} - -bool get_death(bool in, bool ret, t_philo *philo) -{ - static bool death; - - pthread_mutex_lock(philo->check); - if (ret == false) - death = in; - pthread_mutex_unlock(philo->check); - return (death); -} - -uint32_t get_time_in_ms(struct timeval t0, struct timeval t1) -{ - return (((t1.tv_sec - t0.tv_sec) * 1000000 + \ - t1.tv_usec - t0.tv_usec) / 1000); -} - -bool print_death(t_philo *philo) -{ - philo->state = DEAD; - log_philo(philo); - return (true); -}