diff --git a/Makefile b/Makefile index cd26c80..3fcc826 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,16 @@ # By: apommier +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2022/02/13 16:27:49 by apommier #+# #+# # -# Updated: 2022/03/05 18:52:44 by apommier ### ########.fr # +# Updated: 2022/03/15 17:49:12 by apommier ### ########.fr # # # # **************************************************************************** # NAME = philo -SRCS = main.c\ - utils.c +SRCS = srcs/main.c\ + srcs/init.c\ + srcs/exit.c\ + srcs/philo.c\ + srcs/utils.c OBJS = ${SRCS:.c=.o} CC = gcc CFLAGS = -pthread -Wall -Wextra -Werror diff --git a/main.c b/main.c deleted file mode 100644 index 2182102..0000000 --- a/main.c +++ /dev/null @@ -1,258 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* main.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: apommier +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/02/20 19:10:43 by apommier #+# #+# */ -/* Updated: 2022/02/20 19:10:43 by apommier ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "philosophers.h" - -t_arg *create_data(int argc, char **argv) -{ - t_arg *data; - - usleep(1500000); - data = malloc(sizeof(t_arg)); - *data->death = 1; - data->nb_full_philo = 0; - data->nb_philo = ft_atoi(argv[1]); - data->time_to_die = ft_atoi(argv[2]); - data->time_to_eat = ft_atoi(argv[3]); - data->time_to_sleep = ft_atoi(argv[4]); - data->must_eat = 0; - if (argc == 6) - data->must_eat = ft_atoi(argv[5]); - else - data->must_eat = -1; - return (data); -} - -void exit_philo(t_philo *philo, t_arg *data) -{ - int i; - - i = 0; - printf("exit philo\n"); - while (i < data->nb_philo - 1) - { - pthread_mutex_destroy(philo[i].left_fork); - free(philo[i].left_fork); - i++; - } - pthread_mutex_destroy(philo[i].left_fork); - free(philo[i].left_fork); - pthread_mutex_destroy(philo[i].display); - free(philo[i].display); - free(philo); - free(data); - exit(1); -} - -void put_event(t_philo philo, char *event) -{ - pthread_mutex_lock(philo.display); - if (*philo.data->death) - printf("%ldms Philo N°%d %s\n", get_time() - philo.data->time_start, philo.philo_id, event); - pthread_mutex_unlock(philo.display); -} - -void philo_take_fork(t_philo philo) -{ - //printf("philo %d FORKED\n", philo.philo_id); - if (*philo.data->death) - pthread_mutex_lock(philo.left_fork); - if (*philo.data->death) - put_event(philo, "has taken a fork"); - if (*philo.data->death) - pthread_mutex_lock(philo.right_fork); - if (*philo.data->death) - put_event(philo, "has taken a fork"); - //printf("philo %d done FORKED\n", philo.philo_id); -} - -void philo_eat(t_philo *philo_tmp) -{ - t_philo philo; - - philo = *philo_tmp; - if (*philo.data->death) - philo_take_fork(philo); - *philo_tmp->last_eat = get_time(); - if (*philo.data->death) - put_event(philo, "is eating"); - usleep(philo.data->time_to_eat * 1000); - pthread_mutex_unlock(philo.left_fork); - pthread_mutex_unlock(philo.right_fork); - if (*philo.data->death) - put_event(philo, "is sleeping"); - usleep(philo.data->time_to_sleep * 1000); - if (*philo.data->death) - put_event(philo, "is thinking"); -} - -int death_checker(t_philo *philo, t_arg *data) -{ - int i; - - i = 0; - while (*data->death) - { - i = -1; - while (i++ < data->nb_philo - 1 && *data->death && *philo[i].last_eat) - { - if ((get_time() - *philo[i].last_eat) > data->time_to_die && philo[i].must_eat) - { - *philo[i].data->death = 0; - usleep(10000); - pthread_mutex_lock(philo->display); - printf("%ldms Philo N°%d is died\n", - get_time() - data->time_start, philo[i].philo_id); - printf("End: one philo died\n"); - pthread_mutex_unlock(philo->display); - printf("time_to_die: %d TIME: %ld start: %ld philo.start: %ld last_eat: %ld condition: %ld\n", data->time_to_die ,get_time(), data->time_start , philo[i].data->time_start, get_time() - *philo[i].last_eat ,get_time() - *philo[i].last_eat); - return (1); - } - else if (data->nb_full_philo == data->nb_philo) - { - pthread_mutex_lock(philo->display); - printf("End: all philo are full\n"); - return (1); - } - } - } - return (0); -} - -void *routine(void *tmp) -{ - t_philo *philo; - - philo = (t_philo *)tmp; - *philo->last_eat = get_time(); - if (philo->philo_id % 2) - usleep(15000); - while (*philo->data->death && philo->must_eat - && philo->data->nb_full_philo != philo->data->nb_philo) - { - printf("philo %d start_eat\n", philo->philo_id); - philo_eat(philo); - printf("Philo %d end_eat\n", philo->philo_id); - philo->must_eat--; - if (!philo->must_eat) - philo->data->nb_full_philo++; - } - printf("philo %d rutine end\n", philo->philo_id); - //printf("n%d before end routine\n", philo->philo_id); - return (0); -} - -t_philo *create_philo(t_arg *data) -{ - int i; - t_philo *philo; - pthread_mutex_t *display; - - i = 0; - philo = malloc(sizeof(t_philo) * data->nb_philo); - if (!philo) - return (0); - display = malloc(sizeof(pthread_mutex_t)); - if (!display) - return (0); - pthread_mutex_init(display, 0); - while (i < data->nb_philo) - { - *philo[i].last_eat = 0; - philo[i].display = display; - philo[i].philo_id = i + 1; - philo[i].data = data; - philo[i].must_eat = data->must_eat; - philo[i].left_fork = malloc(sizeof(pthread_mutex_t)); - pthread_mutex_init(philo[i].left_fork, 0); - i++; - } - i = 0; - while (i < data->nb_philo) - { - philo[i].right_fork = philo[(i + 1) % data->nb_philo].left_fork; - i++; - } - return (philo); -} - -int start_philo(t_philo *philo, t_arg *data) -{ - int i; - - i = 0; - data->time_start = get_time(); - while (i < data->nb_philo) - { - pthread_create(&philo[i].thread, 0, &routine, &philo[i]); - usleep(10); - i++; - } - death_checker(philo, data); - printf("after d_checker\n"); - i = 0; - while (i < data->nb_philo) - { - printf("i = %d philo %d\n", i, philo[i].philo_id); - pthread_join(philo[i++].thread, 0); - } - printf("after join\n"); - exit_philo(philo, data); - return (0); -} - -int check_arg(int argc, char **argv) -{ - int i; - int j; - - j= 0; - i = 1; - if (argc != 5 && argc != 6) - return (1); - while (argv[i]) - { - j = 0; - while (argv[i][j]) - { - if (argv[i][j] > '9' || argv[i][j] < '0') - return (1); - j++; - } - i++; - } - return (0); -} - -int main(int argc, char **argv) -{ - t_arg *data; - t_philo *philo; - - if (check_arg(argc, argv)) - { - printf("Bad arguments\n"); - return (0); - } - data = create_data(argc, argv); - philo = create_philo(data); - start_philo(philo, data); - return (0); -} - - - - //put_event(*philo, "starting"); - //if ( philo->philo_id == 3) - // *philo->data->test = 0; - //printf("je suis le numero %d\n", philo->philo_id); - //printf("test = %d\n", *philo->data->test); \ No newline at end of file diff --git a/srcs/exit.c b/srcs/exit.c new file mode 100644 index 0000000..065c5a2 --- /dev/null +++ b/srcs/exit.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/03/15 17:40:53 by apommier #+# #+# */ +/* Updated: 2022/03/17 00:22:47 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philosophers.h" + +void exit_philo(t_philo *philo, t_arg *data) +{ + int i; + + i = 0; + printf("exit philo\n"); + usleep(100000); + while (i < data->nb_philo - 1) + { + pthread_mutex_destroy(philo[i].left_fork); + free(philo[i].left_fork); + i++; + } + pthread_mutex_destroy(philo[i].left_fork); + free(philo[i].left_fork); + pthread_mutex_destroy(data->display); + free(data->display); + free(philo); + free(data); + exit(1); +} diff --git a/srcs/init.c b/srcs/init.c new file mode 100644 index 0000000..c20a1a4 --- /dev/null +++ b/srcs/init.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/03/15 17:38:58 by apommier #+# #+# */ +/* Updated: 2022/03/16 21:50:42 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philosophers.h" + +t_arg *create_data(int argc, char **argv) +{ + t_arg *data; + pthread_mutex_t *display; + + display = malloc(sizeof(pthread_mutex_t)); + if (!display) + return (0); + pthread_mutex_init(display, 0); + data = malloc(sizeof(t_arg)); + pthread_mutex_init(&data->life_check, 0); + data->display = display; + data->death = 1; + data->full_philo = 0; + data->nb_philo = ft_atoi(argv[1]); + data->time_to_die = ft_atoi(argv[2]); + data->time_to_eat = ft_atoi(argv[3]); + data->time_to_sleep = ft_atoi(argv[4]); + data->must_eat = -1; + if (argc == 6) + data->must_eat = ft_atoi(argv[5]); + else + data->must_eat = -1; + return (data); +} + +t_philo *create_philo(t_arg *data) +{ + int i; + t_philo *philo; + + i = 0; + philo = malloc(sizeof(t_philo) * data->nb_philo); + if (!philo) + return (0); + while (i < data->nb_philo) + { + philo[i].last_eat = 0; + philo[i].philo_id = i + 1; + philo[i].data = data; + philo[i].nb_eat = 0; + philo[i].left_fork = malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(philo[i].left_fork, 0); + pthread_mutex_init(&philo[i].eat_check, 0); + i++; + } + i = 0; + while (i < data->nb_philo) + { + philo[i].right_fork = philo[(i + 1) % data->nb_philo].left_fork; + i++; + } + return (philo); +} diff --git a/srcs/main.c b/srcs/main.c new file mode 100644 index 0000000..8965c74 --- /dev/null +++ b/srcs/main.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/03/15 17:46:55 by apommier #+# #+# */ +/* Updated: 2022/03/16 21:57:11 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philosophers.h" + +int main(int argc, char **argv) +{ + t_arg *data; + t_philo *philo; + + if (check_arg(argc, argv)) + { + printf("Bad arguments\n"); + return (0); + } + data = create_data(argc, argv); + philo = create_philo(data); + start_philo(philo, data); + return (0); +} diff --git a/srcs/philo.c b/srcs/philo.c new file mode 100644 index 0000000..fbfe678 --- /dev/null +++ b/srcs/philo.c @@ -0,0 +1,123 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/02/20 19:10:43 by apommier #+# #+# */ +/* Updated: 2022/02/20 19:10:43 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philosophers.h" + +void philo_eat(t_philo *philo) +{ + t_arg *data; + + data = philo->data; + pthread_mutex_lock(philo->left_fork); + put_event(data, philo->philo_id, "has taken a fork"); + pthread_mutex_lock(philo->right_fork); + put_event(data, philo->philo_id, "has taken a fork"); + pthread_mutex_lock(&philo->eat_check); + put_event(data, philo->philo_id, "is eating"); + philo->last_eat = get_time(); + pthread_mutex_unlock(&philo->eat_check); + usleep(data->time_to_eat * 1000); + philo->nb_eat++; + pthread_mutex_unlock(philo->left_fork); + pthread_mutex_unlock(philo->right_fork); +} + +void death_checker(t_philo *philo, t_arg *data) +{ + int i; + int death; + + death = 1; + while (!data->full_philo && death) + { + i = -1; + while (++i < data->nb_philo - 1 && death) + { + pthread_mutex_lock(&philo[i].eat_check); + if ((get_time() - philo[i].last_eat) > data->time_to_die) + { + put_event(data, philo[i].philo_id, "is died"); + pthread_mutex_lock(&data->life_check); + data->death = 0; + pthread_mutex_unlock(&data->life_check); + death = 0; + printf("End: one philo died\n"); + printf("time_to_die: %d TIME: %ld start: %ld philo.start: %ld last_eat: %ld condition: %ld\n", data->time_to_die ,get_time(), data->time_start , philo[i].data->time_start, get_time() - philo[i].last_eat ,get_time() - philo[i].last_eat); + } + pthread_mutex_unlock(&philo[i].eat_check); + usleep(100); + if (!death) + break ; + i = 0; + while (data->must_eat != -1 && i < data->nb_philo + && philo[i].nb_eat >= data->must_eat) + i++; + if (i == data->nb_philo) + { + pthread_mutex_lock(&data->life_check); + data->death = 0; + data->full_philo = 1; + pthread_mutex_unlock(&data->life_check); + printf("End: all philo are full\n"); + } + } + } +} + +void *routine(void *tmp) +{ + t_philo *philo; + t_arg *data; + + philo = (t_philo *)tmp; + data = philo->data; + if (philo->philo_id % 2) + usleep(15000); + pthread_mutex_lock(&data->life_check); + while (philo->data->death) + { + pthread_mutex_unlock(&data->life_check); + philo_eat(philo); + put_event(data, philo->philo_id, "is sleeping"); + usleep(philo->data->time_to_sleep * 1000); + put_event(data, philo->philo_id, "is thinking"); + pthread_mutex_lock(&data->life_check); + } + pthread_mutex_unlock(&data->life_check); + return (0); +} + +int start_philo(t_philo *philo, t_arg *data) +{ + int i; + + i = 0; + data->time_start = get_time(); + while (i < data->nb_philo) + { + philo[i].last_eat = get_time(); + if (pthread_create(&philo[i].thread, 0, &routine, &philo[i])) + return (1); + i++; + } + death_checker(philo, data); + //printf(" after d_checker\n"); + i = 0; + while (i < data->nb_philo) + { + //printf("i = %d philo %d\n", i, philo[i].philo_id); + pthread_join(philo[i++].thread, 0); + } +// printf("after join\n"); + exit_philo(philo, data); + return (0); +} diff --git a/philosophers.h b/srcs/philosophers.h similarity index 71% rename from philosophers.h rename to srcs/philosophers.h index 7d58e71..0a00abe 100644 --- a/philosophers.h +++ b/srcs/philosophers.h @@ -22,13 +22,15 @@ typedef struct s_list { int nb_philo; - int nb_full_philo; + int full_philo; int time_to_die; int time_to_eat; int time_to_sleep; int must_eat; long time_start; - int death[1]; + int death; + pthread_mutex_t life_check; + pthread_mutex_t *display; } t_arg; typedef struct t_list @@ -36,16 +38,26 @@ typedef struct t_list int philo_id; pthread_t thread; t_arg *data; - int must_eat; - long last_eat[1]; + int nb_eat; + long last_eat; + pthread_mutex_t eat_check; pthread_mutex_t *right_fork; pthread_mutex_t *left_fork; - pthread_mutex_t *display; - } t_philo; //utils fonctions long ft_atoi(const char *nptr); long get_time(void); +void put_event(t_arg *data, int philo_id, char *event); +t_philo *create_philo(t_arg *data); +t_arg *create_data(int argc, char **argv); +void exit_philo(t_philo *philo, t_arg *data); + +//philo.c +int check_arg(int argc, char **argv); +int start_philo(t_philo *philo, t_arg *data); +void *routine(void *tmp); +void death_checker(t_philo *philoo, t_arg *data); +void philo_eat(t_philo *philo_tmp); #endif \ No newline at end of file diff --git a/utils.c b/srcs/utils.c similarity index 67% rename from utils.c rename to srcs/utils.c index 50db90d..165004b 100644 --- a/utils.c +++ b/srcs/utils.c @@ -45,3 +45,37 @@ long get_time(void) gettimeofday(&time, NULL); return (time.tv_sec * 1000 + time.tv_usec / 1000); } + +void put_event(t_arg *data, int philo_id, char *event) +{ + pthread_mutex_lock(&data->life_check); + pthread_mutex_lock(data->display); + if (data->death) + printf("%ldms Philo N°%d %s\n", get_time() - data->time_start, + philo_id, event); + pthread_mutex_unlock(data->display); + pthread_mutex_unlock(&data->life_check); +} + +int check_arg(int argc, char **argv) +{ + int i; + int j; + + j = 0; + i = 1; + if (argc != 5 && argc != 6) + return (1); + while (argv[i]) + { + j = 0; + while (argv[i][j]) + { + if (argv[i][j] > '9' || argv[i][j] < '0') + return (1); + j++; + } + i++; + } + return (0); +}