From 1a7c6c5a0ed9a5aae1fe45c3af335c120c2dc642 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 10 Feb 2020 00:34:47 +0100 Subject: WIP: philo one --- philo_one/Makefile | 16 ++++++---- philo_one/fork.c | 59 +++++++++++++++++++++++++++++++++++ philo_one/main.c | 43 +++++++++++++++++++++----- philo_one/philo.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ philo_one/philo_one.h | 71 ++++++++++++++++++++++++++++++++++-------- philo_one/routine.c | 53 ++++++++++++++++++++++++++++++++ 6 files changed, 300 insertions(+), 27 deletions(-) create mode 100644 philo_one/fork.c create mode 100644 philo_one/philo.c create mode 100644 philo_one/routine.c (limited to 'philo_one') diff --git a/philo_one/Makefile b/philo_one/Makefile index 0c9125c..e647316 100644 --- a/philo_one/Makefile +++ b/philo_one/Makefile @@ -6,25 +6,29 @@ # By: cacharle +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2019/11/24 05:50:15 by cacharle #+# #+# # -# Updated: 2019/11/24 07:07:35 by cacharle ### ########.fr # +# Updated: 2020/02/10 00:16:03 by cacharle ### ########.fr # # # # **************************************************************************** # RM = rm -f +COMMON_DIR = ../common + CC = gcc -CCFLAGS = -Wall -Wextra #-Werror -LDFLAGS = -lpthread +CCFLAGS = -I$(COMMON_DIR) -Wall -Wextra #-Werror +LDFLAGS = -lpthread -L$(COMMON_DIR) -lphilocommon NAME = philo_one -SRC = main.c -OBJ = $(SRC:.c=.o) +SRC = main.c \ + philo.c \ + fork.c +OBJ = $(SRC:.c=.o) all: $(NAME) $(NAME): $(OBJ) - $(CC) $(LDFLAGS) -o $@ $(OBJ) + $(CC) -o $@ $(OBJ) $(LDFLAGS) %.o: %.c $(CC) $(CCFLAGS) -c -o $@ $^ diff --git a/philo_one/fork.c b/philo_one/fork.c new file mode 100644 index 0000000..d42510b --- /dev/null +++ b/philo_one/fork.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fork.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/09 23:46:40 by cacharle #+# #+# */ +/* Updated: 2020/02/10 00:34:17 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +t_fork *forks_new(int num) +{ + int i; + t_fork *forks; + + if ((forks = (t_fork*)malloc(sizeof(t_fork) * num)) == NULL) + return (NULL); + i = -1; + while (++i < num) + { + if (pthread_mutex_init(&forks[num].mutex, NULL) != 0) + { + forks_destroy(forks, i + 1); + return (NULL); + } + } + return (forks); +} + +void forks_destroy(t_fork *forks, int num) +{ + while (num-- > 0) + { + forks[num].used = TRUE; + pthread_mutex_destroy(&forks[num].mutex); + } +} + +t_routine_arg *forks_dispatch(t_philo *philos, t_fork *forks, t_philo_args *args) +{ + int i; + t_routine_arg *routine_args; + + if ((routine_args = (t_routine_arg*)malloc(sizeof(t_routine_arg) * args->philo_num)) == NULL) + return (NULL); + i = -1; + while (++i < args->philo_num) + { + routine_args[i].args = args; + routine_args[i].philo = philos + i; + routine_args[i].fork_left = forks + i % args->philo_num; + routine_args[i].fork_left = forks + (i - 1) % args->philo_num; + } + return (routine_args); +} diff --git a/philo_one/main.c b/philo_one/main.c index 3bb1181..ef00a0b 100644 --- a/philo_one/main.c +++ b/philo_one/main.c @@ -6,21 +6,48 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/24 05:53:02 by cacharle #+# #+# */ -/* Updated: 2019/11/24 06:35:10 by cacharle ### ########.fr */ +/* Updated: 2020/02/10 01:29:50 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo_one.h" + int main(int argc, char **argv) { - if (argc != 5 || argc != 6) + t_philo_args philo_args; + t_philo *philos; + t_fork *forks; + t_routine_arg *routine_args; + + if (!parse_args(&philo_args, argc, argv)) + return (1); + if ((forks = forks_new(philo_args.philo_num - 1)) == NULL) + return (1); + if ((philos = philos_new(philo_args.philo_num)) == NULL) + { + free(forks); + return (1); + } + if ((routine_args = forks_dispatch(philos, forks, &philo_args)) == NULL) + { + free(forks); + free(philos); + return (1); + } + if (!philos_start(philos, routine_args, philo_args.philo_num)) + { + free(philos); + free(forks); + free(routine_args); return (1); - int philo_nb = ft_atoi(argv[1]); - int death_timer = ft_atoi(argv[2]); - int eat_timer = ft_atoi(argv[3]); - int sleep_timer = ft_atoi(argv[4]); - if (argc == 6) - int eat_nb = ft_atoi(argv[5]); + } + while (TRUE) + if (philos_starved(philos, philo_args.philo_num)) + break; + philos_join(philos, philo_args.philo_num); + free(philos); + free(forks); + free(routine_args); return (0); } diff --git a/philo_one/philo.c b/philo_one/philo.c new file mode 100644 index 0000000..7cc3ca4 --- /dev/null +++ b/philo_one/philo.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* philo.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/09 23:47:14 by cacharle #+# #+# */ +/* Updated: 2020/02/10 01:29:25 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +t_philo *philos_new(int num) +{ + int i; + t_philo *philos; + + if (num < 0) + return (NULL); + if ((philos = (t_philo*)h_calloc(num + 1, sizeof(t_philo))) == NULL) + return (NULL); + i = -1; + while (++i < num) + { + philos[i].id = i + 1; + philos[i].alive = FALSE; + } + return (philos); +} + +void philos_destroy(t_philo *philos, int num) +{ + (void)num; + if (philos == NULL) + return ; + free(philos); +} + +t_bool philos_start(t_philo *philos, t_routine_arg *routine_args, int num) +{ + t_routine_arg *routine_arg; + int i; + + i = -1; + while (++i < num) + { + philos[i].alive = TRUE; + if (pthread_create(philos[i].thread, NULL, philo_one_routine, (void*)(routine_args + i)) == -1) + return (FALSE); + } + return (TRUE); +} + +void philos_join(t_philo *philos, int num) +{ + int i; + + i = -1; + while (++i < num) + { + if (philos[i].alive) + { + philos[i].alive = FALSE; + pthread_join(philos[i].thread, NULL); + } + } +} + +t_bool philos_starved(t_philo *philos, int num) +{ + int i; + + i = -1; + while (++i < num) + if (!philos[i].alive) + { + i = -1; + while (++i < num) + philos[i].alive = FALSE; + return (TRUE); + } + return (FALSE); +} diff --git a/philo_one/philo_one.h b/philo_one/philo_one.h index 4bf9d14..bcac634 100644 --- a/philo_one/philo_one.h +++ b/philo_one/philo_one.h @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/24 06:11:16 by cacharle #+# #+# */ -/* Updated: 2019/11/24 06:55:48 by cacharle ### ########.fr */ +/* Updated: 2020/02/10 01:14:27 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,26 +16,71 @@ # include # include # include +# include +# include "common.h" -typedef enum +typedef struct { - STATE_EATING, - STATE_THINKING, - STATE_SLEEPING, - STATE_TOOK_FORK, - STATE_DEAD -} t_philo_state; + t_bool used; + pthread_mutex_t mutex; +} t_fork; + +// typedef struct +// { +// t_philo *philos; +// t_fork *forks; +// } t_table; +typedef struct s_philo t_philo; typedef struct +{ + t_philo *watched; + pthread_t thread; +} t_watchdog; + +struct s_philo { int id; - t_philo_state state; t_bool alive; - int forks[2]; - int finished_time; -} t_philo + t_watchdog watchdog; + int time_last_eat; + t_philo_state state; + pthread_t thread; +}; + +typedef struct +{ + t_philo_args *args; + t_philo *philo; + t_fork *fork_left; + t_fork *fork_right; +} t_routine_arg; +tine_death_arg; + +/* +** fork.c +*/ + +t_fork *forks_new(int num); +void forks_destroy(t_fork *forks, int num); +t_routine_arg *forks_dispatch(t_philo *philos, t_fork *forks, t_philo_args *args); + +/* +** philo.c +*/ + +t_philo *philos_new(int num); +void philos_destroy(t_philo *philos, int num); +t_bool philos_start(t_philo *philos, t_routine_arg *routine_args, int num); +void philos_join(t_philo *philos, int num); +t_bool philos_starved(t_philo *philos, int num); + +/* +** routine.c +*/ -void print_state_change(int timestamp, t_philo_state state); +void *routine_philo(t_routine_arg *arg); +void *routine_death(t_routine_arg *arg); #endif diff --git a/philo_one/routine.c b/philo_one/routine.c new file mode 100644 index 0000000..48f3c0d --- /dev/null +++ b/philo_one/routine.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* routine.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/10 01:11:27 by cacharle #+# #+# */ +/* Updated: 2020/02/10 01:19:13 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +void *routine_philo(t_routine_arg *routine_arg) +{ + pthread_t thread_death; + + if (pthread_create(&thread_death, NULL, routine_death, routine_arg) != 0) + return (NULL); + philo_think(routine_arg->philo->id); + while (routine_arg->philo->alive && !philo_starved(routine_arg->philo)) + { + if (!routine_arg->fork_left->used && !routine_arg->fork_right->used) + { + pthread_mutex_lock(&routine_arg->fork_left->mutex); + pthread_mutex_lock(&routine_arg->fork_right->mutex); + philo_eat(routine_arg->philo->id, routine_arg->args->timeout_eat); + pthread_mutex_unlock(&routine_arg->fork_left->mutex); + pthread_mutex_unlock(&routine_arg->fork_right->mutex); + philo_sleep(routine_arg->philo->id, routine_arg->args->timeout_sleep); + philo_think(routine_arg->philo->id); + } + } + if (routine_arg->philo->alive) + philo_die(routine_arg->philo->id); + free(routine_arg); + return (NULL); +} + +void *routine_death(t_routine_arg *arg) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + return (NULL); + while (arg->philo->alive && + arg->philo->time_last_eat - tv.asd > arg->args->timeout_death) + if (gettimeofday(&tv, NULL) == -1) + return (NULL); + arg->philo->alive = FALSE; + return (NULL); +} -- cgit