From 08f5d8dab99cd8a4c020e2459aa5dc024e957acc Mon Sep 17 00:00:00 2001 From: narnaud Date: Wed, 18 May 2022 16:48:06 +0200 Subject: [PATCH] rework --- philo/Makefile | 8 +-- philo/philo_init.c | 58 ------------------ philo/philo_launcher.c | 123 ++++++++++++++++++++++++++++---------- philo/philo_threads.c | 132 ++++++++++++++++++++++++++++++++++------- philo/philo_utils.c | 90 ---------------------------- philo/philosophers.h | 38 +++++------- 6 files changed, 220 insertions(+), 229 deletions(-) delete mode 100644 philo/philo_init.c delete mode 100644 philo/philo_utils.c diff --git a/philo/Makefile b/philo/Makefile index 990ed2d..8c55587 100644 --- a/philo/Makefile +++ b/philo/Makefile @@ -1,10 +1,10 @@ NAME = philosophers -SRCS = philo_threads.c philo_launcher.c philo_utils.c philo_init.c +SRCS = philo_threads.c philo_launcher.c OBJS = ${SRCS:.c=.o} -CC = gcc -CFLAGS = -Werror -Wextra -Wall -g -fsanitize=thread -D_REENTRANT +CC = clang +CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT RM = rm -rf .c.o: @@ -13,7 +13,7 @@ RM = rm -rf all: $(NAME) $(NAME): $(OBJS) - ${CC} ${CFLAGS} -lpthread ${OBJS} -o ${NAME} + ${CC} ${CFLAGS} -g -fsanitize=thread -lpthread ${OBJS} -o ${NAME} clean: ${RM} ${OBJS} diff --git a/philo/philo_init.c b/philo/philo_init.c deleted file mode 100644 index c8c7744..0000000 --- a/philo/philo_init.c +++ /dev/null @@ -1,58 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* philo_init.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: narnaud +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/04/11 10:33:01 by narnaud #+# #+# */ -/* Updated: 2022/05/16 18:07:56 by narnaud ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philosophers.h" - -t_param *init_param(char **argv) -{ - t_param *ret; - - ret = malloc(sizeof(t_param)); - ret->philo_amount = mini_atoi(argv[0]); - ret->die_time = mini_atoi(argv[1]); - ret->eat_duration = mini_atoi(argv[2]); - ret->sleep_duration = mini_atoi(argv[3]); - if (argv[4]) - ret->eat_amount = mini_atoi(argv[4]); - else - ret->eat_amount = 2147483647; - return (ret); -} - -t_room *init_room(char **argv) -{ - t_room *room; - static int i = 0; - - room = malloc(sizeof(t_room)); - room->param = init_param(argv); - room->safe = malloc(sizeof(pthread_mutex_t)); - pthread_mutex_init(room->safe, NULL); - room->philos = \ - (t_philo **)malloc(room->param->philo_amount * sizeof(t_philo *)); - room->running = 1; - room->i = 0; - while (i < room->param->philo_amount) - { - room->philos[i] = (t_philo *)malloc(sizeof(t_philo)); - room->philos[i]->fork = malloc(sizeof(pthread_mutex_t)); - room->philos[i]->safe = malloc(sizeof(pthread_mutex_t)); - room->philos[i]->thd = malloc(sizeof(pthread_t)); - room->philos[i]->eat_time = gettime(); - room->philos[i]->eat_amount = 0; - room->philos[i]->i = i; - pthread_mutex_init(room->philos[i]->fork, NULL); - pthread_mutex_init(room->philos[i++]->safe, NULL); - } - return (room); -} - diff --git a/philo/philo_launcher.c b/philo/philo_launcher.c index 00a8f35..da77796 100644 --- a/philo/philo_launcher.c +++ b/philo/philo_launcher.c @@ -6,13 +6,16 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/24 15:44:04 by narnaud #+# #+# */ -/* Updated: 2022/05/16 18:04:42 by narnaud ### ########.fr */ +/* Updated: 2022/05/16 22:42:20 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "philosophers.h" -int waiter(t_room *room); +void init_param(t_room *room, char **argv); +static t_room *init_room(char **argv); +static int clean_memory(t_room *room); +static int mini_atoi(char *str); int main(int argc, char **argv) { @@ -23,52 +26,108 @@ int main(int argc, char **argv) room = init_room(argv + 1); while (room->i >= 0) { - pthread_mutex_lock(room->safe); - if (room->i >= room->param->philo_amount) - room->i -= 1 + (room->param->philo_amount % 2) * 2; pthread_create(room->philos[room->i]->thd, NULL, \ philos_life, (void *)room); pthread_detach(*room->philos[room->i]->thd); - pthread_mutex_unlock(room->safe); - usleep(CLOCK_ONE); - pthread_mutex_lock(room->safe); + usleep(50); + pthread_mutex_lock(room->lock); if ((room->i % 2) == 0) + { room->i += 2; + if (room->i >= room->param[PHILO_AMOUNT]) + room->i -= 1 + (room->param[PHILO_AMOUNT] % 2) * 2; + } else if ((room->i % 2) == 1) room->i -= 2; - pthread_mutex_unlock(room->safe); + pthread_mutex_unlock(room->lock); } - while (!waiter(room)) + while (waiter(room)) usleep(CLOCK_TWO); + pthread_mutex_lock(room->lock); + room->running = 0; return (clean_memory(room)); } -int waiter(t_room *room) +void init_param(t_room *room, char **argv) +{ + room->param[PHILO_AMOUNT] = mini_atoi(argv[0]); + room->param[DIE_TIME] = mini_atoi(argv[1]); + room->param[EAT_DURATION] = mini_atoi(argv[2]); + room->param[SLEEP_DURATION] = mini_atoi(argv[3]); + if (argv[4]) + room->param[MEALS_AMOUNT] = mini_atoi(argv[4]); + else + room->param[MEALS_AMOUNT] = 2147483647; +} + +static t_room *init_room(char **argv) +{ + t_room *room; + static int i = 0; + + room = malloc(sizeof(t_room)); + init_param(room, argv); + room->lock = malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(room->lock, NULL); + room->philos = \ + (t_philo **)malloc(room->param[PHILO_AMOUNT] * sizeof(t_philo *)); + room->running = 1; + room->i = 0; + while (i < room->param[PHILO_AMOUNT]) + { + room->philos[i] = (t_philo *)malloc(sizeof(t_philo)); + room->philos[i]->fork = malloc(sizeof(pthread_mutex_t)); + room->philos[i]->lock = malloc(sizeof(pthread_mutex_t)); + room->philos[i]->thd = malloc(sizeof(pthread_t)); + room->philos[i]->eat_time = room_clock(); + room->philos[i]->eat_amount = 0; + room->philos[i]->i = i; + pthread_mutex_init(room->philos[i]->fork, NULL); + pthread_mutex_init(room->philos[i++]->lock, NULL); + } + return (room); +} + +static int clean_memory(t_room *room) { - t_param *param; - int i; - int starvest; + int *param; + static int i = 0; - pthread_mutex_lock(room->safe); - i = 0; param = room->param; - starvest = param->eat_amount; - while (i < param->philo_amount) + sleep(1); + while (i < param[PHILO_AMOUNT]) { - pthread_mutex_lock(room->philos[i]->safe); - if (room->philos[i]->eat_time + param->die_time < gettime()) - { - safe_print("%ld %d died\n", room, i); - room->running = 0; - return (1); - } - if (room->philos[i]->eat_amount < starvest) - starvest = room->philos[i]->eat_amount; - pthread_mutex_unlock(room->philos[i]->safe); + + pthread_mutex_lock(room->philos[i]->lock); + pthread_mutex_unlock(room->philos[i]->lock); + pthread_mutex_destroy(room->philos[i]->lock); + pthread_mutex_lock(room->philos[i]->fork); + pthread_mutex_unlock(room->philos[i]->fork); + pthread_mutex_destroy(room->philos[i]->fork); + free(room->philos[i]->lock); + free(room->philos[i]->fork); + free(room->philos[i]->thd); + free(room->philos[i]); i++; } - if (starvest == param->eat_amount) - room->running = 0; - pthread_mutex_unlock(room->safe); - return (!room->running); + + pthread_mutex_unlock(room->lock); + pthread_mutex_destroy(room->lock); + free(room->lock); + free(room->philos); + free(room); + return (0); +} + +int mini_atoi(char *nbr) +{ + int ret; + + ret = 0; + while (*nbr >= '0' && *nbr <= '9') + { + ret = (*nbr - '0') + (10 * ret); + nbr++; + } +return (ret); } diff --git a/philo/philo_threads.c b/philo/philo_threads.c index e4267b2..0cbb128 100644 --- a/philo/philo_threads.c +++ b/philo/philo_threads.c @@ -6,49 +6,139 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/26 07:43:48 by narnaud #+# #+# */ -/* Updated: 2022/05/16 17:51:21 by narnaud ### ########.fr */ +/* Updated: 2022/05/16 22:28:37 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "philosophers.h" +static int safe_print(char *str, t_room *room, int id) +{ + int ret; + if (!room->running) + return (0); + pthread_mutex_lock(room->lock); + printf(str, room_clock(), id); + ret = room->running; + pthread_mutex_unlock(room->lock); + return (ret); +} + +int safe_wait(t_room *room, int start, int duration) +{ + int ret; + + ret = room->running; + while (ret && (room_clock() < (start + duration))) + { + pthread_mutex_lock(room->lock); + ret = room->running; + pthread_mutex_unlock(room->lock); + usleep(50); + } + return (ret); +} + + +int waiter(t_room *room) +{ + int *param; + int i; + int starvest; + t_philo *philo; + int ret; + + ret = 1; + pthread_mutex_lock(room->lock); + i = 0; + param = room->param; + starvest = param[MEALS_AMOUNT]; + while (ret && i < param[PHILO_AMOUNT]) + { + philo = room->philos[i]; + pthread_mutex_lock(philo->lock); + if (philo->eat_time + param[DIE_TIME] < room_clock()) + { + printf("%d %d died\n", room_clock(), i); + ret = 0; + } + if (philo->eat_amount < starvest) + starvest = philo->eat_amount; + pthread_mutex_unlock(philo->lock); + i++; + } + pthread_mutex_unlock(room->lock); + if (starvest == param[MEALS_AMOUNT]) + ret = 0; + return (ret); +} + void *philos_life(void *r) { t_room *room; - t_param *param; + int *param; t_philo *philo; int id; int id_p; room = (t_room *)r; param = room->param; - pthread_mutex_lock(room->safe); + pthread_mutex_lock(room->lock); id = room->i; + printf("Philo %d: \n", id); philo = room->philos[id]; - philo->eat_time = gettime(); - id_p = (id + 1) % param->philo_amount; - while (room->running) + philo->eat_time = room_clock(); + id_p = (id + 1) % param[PHILO_AMOUNT]; + pthread_mutex_unlock(room->lock); + while (1) { - pthread_mutex_unlock(room->safe); pthread_mutex_lock(philo->fork); - safe_print("%ld %d has taken a fork\n", room, id); + if (!safe_print("%d %d has taken a fork\n", room, id)) + { + pthread_mutex_unlock(philo->fork); + break ; + } pthread_mutex_lock(room->philos[id_p]->fork); - safe_print("%ld %d has taken a fork\n", room, id); - safe_print("%ld %d is eating\n", room, id); - if (!safe_wait(room, gettime(), param->eat_duration * 1000)) - return (NULL); + safe_print("%d %d has taken a fork\n", room, id); + if(!safe_print("%d %d is eating\n", room, id)) + { + pthread_mutex_unlock(philo->fork); + pthread_mutex_unlock(room->philos[id_p]->fork); + break; + } + pthread_mutex_lock(philo->lock); + philo->eat_time = room_clock(); + pthread_mutex_unlock(philo->lock); + if (!safe_wait(room, room_clock(), param[EAT_DURATION])) + { pthread_mutex_unlock(philo->fork); pthread_mutex_unlock(room->philos[id_p]->fork); - pthread_mutex_lock(philo->safe); - philo->eat_time = gettime(); + break; + } + pthread_mutex_unlock(philo->fork); + pthread_mutex_unlock(room->philos[id_p]->fork); + if(!safe_print("%d %d is sleeping\n", room, id)) + break ; + pthread_mutex_lock(philo->lock); philo->eat_amount++; - pthread_mutex_unlock(philo->safe); - safe_print("%ld %d is sleeping\n", room, id); - if (!safe_wait(room, gettime(), param->sleep_duration * 1000)) - return (NULL); - safe_print("%ld %d is thinking\n", room, id); - pthread_mutex_lock(room->safe); + pthread_mutex_unlock(philo->lock); + if (!safe_wait(room, room_clock(), param[SLEEP_DURATION])) + break ; + if (!safe_print("%d %d is thinking\n", room, id)) + break ; } - pthread_mutex_unlock(room->safe); return (NULL); } + +int room_clock() +{ + struct timeval time; + int ret; + static long int start_time = 0; + + gettimeofday(&time, NULL); + if (!start_time) + start_time = time.tv_sec * 1000 + time.tv_usec / 1000; + ret = (int)(time.tv_sec * 1000 + time.tv_usec / 1000 - start_time); + return (ret); +} diff --git a/philo/philo_utils.c b/philo/philo_utils.c deleted file mode 100644 index 3d1a83d..0000000 --- a/philo/philo_utils.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* philo_utils.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: narnaud +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/04/11 10:29:50 by narnaud #+# #+# */ -/* Updated: 2022/05/16 18:03:12 by narnaud ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philosophers.h" - - -int mini_atoi(char *nbr) -{ - int ret; - - ret = 0; - while (*nbr >= '0' && *nbr <= '9') - { - ret = (*nbr - '0') + (10 * ret); - nbr++; - } -return (ret); -} - -size_t gettime(void) -{ - static struct timeval start = {0,0}; - struct timeval actualtime; - size_t ret; - - if(start.tv_sec == 0 && start.tv_usec == 0) - gettimeofday(&start, NULL); - gettimeofday(&actualtime, NULL); - ret = (size_t)((actualtime.tv_sec * 1000 + actualtime.tv_usec / 1000)\ - - (start.tv_sec * 1000 + start.tv_usec / 1000)); - return (ret); -} - -void safe_print(char *str, t_room *room, int id) -{ - pthread_mutex_lock(room->safe); - printf(str, gettime(), id); - pthread_mutex_unlock(room->safe); -} - -int safe_wait(t_room *room, size_t start, size_t duration) -{ - int ret; - - ret = 1; - while (ret && (gettime() < start + duration)) - { - pthread_mutex_lock(room->safe); - if (!room->running) - ret = 0; - pthread_mutex_unlock(room->safe); - usleep(5000); - } - return (ret); -} - -int clean_memory(t_room *room) -{ - t_param *param; - int i; - - i = 0; - param = room->param; - while (i < param->philo_amount) - { - pthread_mutex_destroy(room->philos[i]->safe); - pthread_mutex_destroy(room->philos[i]->fork); - free(room->philos[i]->safe); - free(room->philos[i]->fork); - free(room->philos[i]->thd); - free(room->philos[i]); - i++; - } - pthread_mutex_destroy(room->safe); - free(room->safe); - free(room->philos); - free(room->param); - free(room); - return (0); -} - diff --git a/philo/philosophers.h b/philo/philosophers.h index 127e4d1..3350b55 100644 --- a/philo/philosophers.h +++ b/philo/philosophers.h @@ -6,7 +6,7 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/24 15:44:06 by narnaud #+# #+# */ -/* Updated: 2022/05/16 18:06:07 by narnaud ### ########.fr */ +/* Updated: 2022/03/31 12:37:23 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,46 +22,36 @@ # include # include -typedef struct s_param +enum e_params { - int philo_amount; - int die_time; - int eat_duration; - int sleep_duration; - int eat_amount; -} t_param; + PHILO_AMOUNT, + DIE_TIME, + EAT_DURATION, + SLEEP_DURATION, + MEALS_AMOUNT, +}; typedef struct s_philo { pthread_mutex_t *fork; - pthread_mutex_t *safe; + pthread_mutex_t *lock; pthread_t *thd; - size_t eat_time; + int eat_time; int eat_amount; int i; } t_philo; typedef struct s_room { - t_param *param; + int param[5]; t_philo **philos; - pthread_mutex_t *safe; + pthread_mutex_t *lock; int running; int i; } t_room; -//philo_threads.c +int waiter(t_room *room); void *philos_life(void *r); - -//philo_init.c -t_param *init_param(char **argv); -t_room *init_room(char **argv); - -//philo_utils.c -int mini_atoi(char *nbr); -void safe_print(char *str, t_room *room, int id); -int clean_memory(t_room *room); -int safe_wait(t_room *room, size_t start, size_t duration); -size_t gettime(void); +int room_clock(); #endif