commit 4580f4d963bb75cca3c9bcf390a6dcf8fcd3a297 Author: Danny Jonker Date: Thu May 18 17:02:05 2023 +0200 firsttry diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..a33b5c1 --- /dev/null +++ b/Readme.md @@ -0,0 +1,11 @@ +# Philosophers + +--- +## Tester +- Write tester +- Wrong input +- try to make the program hang +- check 1 philosopher + +--- +[This project is part of the studies at 42](https://42.fr/en/homepage/) diff --git a/intra-uuid-c2ff0fca-c4ef-425a-a3b5-c9013600b6ac-4838105-djonker b/intra-uuid-c2ff0fca-c4ef-425a-a3b5-c9013600b6ac-4838105-djonker new file mode 160000 index 0000000..9ada401 --- /dev/null +++ b/intra-uuid-c2ff0fca-c4ef-425a-a3b5-c9013600b6ac-4838105-djonker @@ -0,0 +1 @@ +Subproject commit 9ada401ba0d9cd15e3c132c66693c13d56371965 diff --git a/philo/Makefile b/philo/Makefile new file mode 100644 index 0000000..83e8566 --- /dev/null +++ b/philo/Makefile @@ -0,0 +1,46 @@ +# **************************************************************************** # +# # +# .--. _ # +# Makefile |o_o || | # +# |:_/ || |_ _ ___ __ # +# By: djonker // \ \ __| | | \ \/ / # +# (| | )|_| |_| |> < # +# Created: 2021/08/19 15:20:20 by djonker /'\_ _/`\__|\__,_/_/\_\ # +# Updated: 2023/05/14 09:08:22 by djonker \___)=(___/ # +# # +# **************************************************************************** # + +NAME =philo +CC =gcc +CFLAGS =-Wall -Werror -Wextra -g -fsanitize=thread +RM =rm -f +SRC =src/philo.c\ + src/init.c\ + src/util.c +OBJ =$(SRC:src/%.c=obj/%.o) + +all: $(NAME) + +clean: + @$(RM) -r obj + @printf "\e[1;35mCleaned Object Files\n\e[0;00m" + +fclean: clean + @$(RM) philo philo_bonus + @printf "\e[1;31mCleaned Executables\n\e[0;00m" + +re: fclean all + +$(NAME): + +$(OBJ): $(SRC) + @mkdir -p $(dir $@) + @printf "\e[1;34mBuilding $@\n\e[0;00m" + @$(CC) $(CFLAGS) -c $(@:obj/%.o=src/%.c) -o $@ + +philo: $(OBJ) + @printf "\e[1;36mCompiling $@\n\e[0;00m" + @$(CC) $(CFLAGS) $^ -o $@ + @printf "\e[1;32mDone\e[0;00m\n" + +.PHONY: all clean fclean re diff --git a/philo/philo.h b/philo/philo.h new file mode 100644 index 0000000..a3e47d7 --- /dev/null +++ b/philo/philo.h @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* philo.h |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/11 07:19:18 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 06:08:32 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#ifndef PHILO_H +# define PHILO_H + +# include +# include +# include +# include +# include + +typedef struct s_philo +{ + int id; + int cycles; + pthread_mutex_t *forks; + pthread_mutex_t *datarace; + int *philos; + int lfork; + int rfork; + long long lastfood; + long long *dietime; + long long *eattime; + long long *sleeptime; + long long *strtt; + int *target; + int *done; + int *dead; + pthread_t thrd; +} t_philo; + +typedef struct s_strct +{ + pthread_mutex_t forks[512]; + pthread_mutex_t datarace[3]; + t_philo philo[512]; + int philos; + long long dietime; + long long eattime; + long long sleeptime; + long long strtt; + int target; + int done; + int dead; + char *error; +} t_strct; + +t_strct *ft_parseandvalidateinput(int argc, char **argv); +int ft_initstructandmutex(t_strct *strct); +int ft_startcycle(t_strct *strct); +void *ft_cycle(void *pointer); +int ft_liveordie(t_strct *strct, int i); +int ft_cleanup(t_strct *strct); +long long ft_time(void); +int philo_atoi(char *str); +int ft_printreturn(char *reason, int code); +int ft_charactercheck(int argc, char **argv); +int ft_alivecheck(t_philo *ps); + +#endif diff --git a/philo/src/init.c b/philo/src/init.c new file mode 100644 index 0000000..d36fa26 --- /dev/null +++ b/philo/src/init.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* init.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/15 02:00:19 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 08:24:58 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_charactercheck(int argc, char **argv) +{ + int i; + int j; + + i = 1; + j = 0; + while (i < argc) + { + while (argv[i][j] != '\0') + { + if (argv[i][j] < '0' || argv[i][j] > '9') + return (1); + j++; + } + i++; + j = 0; + } + return (0); +} + +t_strct *ft_parseandvalidateinput(int argc, char **argv) +{ + t_strct *strct; + + strct = malloc(sizeof(t_strct)); + strct->error = NULL; + if (ft_charactercheck(argc, argv)) + strct->error = "input can only be numbers"; + strct->philos = philo_atoi(argv[1]); + if (strct->philos < 1 || strct->philos > 500) + strct->error = "Min 1 and Max 500 philosophers"; + strct->dietime = philo_atoi(argv[2]); + if (strct->dietime < 50) + strct->error = "die time must be a minimum of 50ms"; + strct->eattime = philo_atoi(argv[3]); + if (strct->eattime < 50) + strct->error = "eat time must be a minimum of 50ms"; + strct->sleeptime = philo_atoi(argv[4]); + if (strct->sleeptime < 50) + strct->error = "sleeptime must be a minimum of 50ms"; + if (argc == 6) + strct->target = philo_atoi(argv[5]); + else + strct->target = 1000000000; + if (strct->target < 0) + strct->error = "We can't do negative cycles"; + return (strct); +} + +int ft_initstructandmutex(t_strct *strct) +{ + int i; + + i = 0; + while (i <= strct->philos) + { + strct->philo[i].id = i + 1; + strct->philo[i].cycles = 0; + strct->philo[i].thrd = (pthread_t)(&i); + strct->philo[i].dietime = &strct->dietime; + strct->philo[i].eattime = &strct->eattime; + strct->philo[i].sleeptime = &strct->sleeptime; + strct->philo[i].strtt = &strct->strtt; + strct->philo[i].forks = strct->forks; + strct->philo[i].datarace = strct->datarace; + strct->philo[i].lfork = i; + strct->philo[i].rfork = (i + 1) % strct->philos; + strct->philo[i].philos = &strct->philos; + strct->philo[i].target = &strct->target; + strct->philo[i].done = &strct->done; + strct->philo[i].dead = &strct->dead; + pthread_mutex_init(&strct->forks[i], NULL); + i++; + } + return (0); +} diff --git a/philo/src/philo.c b/philo/src/philo.c new file mode 100644 index 0000000..7b120dd --- /dev/null +++ b/philo/src/philo.c @@ -0,0 +1,133 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* philo.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/11 06:42:31 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 08:18:24 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_eatsleepthink(t_philo *ps) +{ + pthread_mutex_lock(&ps->forks[ps->lfork]); + if (ft_alivecheck(ps)) + printf("%lld %d has taken a fork\n", ft_time() - *ps->strtt, ps->id); + if (*ps->philos == 1) + return (1); + pthread_mutex_lock(&ps->forks[ps->rfork]); + if (ft_alivecheck(ps)) + printf("%lld %d has taken a fork\n", ft_time() - *ps->strtt, ps->id); + pthread_mutex_lock(&ps->datarace[0]); + ps->lastfood = ft_time(); + pthread_mutex_unlock(&ps->datarace[0]); + if (ft_alivecheck(ps)) + printf("%lld %d is eating\n", ft_time() - *ps->strtt, ps->id); + usleep(*ps->eattime * 1000); + pthread_mutex_unlock(&ps->forks[ps->lfork]); + pthread_mutex_unlock(&ps->forks[ps->rfork]); + if (ft_alivecheck(ps)) + printf("%lld %d is sleeping\n", ft_time() - *ps->strtt, ps->id); + usleep(*ps->sleeptime * 1000); + if (ft_alivecheck(ps)) + printf("%lld %d is thinking\n", ft_time() - *ps->strtt, ps->id); + pthread_mutex_lock(&ps->datarace[2]); + ps->cycles++; + pthread_mutex_unlock(&ps->datarace[2]); + return (0); +} + +void *ft_cycle(void *pointer) +{ + t_philo *philo; + + philo = pointer; + if ((philo->id - 1) % 2) + usleep(*philo->eattime * 1000); + pthread_mutex_lock(&philo->datarace[2]); + while (philo->cycles < *philo->target && *philo->dead == 0) + { + pthread_mutex_unlock(&philo->datarace[2]); + if (ft_eatsleepthink(philo)) + return (NULL); + pthread_mutex_lock(&philo->datarace[2]); + } + pthread_mutex_unlock(&philo->datarace[2]); + pthread_mutex_lock(&philo->datarace[1]); + *philo->done = *philo->done + 1; + pthread_mutex_unlock(&philo->datarace[1]); + return (NULL); +} + +int ft_liveordie(t_strct *stct, int i) +{ + pthread_mutex_lock(&stct->datarace[1]); + while (stct->done < stct->philos) + { + pthread_mutex_unlock(&stct->datarace[1]); + if (i == stct->philos) + i = 0; + pthread_mutex_lock(&stct->datarace[0]); + if (ft_time() - stct->philo[i].lastfood > stct->dietime) + { + printf("%lld %d died\n", ft_time() - stct->strtt, stct->philo[i].id); + pthread_mutex_lock(&stct->datarace[2]); + stct->dead = 1; + pthread_mutex_unlock(&stct->datarace[2]); + pthread_mutex_unlock(&stct->datarace[0]); + return (1); + } + pthread_mutex_unlock(&stct->datarace[0]); + usleep(100); + i++; + pthread_mutex_lock(&stct->datarace[1]); + } + pthread_mutex_unlock(&stct->datarace[1]); + printf("All %d philosophers have", stct->philos); + printf(" finished all %d cycles\n", stct->target); + return (0); +} + +int ft_startcycle(t_strct *strct) +{ + int i; + + i = 0; + strct->strtt = ft_time(); + while (i < strct->philos) + { + strct->philo[i].lastfood = ft_time(); + pthread_create(&strct->philo[i].thrd, NULL, ft_cycle, &strct->philo[i]); + i++; + } + ft_liveordie(strct, 0); + return (0); +} + +int main(int argc, char **argv) +{ + t_strct *strct; + + if (argc < 5 || argc > 6) + return (ft_printreturn("Wrong number of arguments", 1)); + strct = ft_parseandvalidateinput(argc, argv); + if (strct->error) + { + ft_printreturn(strct->error, 0); + free(strct); + return (1); + } + strct->done = 0; + strct->dead = 0; + pthread_mutex_init(&strct->datarace[0], NULL); + pthread_mutex_init(&strct->datarace[1], NULL); + pthread_mutex_init(&strct->datarace[2], NULL); + ft_initstructandmutex(strct); + ft_startcycle(strct); + ft_cleanup(strct); + return (0); +} diff --git a/philo/src/util.c b/philo/src/util.c new file mode 100644 index 0000000..0cee70e --- /dev/null +++ b/philo/src/util.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* util.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/15 02:01:41 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 06:09:40 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_printreturn(char *reason, int code) +{ + printf("%s\n", reason); + return (code); +} + +long long ft_time(void) +{ + struct timeval t; + long long r; + + gettimeofday(&t, NULL); + r = (t.tv_sec * 1000) + (t.tv_usec / 1000); + return (r); +} + +int philo_atoi(char *str) +{ + unsigned int r; + int c; + int n; + + r = 0; + c = 0; + n = 1; + if (str == NULL) + return (0); + while ((str[c] == 32) || (str[c] > 8 && str[c] < 14)) + c++; + if (str[c] == '-' || str[c] == '+') + if (str[c++] == '-') + n = -1; + while (str[c] >= '0' && str[c] <= '9') + { + r = 10 * r + (str[c] - '0'); + if (r > 2147483647 && n == 1) + return (-1); + else if (r > 2147483648 && n == -1) + return (0); + c++; + } + return (n * r); +} + +int ft_cleanup(t_strct *strct) +{ + int i; + + i = 0; + while (i < strct->philos) + { + pthread_join(strct->philo[i].thrd, NULL); + i++; + } + i = 0; + while (i < strct->philos) + { + pthread_mutex_destroy(&strct->forks[i]); + i++; + } + pthread_mutex_destroy(&strct->datarace[0]); + pthread_mutex_destroy(&strct->datarace[1]); + pthread_mutex_destroy(&strct->datarace[2]); + free(strct); + return (0); +} + +int ft_alivecheck(t_philo *ps) +{ + int i; + + i = 1; + pthread_mutex_lock(&ps->datarace[2]); + if (*ps->dead) + i = 0; + pthread_mutex_unlock(&ps->datarace[2]); + return (i); +} diff --git a/philo_bonus/Makefile b/philo_bonus/Makefile new file mode 100644 index 0000000..8ba5134 --- /dev/null +++ b/philo_bonus/Makefile @@ -0,0 +1,44 @@ +# **************************************************************************** # +# # +# .--. _ # +# Makefile |o_o || | # +# |:_/ || |_ _ ___ __ # +# By: djonker // \ \ __| | | \ \/ / # +# (| | )|_| |_| |> < # +# Created: 2021/08/19 15:20:20 by djonker /'\_ _/`\__|\__,_/_/\_\ # +# Updated: 2023/05/14 09:48:37 by djonker \___)=(___/ # +# # +# **************************************************************************** # + +NAME =philo_bonus +CC =gcc +CFLAGS =-Wall -Werror -Wextra# -g -fsanitize=address +RM =rm -f +SRC =src/philo.c\ + src/init.c\ + src/util.c +OBJ =$(SRC:src/%.c=obj/%.o) + +all: $(NAME) + +clean: + @$(RM) -r obj + @printf "\e[1;35mCleaned Object Files\n\e[0;00m" + +fclean: clean + @$(RM) philo_bonus + @printf "\e[1;31mCleaned Executables\n\e[0;00m" + +re: fclean all + +$(OBJ): $(SRC) + @mkdir -p $(dir $@) + @printf "\e[1;34mBuilding $@\n\e[0;00m" + @$(CC) $(CFLAGS) -c $(@:obj/%.o=src/%.c) -o $@ + +philo_bonus:$(OBJ) + @printf "\e[1;36mCompiling $@\n\e[0;00m" + @$(CC) $(CFLAGS) $^ -o $@ + @printf "\e[1;32mDone\e[0;00m\n" + +.PHONY: all clean fclean re diff --git a/philo_bonus/philo.h b/philo_bonus/philo.h new file mode 100644 index 0000000..d4adb83 --- /dev/null +++ b/philo_bonus/philo.h @@ -0,0 +1,78 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* philo.h |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/11 07:19:18 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 08:55:03 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#ifndef PHILO_H +# define PHILO_H + +# include +# include +# include +# include +# include +# include +# include +# include + +typedef struct s_philo +{ + int id; + int cycles; + sem_t *forks; + int *philos; + int *pid; + int lfork; + int rfork; + long long lastfood; + long long *dietime; + long long *eattime; + long long *sleeptime; + long long *strtt; + int *target; + sem_t *done; + sem_t *dead; + sem_t *hold; + sem_t *print; +} t_philo; + +typedef struct s_strct +{ + sem_t *forks; + t_philo philo[512]; + int pid[512]; + int philos; + long long dietime; + long long eattime; + long long sleeptime; + long long strtt; + int target; + sem_t *done; + sem_t *dead; + sem_t *hold; + sem_t *print; + char *error; +} t_strct; + +t_strct *ft_parseandvalidateinput(int argc, char **argv); +int ft_initstructandmutex(t_strct *strct, int i); +int ft_startcycle(t_strct *strct); +void ft_cycle(void *pointer); +int ft_releasetheminds(t_strct *strct); +int ft_cyclecounter(t_strct *strct); +int ft_waitingfordeath(t_strct *strct); +int ft_cleanup(t_strct *strct); +long long ft_time(void); +int philo_atoi(char *str); +int ft_printreturn(char *reason, int code); +int ft_charactercheck(int argc, char **argv); +void ft_safeprint(t_philo *ps, char *str); + +#endif diff --git a/philo_bonus/src/init.c b/philo_bonus/src/init.c new file mode 100644 index 0000000..f0b09ed --- /dev/null +++ b/philo_bonus/src/init.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* init.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/15 02:00:19 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 08:55:41 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_charactercheck(int argc, char **argv) +{ + int i; + int j; + + i = 1; + j = 0; + while (i < argc) + { + while (argv[i][j] != '\0') + { + if (argv[i][j] < '0' || argv[i][j] > '9') + return (1); + j++; + } + i++; + j = 0; + } + return (0); +} + +t_strct *ft_parseandvalidateinput(int argc, char **argv) +{ + t_strct *strct; + + strct = malloc(sizeof(t_strct)); + strct->error = NULL; + if (ft_charactercheck(argc, argv)) + strct->error = "input can only be numbers"; + strct->philos = philo_atoi(argv[1]); + if (strct->philos < 1 || strct->philos > 500) + strct->error = "Min 1 and Max 500 philosophers"; + strct->dietime = philo_atoi(argv[2]); + if (strct->dietime < 50) + strct->error = "die time must be a minimum of 50ms"; + strct->eattime = philo_atoi(argv[3]); + if (strct->eattime < 50) + strct->error = "eat time must be a minimum of 50ms"; + strct->sleeptime = philo_atoi(argv[4]); + if (strct->sleeptime < 50) + strct->error = "sleeptime must be a minimum of 50ms"; + if (argc == 6) + strct->target = philo_atoi(argv[5]); + else + strct->target = 1000000000; + if (strct->target < 0) + strct->error = "We can't do negative cycles"; + return (strct); +} + +int ft_initstructandmutex(t_strct *strct, int i) +{ + strct->dead = sem_open("dead", O_CREAT, 0666, 0); + strct->done = sem_open("done", O_CREAT, 0666, 0); + strct->hold = sem_open("hold", O_CREAT, 0666, 0); + strct->print = sem_open("print", O_CREAT, 0666, 1); + strct->forks = sem_open("forks", O_CREAT, 0666, strct->philos); + while (i <= strct->philos) + { + strct->philo[i].id = i + 1; + strct->philo[i].cycles = 0; + strct->philo[i].dietime = &strct->dietime; + strct->philo[i].eattime = &strct->eattime; + strct->philo[i].sleeptime = &strct->sleeptime; + strct->philo[i].strtt = &strct->strtt; + strct->philo[i].philos = &strct->philos; + strct->philo[i].target = &strct->target; + strct->philo[i].forks = strct->forks; + strct->philo[i].done = strct->done; + strct->philo[i].dead = strct->dead; + strct->philo[i].hold = strct->hold; + strct->philo[i].print = strct->print; + strct->philo[i].pid = strct->pid; + i++; + } + return (0); +} + +int ft_releasetheminds(t_strct *strct) +{ + int i; + + i = 0; + while (i < strct->philos) + { + sem_post(strct->hold); + i++; + } + return (0); +} + +void ft_safeprint(t_philo *ps, char *str) +{ + sem_wait(ps->print); + printf("%lld %d %s\n", ft_time() - *ps->strtt, ps->id, str); + sem_post(ps->print); +} diff --git a/philo_bonus/src/philo.c b/philo_bonus/src/philo.c new file mode 100644 index 0000000..21372db --- /dev/null +++ b/philo_bonus/src/philo.c @@ -0,0 +1,148 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* philo.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/11 06:42:31 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 09:24:42 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_eatsleepthink(t_philo *ps) +{ + sem_wait(ps->forks); + if (ft_time() - ps->lastfood > *ps->dietime) + return (1); + ft_safeprint(ps, "has taken a fork"); + if (*ps->philos == 1) + return (1); + sem_wait(ps->forks); + ft_safeprint(ps, "has taken a fork"); + ps->lastfood = ft_time(); + ft_safeprint(ps, "is eating"); + usleep(*ps->eattime * 1000); + sem_post(ps->forks); + sem_post(ps->forks); + if (ft_time() - ps->lastfood > *ps->dietime) + return (1); + ft_safeprint(ps, "is sleeping"); + usleep(*ps->sleeptime * 1000); + if (ft_time() - ps->lastfood > *ps->dietime) + return (1); + ft_safeprint(ps, "is thinking"); + ps->cycles++; + if (ps->cycles == *ps->target) + return (2); + return (0); +} + +void ft_cycle(void *pointer) +{ + t_philo *philo; + int ret; + + ret = 0; + philo = pointer; + philo->hold = sem_open("hold", 0); + sem_wait(philo->hold); + philo->dead = sem_open("dead", 0); + philo->done = sem_open("done", 0); + if ((philo->id - 1) % 2) + usleep(*philo->eattime * 1000); + while (!ret) + ret = ft_eatsleepthink(philo); + if (ret == 1) + { + printf("%lld %d died\n", ft_time() - *philo->strtt, philo->id); + sem_post(philo->dead); + } + if (ret == 2) + sem_post(philo->done); +} + +int ft_startcycle(t_strct *strct) +{ + int i; + + i = 0; + strct->strtt = ft_time(); + while (i < strct->philos) + { + strct->philo[i].lastfood = ft_time(); + strct->pid[i] = fork(); + if (strct->pid[i] == 0) + { + ft_cycle(&strct->philo[i]); + sem_close(strct->dead); + sem_close(strct->done); + sem_close(strct->hold); + sem_close(strct->forks); + sem_close(strct->print); + free(strct); + exit(0); + } + i++; + } + return (0); +} + +int ft_cyclecounter(t_strct *strct) +{ + int i; + sem_t *done; + int philos; + int target; + + philos = strct->philos; + target = strct->target; + sem_close(strct->dead); + sem_close(strct->done); + sem_close(strct->hold); + sem_close(strct->forks); + sem_close(strct->print); + free(strct); + done = sem_open("done", 0); + i = 0; + while (i < philos) + { + sem_wait(done); + i++; + } + printf("All %d philosophers have", philos); + printf(" finished all %d cycles\n", target); + sem_close(done); + exit (0); +} + +int main(int argc, char **argv) +{ + t_strct *strct; + int i; + + if (argc < 5 || argc > 6) + return (ft_printreturn("Wrong number of arguments", 1)); + strct = ft_parseandvalidateinput(argc, argv); + if (strct->error) + { + ft_printreturn(strct->error, 0); + free(strct); + return (1); + } + i = ft_initstructandmutex(strct, 0); + ft_startcycle(strct); + strct->pid[501] = fork(); + if (strct->pid[501] == 0) + ft_waitingfordeath(strct); + strct->pid[502] = fork(); + if (strct->pid[502] == 0) + ft_cyclecounter(strct); + ft_releasetheminds(strct); + while (i != strct->pid[501] && i != strct->pid[502]) + i = waitpid(-1, NULL, 0); + ft_cleanup(strct); + return (0); +} diff --git a/philo_bonus/src/util.c b/philo_bonus/src/util.c new file mode 100644 index 0000000..1e4c63f --- /dev/null +++ b/philo_bonus/src/util.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* .--. _ */ +/* util.c |o_o || | */ +/* |:_/ || |_ _ ___ __ */ +/* By: houtworm // \ \ __| | | \ \/ / */ +/* (| | )|_| |_| |> < */ +/* Created: 2023/03/15 02:01:41 by houtworm /'\_ _/`\__|\__,_/_/\_\ */ +/* Updated: 2023/05/14 09:13:53 by djonker \___)=(___/ */ +/* */ +/* ************************************************************************** */ + +#include "../philo.h" + +int ft_printreturn(char *reason, int code) +{ + printf("%s\n", reason); + return (code); +} + +long long ft_time(void) +{ + struct timeval t; + long long r; + + gettimeofday(&t, NULL); + r = (t.tv_sec * 1000) + (t.tv_usec / 1000); + return (r); +} + +int ft_waitingfordeath(t_strct *strct) +{ + sem_t *dead; + + sem_close(strct->dead); + sem_close(strct->done); + sem_close(strct->hold); + sem_close(strct->forks); + sem_close(strct->print); + free(strct); + dead = sem_open("dead", 0); + sem_wait(dead); + sem_close(dead); + exit (0); +} + +int philo_atoi(char *str) +{ + unsigned int r; + int c; + int n; + + r = 0; + c = 0; + n = 1; + if (str == NULL) + return (0); + while ((str[c] == 32) || (str[c] > 8 && str[c] < 14)) + c++; + if (str[c] == '-' || str[c] == '+') + if (str[c++] == '-') + n = -1; + while (str[c] >= '0' && str[c] <= '9') + { + r = 10 * r + (str[c] - '0'); + if (r > 2147483647 && n == 1) + return (-1); + else if (r > 2147483648 && n == -1) + return (0); + c++; + } + return (n * r); +} + +int ft_cleanup(t_strct *strct) +{ + int i; + + i = 0; + kill(strct->pid[501], 15); + kill(strct->pid[502], 15); + while (i < strct->philos) + { + kill(strct->pid[i], 15); + i++; + } + sem_close(strct->dead); + sem_close(strct->done); + sem_close(strct->hold); + sem_close(strct->forks); + sem_close(strct->print); + sem_unlink("dead"); + sem_unlink("done"); + sem_unlink("hold"); + sem_unlink("forks"); + sem_unlink("print"); + free(strct); + exit (0); +}