From 6bfcd3c6f921e7717e61167b291bb27bd3f66386 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Tue, 29 Sep 2020 14:56:27 +0200 Subject: Fixing taking none existing fork in logs --- philo_one/Makefile | 16 ++---- philo_one/args.c | 32 ------------ philo_one/forks.c | 60 ---------------------- philo_one/helper.c | 99 ------------------------------------- philo_one/io.c | 75 ---------------------------- philo_one/main.c | 46 ----------------- philo_one/philo.c | 61 ----------------------- philo_one/philo_one.h | 123 ---------------------------------------------- philo_one/routine.c | 55 --------------------- philo_one/src/args.c | 32 ++++++++++++ philo_one/src/forks.c | 60 ++++++++++++++++++++++ philo_one/src/helper.c | 99 +++++++++++++++++++++++++++++++++++++ philo_one/src/io.c | 81 ++++++++++++++++++++++++++++++ philo_one/src/main.c | 48 ++++++++++++++++++ philo_one/src/philo.c | 61 +++++++++++++++++++++++ philo_one/src/philo_one.h | 123 ++++++++++++++++++++++++++++++++++++++++++++++ philo_one/src/routine.c | 56 +++++++++++++++++++++ 17 files changed, 565 insertions(+), 562 deletions(-) delete mode 100644 philo_one/args.c delete mode 100644 philo_one/forks.c delete mode 100644 philo_one/helper.c delete mode 100644 philo_one/io.c delete mode 100644 philo_one/main.c delete mode 100644 philo_one/philo.c delete mode 100644 philo_one/philo_one.h delete mode 100644 philo_one/routine.c create mode 100644 philo_one/src/args.c create mode 100644 philo_one/src/forks.c create mode 100644 philo_one/src/helper.c create mode 100644 philo_one/src/io.c create mode 100644 philo_one/src/main.c create mode 100644 philo_one/src/philo.c create mode 100644 philo_one/src/philo_one.h create mode 100644 philo_one/src/routine.c (limited to 'philo_one') diff --git a/philo_one/Makefile b/philo_one/Makefile index de41214..da3f82e 100644 --- a/philo_one/Makefile +++ b/philo_one/Makefile @@ -6,7 +6,7 @@ # By: cacharle +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2019/11/24 05:50:15 by cacharle #+# #+# # -# Updated: 2020/09/28 14:12:28 by cacharle ### ########.fr # +# Updated: 2020/09/29 11:30:07 by cacharle ### ########.fr # # # # **************************************************************************** # @@ -18,17 +18,11 @@ LDFLAGS = -lpthread NAME = philo_one -SRC = main.c \ - philo.c \ - forks.c \ - routine.c \ - io.c \ - args.c \ - helper.c - +SRCDIR = src OBJDIR = obj -OBJ = $(SRC:%.c=$(OBJDIR)/%.o) +SRC = $(shell find $(SRCDIR) -type f -name '*.c') +OBJ = $(SRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o) all: prebuild $(NAME) @@ -38,7 +32,7 @@ prebuild: $(NAME): $(OBJ) $(CC) -o $@ $(OBJ) $(LDFLAGS) -$(OBJDIR)/%.o: %.c +$(OBJDIR)/%.o: $(SRCDIR)/%.c $(CC) $(CCFLAGS) -c -o $@ $< clean: diff --git a/philo_one/args.c b/philo_one/args.c deleted file mode 100644 index 9eb6da5..0000000 --- a/philo_one/args.c +++ /dev/null @@ -1,32 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* args.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/08 23:12:55 by cacharle #+# #+# */ -/* Updated: 2020/09/28 14:24:53 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -bool parse_args(t_philo_conf *philo_args, int argc, char **argv) -{ - if (argc != 5 && argc != 6) - return h_err(false, "Usage: %s philosophers_num death_timeout eat_timeout sleep_timeout", argv[0]); - if ((philo_args->philo_num = h_atou_strict(argv[1])) == -1 - || (philo_args->timeout_death = h_atou_strict(argv[2])) == -1 - || (philo_args->timeout_eat = h_atou_strict(argv[3])) == -1 - || (philo_args->timeout_sleep = h_atou_strict(argv[4])) == -1) - return (false); - if (argc == 6) - { - if ((philo_args->meal_num = h_atou_strict(argv[5])) == -1) - return (false); - } - else - philo_args->meal_num = 1; - return (true); -} diff --git a/philo_one/forks.c b/philo_one/forks.c deleted file mode 100644 index ebe5261..0000000 --- a/philo_one/forks.c +++ /dev/null @@ -1,60 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* forks.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/09 23:46:40 by cacharle #+# #+# */ -/* Updated: 2020/09/27 09:26:12 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -pthread_mutex_t *forks_new(int num) -{ - int i; - pthread_mutex_t *forks; - - if ((forks = malloc(num * sizeof(pthread_mutex_t))) == NULL) - return (NULL); - i = -1; - while (++i < num) - { - if (pthread_mutex_init(&forks[i], NULL) != 0) - { - forks_destroy(forks, i + 1); - return (NULL); - } - } - return (forks); -} - -void forks_destroy(pthread_mutex_t *forks, int num) -{ - while (num-- > 0) - pthread_mutex_destroy(&forks[num]); - free(forks); -} - -t_routine_arg *forks_dispatch( - t_philo *philos, - pthread_mutex_t *forks, - t_philo_conf *conf) -{ - int i; - t_routine_arg *routine_args; - - if ((routine_args = malloc(conf->philo_num * sizeof(t_routine_arg))) == NULL) - return (NULL); - i = -1; - while (++i < conf->philo_num) - { - routine_args[i].conf = conf; - routine_args[i].philo = philos + i; - routine_args[i].fork_left = forks + i % conf->philo_num; - routine_args[i].fork_right = forks + (i + 1) % conf->philo_num; - } - return (routine_args); -} diff --git a/philo_one/helper.c b/philo_one/helper.c deleted file mode 100644 index 1caec00..0000000 --- a/philo_one/helper.c +++ /dev/null @@ -1,99 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* helper.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/08 23:22:49 by cacharle #+# #+# */ -/* Updated: 2020/09/28 14:54:17 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -static int h_strlen(char *s) -{ - int counter; - - counter = 0; - while (s[counter]) - counter++; - return (counter); -} - -long int h_atou_strict(char *s) -{ - long int num; - char *origin; - - origin = s; - if (*s < '0' || *s > '9') - return (h_err(-1, "Error: %s: is not a number", origin)); - num = 0; - while (*s >= '0' && *s <= '9') - { - num *= 10; - if (num > UINT_MAX) - return (h_err(-1, "Error: %s: is too big", origin)); - num += *s - '0'; - if (num > UINT_MAX) - return (h_err(-1, "Error: %s: is too big", origin)); - s++; - } - if (*s != '\0') - return (h_err(-1, "Error: %s: is not a number", origin)); - return (num); -} - -void h_putnbr(unsigned long int num) -{ - if (num > 9) - h_putnbr(num / 10); - h_putchar(num % 10 + '0'); -} - -void h_putchar(char c) -{ - write(STDOUT_FILENO, &c, 1); -} - -void h_putstr(char *s) -{ - write(STDOUT_FILENO, s, h_strlen(s)); -} - -int h_err(int ret, const char *format, ...) -{ - char *str; - va_list ap; - - va_start(ap, format); - while (*format != '\0') - { - if (format[0] == '%' && format[1] == 's') - { - str = va_arg(ap, char*); - if (str != NULL) - write(STDERR_FILENO, str, h_strlen(str)); - format += 2; - } - else - { - write(STDERR_FILENO, format, 1); - format++; - } - } - va_end(ap); - write(STDERR_FILENO, "\n", 1); - return (ret); -} - -t_time h_time_now(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL) == -1) - return (-1); - return (tv.tv_sec * 1000 + tv.tv_usec / 1000); -} diff --git a/philo_one/io.c b/philo_one/io.c deleted file mode 100644 index c91e9ab..0000000 --- a/philo_one/io.c +++ /dev/null @@ -1,75 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* io.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/14 21:37:50 by cacharle #+# #+# */ -/* Updated: 2020/09/27 10:33:29 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -static void philo_put(int id, t_philo_event event) -{ - h_putnbr(h_time_now()); - h_putchar(' '); - h_putnbr(id); - if (event == EVENT_FORK) - h_putstr(" has taken fork\n"); - else if (event == EVENT_EAT) - h_putstr(" is eating\n"); - else if (event == EVENT_SLEEP) - h_putstr(" is sleeping\n"); - else if (event == EVENT_THINK) - h_putstr(" is thinking\n"); - else if (event == EVENT_DIE) - h_putstr(" died\n"); -} - -void io_eat(t_routine_arg *arg) -{ - int eat_counter; - - eat_counter = 0; - while (eat_counter < arg->conf->meal_num) - { - if (!arg->conf->all_alive) - return ; - pthread_mutex_lock(&arg->conf->mutex_stdout); - philo_put(arg->philo->id, EVENT_EAT); - pthread_mutex_unlock(&arg->conf->mutex_stdout); - usleep(arg->conf->timeout_eat * 1000); - eat_counter++; - } -} - -void io_think(t_routine_arg *arg) -{ - if (!arg->conf->all_alive) - return ; - pthread_mutex_lock(&arg->conf->mutex_stdout); - philo_put(arg->philo->id, EVENT_THINK); - pthread_mutex_unlock(&arg->conf->mutex_stdout); -} - -void io_sleep(t_routine_arg *arg) -{ - if (!arg->conf->all_alive) - return ; - pthread_mutex_lock(&arg->conf->mutex_stdout); - philo_put(arg->philo->id, EVENT_SLEEP); - pthread_mutex_unlock(&arg->conf->mutex_stdout); - usleep(arg->conf->timeout_sleep * 1000); -} - -void io_die(t_routine_arg *arg) -{ - if (!arg->conf->all_alive) - return ; - pthread_mutex_lock(&arg->conf->mutex_stdout); - philo_put(arg->philo->id, EVENT_DIE); - pthread_mutex_unlock(&arg->conf->mutex_stdout); -} diff --git a/philo_one/main.c b/philo_one/main.c deleted file mode 100644 index 83b5564..0000000 --- a/philo_one/main.c +++ /dev/null @@ -1,46 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* main.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/24 05:53:02 by cacharle #+# #+# */ -/* Updated: 2020/09/28 14:59:59 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -int main(int argc, char **argv) -{ - t_philo_conf philo_args; - t_philo *philos; - pthread_mutex_t *forks; - t_routine_arg *routine_args; - - if (!parse_args(&philo_args, argc, argv)) - return (1); - if (philo_args.philo_num < 2) - return (h_err(1, "Error: there should be at least 2 philosophers")); - if ((forks = forks_new(philo_args.philo_num)) == NULL) - return (1); - if ((philos = philos_new(philo_args.philo_num)) == NULL) - return (1); - if ((routine_args = forks_dispatch(philos, forks, &philo_args)) == NULL) - return (1); - philo_args.all_alive = true; - pthread_mutex_init(&philo_args.mutex_all_alive, NULL); - pthread_mutex_init(&philo_args.mutex_stdout, NULL); - if (!philos_start(philos, routine_args, philo_args.philo_num)) - return (1); - while (philo_args.all_alive) - ; - philos_join(philos, philo_args.philo_num); - pthread_mutex_destroy(&philo_args.mutex_stdout); - pthread_mutex_destroy(&philo_args.mutex_all_alive); - free(routine_args); - free(philos); - forks_destroy(forks, philo_args.philo_num); - return (0); -} diff --git a/philo_one/philo.c b/philo_one/philo.c deleted file mode 100644 index c32dc76..0000000 --- a/philo_one/philo.c +++ /dev/null @@ -1,61 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* philo.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/09 23:47:14 by cacharle #+# #+# */ -/* Updated: 2020/09/27 10:42:25 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -t_philo *philos_new(int num) -{ - int i; - t_philo *philos; - - if (num < 0) - return (NULL); - if ((philos = malloc(num * sizeof(t_philo))) == NULL) - return (NULL); - i = -1; - while (++i < num) - { - philos[i].id = i + 1; - philos[i].alive = false; - } - return (philos); -} - -bool philos_start(t_philo *philos, t_routine_arg *routine_args, int num) -{ - int i; - - i = -1; - while (++i < num) - { - philos[i].alive = true; - if (pthread_create(&philos[i].thread, NULL, - (void *(*)(void*))routine_philo, (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); - } - } -} diff --git a/philo_one/philo_one.h b/philo_one/philo_one.h deleted file mode 100644 index 0d6844c..0000000 --- a/philo_one/philo_one.h +++ /dev/null @@ -1,123 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* philo_one.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/24 06:11:16 by cacharle #+# #+# */ -/* Updated: 2020/09/28 14:22:57 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef PHILO_ONE_H -# define PHILO_ONE_H - -# include -# include -# include -# include -# include -# include -# include - -typedef long int t_time; - -typedef enum -{ - EVENT_FORK, - EVENT_EAT, - EVENT_SLEEP, - EVENT_THINK, - EVENT_DIE -} t_philo_event; - -typedef struct -{ - int philo_num; - t_time timeout_death; - t_time timeout_eat; - t_time timeout_sleep; - int meal_num; - bool all_alive; - pthread_mutex_t mutex_stdout; - pthread_mutex_t mutex_all_alive; -} t_philo_conf; - -typedef struct s_philo -{ - int id; - bool alive; - t_time time_last_eat; - pthread_t thread; -} t_philo; - -typedef struct s_routine_arg -{ - t_philo_conf *conf; - t_philo *philo; - pthread_mutex_t *fork_left; - pthread_mutex_t *fork_right; - pthread_mutex_t *mutex_stdout; -} t_routine_arg; - -/* -** forks.c -*/ - -pthread_mutex_t *forks_new(int num); -void forks_destroy(pthread_mutex_t *forks, int num); -t_routine_arg *forks_dispatch( - t_philo *philos, - pthread_mutex_t *forks, - t_philo_conf *conf); - -/* -** philo.c -*/ - -t_philo *philos_new(int num); -void philos_destroy(t_philo *philos, int num); -bool philos_start( - t_philo *philos, - t_routine_arg *routine_args, - int num); -void philos_join(t_philo *philos, int num); - -/* -** routine.c -*/ - -void *routine_philo(t_routine_arg *arg); -void *routine_death(t_routine_arg *arg); - -/* -** io.c -*/ - -void io_eat(t_routine_arg *arg); -void io_think(t_routine_arg *arg); -void io_sleep(t_routine_arg *arg); -void io_die(t_routine_arg *arg); - -/* -** common.c -*/ - -bool parse_args( - t_philo_conf *philo_args, - int argc, - char **argv); - -/* -** helper.c -*/ - -long int h_atou_strict(char *s); -void h_putnbr(unsigned long num); -void h_putchar(char c); -void h_putstr(char *s); -int h_err(int ret, const char *format, ...); -t_time h_time_now(void); - -#endif diff --git a/philo_one/routine.c b/philo_one/routine.c deleted file mode 100644 index d52fe2e..0000000 --- a/philo_one/routine.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* routine.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/10 01:11:27 by cacharle #+# #+# */ -/* Updated: 2020/09/27 10:25:56 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philo_one.h" - -void *routine_philo(t_routine_arg *arg) -{ - pthread_t thread_death; - - if (!arg->conf->all_alive) - return (NULL); - arg->philo->time_last_eat = h_time_now(); - if (pthread_create(&thread_death, NULL, (void *(*)(void*))routine_death, arg) != 0) - return (NULL); - io_think(arg); - while (arg->conf->all_alive) - { - pthread_mutex_lock(arg->fork_left); - pthread_mutex_lock(arg->fork_right); - arg->philo->time_last_eat = h_time_now(); - io_eat(arg); - pthread_mutex_unlock(arg->fork_right); - pthread_mutex_unlock(arg->fork_left); - io_sleep(arg); - io_think(arg); - } - pthread_join(thread_death, NULL); - return (NULL); -} - -void *routine_death(t_routine_arg *arg) -{ - t_time current; - - current = h_time_now(); - while (arg->conf->all_alive && - current - arg->philo->time_last_eat < arg->conf->timeout_death) - current = h_time_now(); - if (!arg->conf->all_alive) - return (NULL); - pthread_mutex_lock(&arg->conf->mutex_all_alive); - io_die(arg); - arg->conf->all_alive = false; - pthread_mutex_unlock(&arg->conf->mutex_all_alive); - return (NULL); -} diff --git a/philo_one/src/args.c b/philo_one/src/args.c new file mode 100644 index 0000000..b7277dd --- /dev/null +++ b/philo_one/src/args.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* args.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/08 23:12:55 by cacharle #+# #+# */ +/* Updated: 2020/09/29 11:08:06 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +bool parse_args(t_philo_conf *philo_args, int argc, char **argv) +{ + if (argc != 5 && argc != 6) + return h_err(false, "Usage: %s philosophers_num death_timeout eat_timeout sleep_timeout [meal_num]", argv[0]); + if ((philo_args->philo_num = h_atou_strict(argv[1])) == -1 + || (philo_args->timeout_death = h_atou_strict(argv[2])) == -1 + || (philo_args->timeout_eat = h_atou_strict(argv[3])) == -1 + || (philo_args->timeout_sleep = h_atou_strict(argv[4])) == -1) + return (false); + if (argc == 6) + { + if ((philo_args->meal_num = h_atou_strict(argv[5])) == -1) + return (false); + } + else + philo_args->meal_num = 1; + return (true); +} diff --git a/philo_one/src/forks.c b/philo_one/src/forks.c new file mode 100644 index 0000000..ebe5261 --- /dev/null +++ b/philo_one/src/forks.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* forks.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/09 23:46:40 by cacharle #+# #+# */ +/* Updated: 2020/09/27 09:26:12 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +pthread_mutex_t *forks_new(int num) +{ + int i; + pthread_mutex_t *forks; + + if ((forks = malloc(num * sizeof(pthread_mutex_t))) == NULL) + return (NULL); + i = -1; + while (++i < num) + { + if (pthread_mutex_init(&forks[i], NULL) != 0) + { + forks_destroy(forks, i + 1); + return (NULL); + } + } + return (forks); +} + +void forks_destroy(pthread_mutex_t *forks, int num) +{ + while (num-- > 0) + pthread_mutex_destroy(&forks[num]); + free(forks); +} + +t_routine_arg *forks_dispatch( + t_philo *philos, + pthread_mutex_t *forks, + t_philo_conf *conf) +{ + int i; + t_routine_arg *routine_args; + + if ((routine_args = malloc(conf->philo_num * sizeof(t_routine_arg))) == NULL) + return (NULL); + i = -1; + while (++i < conf->philo_num) + { + routine_args[i].conf = conf; + routine_args[i].philo = philos + i; + routine_args[i].fork_left = forks + i % conf->philo_num; + routine_args[i].fork_right = forks + (i + 1) % conf->philo_num; + } + return (routine_args); +} diff --git a/philo_one/src/helper.c b/philo_one/src/helper.c new file mode 100644 index 0000000..fa4c7ff --- /dev/null +++ b/philo_one/src/helper.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/08 23:22:49 by cacharle #+# #+# */ +/* Updated: 2020/09/29 14:15:50 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +static int h_strlen(char *s) +{ + int counter; + + counter = 0; + while (s[counter]) + counter++; + return (counter); +} + +long int h_atou_strict(char *s) +{ + long int num; + char *origin; + + origin = s; + if (*s < '0' || *s > '9') + return (h_err(-1, "Error: %s: is not a number", origin)); + num = 0; + while (*s >= '0' && *s <= '9') + { + num *= 10; + if (num > UINT_MAX) + return (h_err(-1, "Error: %s: is too big", origin)); + num += *s - '0'; + if (num > UINT_MAX) + return (h_err(-1, "Error: %s: is too big", origin)); + s++; + } + if (*s != '\0') + return (h_err(-1, "Error: %s: is not a number", origin)); + return (num); +} + +void h_putnbr(unsigned long int num) +{ + if (num > 9) + h_putnbr(num / 10); + h_putchar(num % 10 + '0'); +} + +void h_putchar(char c) +{ + write(STDOUT_FILENO, &c, 1); +} + +void h_putstr(char *s) +{ + write(STDOUT_FILENO, s, h_strlen(s)); +} + +int h_err(int ret, const char *format, ...) +{ + char *str; + va_list ap; + + va_start(ap, format); + while (*format != '\0') + { + if (format[0] == '%' && format[1] == 's') + { + str = va_arg(ap, char*); + if (str != NULL) + write(STDERR_FILENO, str, h_strlen(str)); + format += 2; + } + else + { + write(STDERR_FILENO, format, 1); + format++; + } + } + va_end(ap); + write(STDERR_FILENO, "\n", 1); + return (ret); +} + +t_time h_time_now(void) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + return (-1); + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} diff --git a/philo_one/src/io.c b/philo_one/src/io.c new file mode 100644 index 0000000..96a8f07 --- /dev/null +++ b/philo_one/src/io.c @@ -0,0 +1,81 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* io.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 21:37:50 by cacharle #+# #+# */ +/* Updated: 2020/09/29 14:55:21 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +static void philo_put(int id, t_philo_event event) +{ + h_putnbr(h_time_now()); + h_putchar(' '); + h_putnbr(id); + if (event == EVENT_FORK) + h_putstr(" has taken fork\n"); + else if (event == EVENT_EAT) + h_putstr(" is eating\n"); + else if (event == EVENT_SLEEP) + h_putstr(" is sleeping\n"); + else if (event == EVENT_THINK) + h_putstr(" is thinking\n"); + else if (event == EVENT_DIE) + h_putstr(" died\n"); +} + +void io_eat(t_routine_arg *arg) +{ + int eat_counter; + + eat_counter = 0; + while (eat_counter < arg->conf->meal_num) + { + pthread_mutex_lock(&arg->conf->mutex_all_alive); + if (!arg->conf->all_alive) + return ; + pthread_mutex_lock(&arg->conf->mutex_stdout); + philo_put(arg->philo->id, EVENT_EAT); + pthread_mutex_unlock(&arg->conf->mutex_stdout); + pthread_mutex_unlock(&arg->conf->mutex_all_alive); + usleep(arg->conf->timeout_eat * 1000); + eat_counter++; + } +} + +void io_think(t_routine_arg *arg) +{ + pthread_mutex_lock(&arg->conf->mutex_all_alive); + if (!arg->conf->all_alive) + return ; + pthread_mutex_lock(&arg->conf->mutex_stdout); + philo_put(arg->philo->id, EVENT_THINK); + pthread_mutex_unlock(&arg->conf->mutex_stdout); + pthread_mutex_unlock(&arg->conf->mutex_all_alive); +} + +void io_sleep(t_routine_arg *arg) +{ + pthread_mutex_lock(&arg->conf->mutex_all_alive); + if (!arg->conf->all_alive) + return ; + pthread_mutex_lock(&arg->conf->mutex_stdout); + philo_put(arg->philo->id, EVENT_SLEEP); + pthread_mutex_unlock(&arg->conf->mutex_stdout); + pthread_mutex_unlock(&arg->conf->mutex_all_alive); + /* usleep(arg->conf->timeout_sleep * 1000); */ +} + +void io_die(t_routine_arg *arg) +{ + if (!arg->conf->all_alive) + return ; + pthread_mutex_lock(&arg->conf->mutex_stdout); + philo_put(arg->philo->id, EVENT_DIE); + pthread_mutex_unlock(&arg->conf->mutex_stdout); +} diff --git a/philo_one/src/main.c b/philo_one/src/main.c new file mode 100644 index 0000000..511fdbe --- /dev/null +++ b/philo_one/src/main.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/24 05:53:02 by cacharle #+# #+# */ +/* Updated: 2020/09/29 13:26:07 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +int main(int argc, char **argv) +{ + t_philo_conf philo_args; + t_philo *philos; + pthread_mutex_t *forks; + t_routine_arg *routine_args; + + if (!parse_args(&philo_args, argc, argv)) + return (1); + if (philo_args.philo_num == 0) + return (0); + if ((forks = forks_new(philo_args.philo_num)) == NULL) + return (1); + if ((philos = philos_new(philo_args.philo_num)) == NULL) + return (1); + if ((routine_args = forks_dispatch(philos, forks, &philo_args)) == NULL) + return (1); + philo_args.all_alive = true; + pthread_mutex_init(&philo_args.mutex_all_alive, NULL); + pthread_mutex_init(&philo_args.mutex_stdout, NULL); + if (!philos_start(philos, routine_args, philo_args.philo_num)) + return (1); + /* pthread_mutex_lock(philo_args.mutex_all_alive); */ + /* pthread_mutex_lock(philo_args.mutex_all_alive); */ + while (philo_args.all_alive) + ; + philos_join(philos, philo_args.philo_num); + pthread_mutex_destroy(&philo_args.mutex_stdout); + pthread_mutex_destroy(&philo_args.mutex_all_alive); + free(routine_args); + free(philos); + forks_destroy(forks, philo_args.philo_num); + return (0); +} diff --git a/philo_one/src/philo.c b/philo_one/src/philo.c new file mode 100644 index 0000000..e0ecfec --- /dev/null +++ b/philo_one/src/philo.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* philo.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/09 23:47:14 by cacharle #+# #+# */ +/* Updated: 2020/09/29 13:29:49 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 = malloc(num * sizeof(t_philo))) == NULL) + return (NULL); + i = -1; + while (++i < num) + { + philos[i].id = i + 1; + philos[i].alive = false; + } + return (philos); +} + +bool philos_start(t_philo *philos, t_routine_arg *routine_args, int num) +{ + int i; + + i = -1; + while (++i < num) + { + philos[i].alive = true; + if (pthread_create(&philos[i].thread, NULL, + (void *(*)(void*))routine_philo, (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_detach(philos[i].thread); + } + } +} diff --git a/philo_one/src/philo_one.h b/philo_one/src/philo_one.h new file mode 100644 index 0000000..e92fdcd --- /dev/null +++ b/philo_one/src/philo_one.h @@ -0,0 +1,123 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* philo_one.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/24 06:11:16 by cacharle #+# #+# */ +/* Updated: 2020/09/29 14:15:47 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PHILO_ONE_H +# define PHILO_ONE_H + +# include +# include +# include +# include +# include +# include +# include + +typedef long int t_time; + +typedef enum +{ + EVENT_FORK, + EVENT_EAT, + EVENT_SLEEP, + EVENT_THINK, + EVENT_DIE +} t_philo_event; + +typedef struct +{ + int philo_num; + t_time timeout_death; + t_time timeout_eat; + t_time timeout_sleep; + int meal_num; + bool all_alive; + pthread_mutex_t mutex_stdout; + pthread_mutex_t mutex_all_alive; +} t_philo_conf; + +typedef struct s_philo +{ + int id; + bool alive; + t_time time_last_eat; + pthread_t thread; +} t_philo; + +typedef struct s_routine_arg +{ + t_philo_conf *conf; + t_philo *philo; + pthread_mutex_t *fork_left; + pthread_mutex_t *fork_right; + pthread_mutex_t *mutex_stdout; +} t_routine_arg; + +/* +** forks.c +*/ + +pthread_mutex_t *forks_new(int num); +void forks_destroy(pthread_mutex_t *forks, int num); +t_routine_arg *forks_dispatch( + t_philo *philos, + pthread_mutex_t *forks, + t_philo_conf *conf); + +/* +** philo.c +*/ + +t_philo *philos_new(int num); +void philos_destroy(t_philo *philos, int num); +bool philos_start( + t_philo *philos, + t_routine_arg *routine_args, + int num); +void philos_join(t_philo *philos, int num); + +/* +** routine.c +*/ + +void *routine_philo(t_routine_arg *arg); +void *routine_death(t_routine_arg *arg); + +/* +** io.c +*/ + +void io_eat(t_routine_arg *arg); +void io_think(t_routine_arg *arg); +void io_sleep(t_routine_arg *arg); +void io_die(t_routine_arg *arg); + +/* +** common.c +*/ + +bool parse_args( + t_philo_conf *philo_args, + int argc, + char **argv); + +/* +** helper.c +*/ + +long int h_atou_strict(char *s); +void h_putnbr(unsigned long num); +void h_putchar(char c); +void h_putstr(char *s); +int h_err(int ret, const char *format, ...); +t_time h_time_now(void); + +#endif diff --git a/philo_one/src/routine.c b/philo_one/src/routine.c new file mode 100644 index 0000000..0115e91 --- /dev/null +++ b/philo_one/src/routine.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* routine.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/10 01:11:27 by cacharle #+# #+# */ +/* Updated: 2020/09/29 14:30:06 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo_one.h" + +void *routine_philo(t_routine_arg *arg) +{ + pthread_t thread_death; + + if (!arg->conf->all_alive) + return (NULL); + arg->philo->time_last_eat = h_time_now(); + if (pthread_create(&thread_death, NULL, (void *(*)(void*))routine_death, arg) != 0) + return (NULL); + io_think(arg); + while (arg->conf->all_alive) + { + pthread_mutex_lock(arg->fork_left); + pthread_mutex_lock(arg->fork_right); + arg->philo->time_last_eat = h_time_now(); + io_eat(arg); + io_sleep(arg); + pthread_mutex_unlock(arg->fork_right); + pthread_mutex_unlock(arg->fork_left); + usleep(arg->conf->timeout_sleep * 1000); + io_think(arg); + } + pthread_join(thread_death, NULL); + return (NULL); +} + +void *routine_death(t_routine_arg *arg) +{ + t_time current; + + current = h_time_now(); + while (arg->conf->all_alive && + current - arg->philo->time_last_eat < arg->conf->timeout_death) + current = h_time_now(); + if (!arg->conf->all_alive) + return (NULL); + pthread_mutex_lock(&arg->conf->mutex_all_alive); + io_die(arg); + arg->conf->all_alive = false; + pthread_mutex_unlock(&arg->conf->mutex_all_alive); + return (NULL); +} -- cgit