From 1a7c6c5a0ed9a5aae1fe45c3af335c120c2dc642 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 10 Feb 2020 00:34:47 +0100 Subject: WIP: philo one --- .gitignore | 1 + Makefile | 17 ++++++++--- common/Makefile | 38 +++++++++++++++++++++++ common/common.c | 6 ++-- common/common.h | 31 +++++-------------- common/helper.c | 2 +- common/philo.c | 53 ++++++++------------------------ 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 ++++++++++++++++++++++++++++++++ 13 files changed, 376 insertions(+), 99 deletions(-) create mode 100644 common/Makefile create mode 100644 philo_one/fork.c create mode 100644 philo_one/philo.c create mode 100644 philo_one/routine.c diff --git a/.gitignore b/.gitignore index 8cae5ea..4275a65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.o *.ghc +*.a a.out philo_one/philo_one philo_two/philo_two diff --git a/Makefile b/Makefile index 3ebc3ac..61d67c3 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: cacharle +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/02/09 03:31:28 by cacharle #+# #+# # -# Updated: 2020/02/09 03:32:56 by cacharle ### ########.fr # +# Updated: 2020/02/09 22:38:47 by cacharle ### ########.fr # # # # **************************************************************************** # @@ -17,11 +17,20 @@ PHILO_ONE_DIR = philo_one PHILO_TWO_DIR = philo_two PHILO_THREE_DIR = philo_three -philo_one: +help: + @echo "make common - build common lib" + @echo "make philo_one - compile philo_one" + @echo "make philo two - compile philo_one" + @echo "make philo three - compile philo_one" + +common: + $(MAKE) $(MAKE_ARGS) $(COMMON_DIR) + +philo_one: common $(MAKE) $(MAKE_ARGS) $(PHILO_ONE_DIR) -philo_two: +philo_two: common $(MAKE) $(MAKE_ARGS) $(PHILO_TWO_DIR) -philo_two: +philo_two: common $(MAKE) $(MAKE_ARGS) $(PHILO_THREE_DIR) diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 0000000..cf3089c --- /dev/null +++ b/common/Makefile @@ -0,0 +1,38 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: cacharle +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/02/09 22:39:08 by cacharle #+# #+# # +# Updated: 2020/02/09 23:57:34 by cacharle ### ########.fr # +# # +# **************************************************************************** # + +LIB = ar rcs +RM = rm -rf + +CC = gcc +CCFLAGS = -Wall -Wextra -Werror + +NAME = libphilocommon.a + +SRC = $(shell find . -type f -name "*.c") +OBJ = $(SRC:.c=.o) + +all: $(NAME) + +$(NAME): $(OBJ) + $(LIB) $(NAME) $(OBJ) + +%.o: %.c + $(CC) $(CCFLAGS) -c -o $@ $< + +clean: + $(RM) $(OBJ) + +fclean: clean + $(RM) $(NAME) + +re: fclean all diff --git a/common/common.c b/common/common.c index be35e69..03fc32f 100644 --- a/common/common.c +++ b/common/common.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/08 23:12:55 by cacharle #+# #+# */ -/* Updated: 2020/02/09 01:36:40 by cacharle ### ########.fr */ +/* Updated: 2020/02/09 23:57:20 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ t_bool parse_args(t_philo_args *philo_args, int argc, char **argv) return (TRUE); } -void philo_put_state_change(t_philo *philo, t_philo_event event) // not correct for philo3 +void philo_put_state_change(int id, t_philo_event event) // not correct for philo3 { struct timeval tv; @@ -42,7 +42,7 @@ void philo_put_state_change(t_philo *philo, t_philo_event event) // not corr h_putnbr(tv.tv_sec); h_putnbr(tv.tv_usec / 1000); h_putchar(' '); - h_putnbr(philo->id); + h_putnbr(id); if (event == EVENT_FORK) h_putstr(" has taken fork\n"); else if (event == EVENT_EATING) diff --git a/common/common.h b/common/common.h index ff371a9..def49cf 100644 --- a/common/common.h +++ b/common/common.h @@ -6,14 +6,16 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/08 22:58:35 by cacharle #+# #+# */ -/* Updated: 2020/02/09 03:22:56 by cacharle ### ########.fr */ +/* Updated: 2020/02/09 23:56:48 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef COMMON_H # define COMMON_H +# include # include +# include # include # define FALSE 0 @@ -38,13 +40,6 @@ typedef enum EVENT_DIED } t_philo_event; -typedef struct -{ - int id; - t_philo_state state; - pthread_t thread; -} t_philo; - typedef struct { int philo_num; @@ -56,30 +51,21 @@ typedef struct typedef void (*t_philo_routine)(void *arg); -typedef struct -{ - t_bool used; - t_philo *left; - t_philo *right; -} t_fork; - /* ** common.c */ t_bool parse_args(t_philo_args *philo_args, int argc, char **argv); -void philo_put_state_change(t_philo *philo, t_philo_event event); +void philo_put_state_change(int id, t_philo_event event); /* ** philo.c */ -t_philo *philos_new(int num); -void philos_destroy(t_philo *philo); - -void philo_eat(t_philo *philo); -void philo_sleep(t_philo *philo); -void philo_think(t_philo *philo); +void philo_eat(int id, int timeout); +void philo_sleep(int id, int timeout); +void philo_think(int id); +void philo_die(int id); /* ** helper.c @@ -92,5 +78,4 @@ void h_putchar(char c); void h_putstr(char *s); void *h_calloc(int count, int size); - #endif diff --git a/common/helper.c b/common/helper.c index 4c4b1f1..590c415 100644 --- a/common/helper.c +++ b/common/helper.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/08 23:22:49 by cacharle #+# #+# */ -/* Updated: 2020/02/09 02:15:02 by cacharle ### ########.fr */ +/* Updated: 2020/02/10 01:15:05 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/common/philo.c b/common/philo.c index b8d7caf..484257e 100644 --- a/common/philo.c +++ b/common/philo.c @@ -6,61 +6,32 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/09 01:54:53 by cacharle #+# #+# */ -/* Updated: 2020/02/09 03:26:07 by cacharle ### ########.fr */ +/* Updated: 2020/02/09 23:56:26 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "common.h" -t_philo *philos_new(int num, t_philo_routine routine) +void philo_eat(int id, int timeout) { - 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 = num + 1; - if (pthread_create(&philos[i].thread, NULL, routine, philos + num) != 0) - { - philos_destroy(philos, i); - return (NULL); - } - } - return (philos); + philo_put_state_change(id, EVENT_EATING); + usleep(timeout * 1000); } -void philos_destroy(t_philo *philo, int num) +void philo_sleep(int id, int timeout) { - if (philo == NULL) - return ; - while (num-- > 0) - pthread_join(philos[num].thread, NULL); - free(philos); + philo_put_state_change(id, EVENT_SLEEPING); + usleep(timeout * 1000); } -void philo_eat(t_philo *philo) +void philo_think(int id) { - // take forks - // lock mutex - philo_put_state_change(philo, EVENT_EATING); - usleep(philo->timeout_eat * 1000); - // drop forks - // unlock mutex + philo_put_state_change(id, EVENT_THINKING); } -void philo_sleep(t_philo *philo) +void philo_die(int id) { - philo_put_state_change(philo, EVENT_SLEEPING); - usleep(philo->timeout_sleep * 1000); + philo_put_state_change(id, EVENT_DIED); } -void philo_think(t_philo *philo) -{ - philo_put_state_change(philo, EVENT_THINKING); - // search a fork -} + 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