├── .gitignore ├── README.md ├── philo_three ├── eat.c ├── forks.c ├── semaphores.c ├── Makefile ├── exit.c ├── messages.c ├── monitor.c ├── utils.c ├── main.c ├── init.c └── philosophers.h ├── philo_one ├── eat.c ├── Makefile ├── forks.c ├── exit.c ├── messages.c ├── utils.c ├── philosophers.h ├── init.c └── main.c └── philo_two ├── semaphores.c ├── Makefile ├── eat.c ├── forks.c ├── exit.c ├── messages.c ├── utils.c ├── init.c ├── philosophers.h └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.o 3 | */philo_one 4 | */philo_two 5 | */philo_three -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Philosophers 2 | 3 | ## Ressources 4 | 5 | * [Parallel Computing](https://computing.llnl.gov/tutorials/parallel_comp/) 6 | * [POSIX Threads](https://computing.llnl.gov/tutorials/pthreads/) ([pthread routines](https://computing.llnl.gov/tutorials/pthreads/#AppendixA)) 7 | * [Working example](https://timmurphy.org/2010/05/04/pthreads-in-c-a-minimal-working-example/) 8 | * [French tutorial](https://franckh.developpez.com/tutoriels/posix/pthreads/) 9 | * [Semaphores in C](http://greenteapress.com/thinkos/html/thinkos012.html) 10 | * [Semaphores example in French](http://jean-luc.massat.perso.luminy.univ-amu.fr/ens/docs/thread-sem.html) 11 | * [fork() example](https://timmurphy.org/2014/04/26/using-fork-in-cc-a-minimum-working-example/) 12 | * [fork() multiple childs](https://stackoverflow.com/questions/876605/multiple-child-process) 13 | * [Semaphore when programs end](https://stackoverflow.com/questions/9537068/sem-close-vs-sem-unlink-when-process-terminates) 14 | -------------------------------------------------------------------------------- /philo_three/eat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* eat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:41:58 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:58:50 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | void 16 | eat(t_philo *philo) 17 | { 18 | sem_wait(philo->mutex); 19 | philo->is_eating = 1; 20 | philo->last_eat = get_time(); 21 | philo->limit = philo->last_eat + philo->state->time_to_die; 22 | display_message(philo, TYPE_EAT); 23 | usleep(philo->state->time_to_eat * 1000); 24 | philo->eat_count++; 25 | philo->is_eating = 0; 26 | sem_post(philo->mutex); 27 | sem_post(philo->eat_count_m); 28 | } 29 | -------------------------------------------------------------------------------- /philo_one/eat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* eat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:41:58 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:08:46 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | void 16 | eat(t_philo *philo) 17 | { 18 | pthread_mutex_lock(&philo->mutex); 19 | philo->is_eating = 1; 20 | philo->last_eat = get_time(); 21 | philo->limit = philo->last_eat + philo->state->time_to_die; 22 | display_message(philo, TYPE_EAT); 23 | usleep(philo->state->time_to_eat * 1000); 24 | philo->eat_count++; 25 | philo->is_eating = 0; 26 | pthread_mutex_unlock(&philo->mutex); 27 | pthread_mutex_unlock(&philo->eat_m); 28 | } 29 | -------------------------------------------------------------------------------- /philo_three/forks.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* forks.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:40:23 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:36:13 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | void 16 | take_forks(t_philo *philo) 17 | { 18 | sem_wait(philo->state->forks_m); 19 | display_message(philo, TYPE_FORK); 20 | sem_wait(philo->state->forks_m); 21 | display_message(philo, TYPE_FORK); 22 | } 23 | 24 | void 25 | clean_forks(t_philo *philo) 26 | { 27 | display_message(philo, TYPE_SLEEP); 28 | sem_post(philo->state->forks_m); 29 | sem_post(philo->state->forks_m); 30 | usleep(philo->state->time_to_sleep * 1000); 31 | } 32 | -------------------------------------------------------------------------------- /philo_three/semaphores.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* semaphores.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 23:22:05 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:57:47 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | sem_t 16 | *ft_sem_open(char const *name, int value) 17 | { 18 | return (sem_open(name, O_CREAT | O_EXCL, 0644, value)); 19 | } 20 | 21 | char 22 | *make_semaphore_name(char const *base, char *buffer, int position) 23 | { 24 | int i; 25 | 26 | i = ft_strcpy(buffer, base); 27 | while (position > 0) 28 | { 29 | buffer[i++] = (position % 10) + '0'; 30 | position /= 10; 31 | } 32 | buffer[i] = 0; 33 | return (buffer); 34 | } 35 | -------------------------------------------------------------------------------- /philo_two/semaphores.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* semaphores.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 23:22:05 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:38:18 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | sem_t 16 | *ft_sem_open(char const *name, int value) 17 | { 18 | sem_unlink(name); 19 | return (sem_open(name, O_CREAT | O_EXCL, 0644, value)); 20 | } 21 | 22 | char 23 | *make_semaphore_name(char const *base, char *buffer, int position) 24 | { 25 | int i; 26 | 27 | i = ft_strcpy(buffer, base); 28 | while (position > 0) 29 | { 30 | buffer[i++] = (position % 10) + '0'; 31 | position /= 10; 32 | } 33 | buffer[i] = 0; 34 | return (buffer); 35 | } 36 | -------------------------------------------------------------------------------- /philo_one/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: ncolomer +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2019/12/09 19:06:43 by ncolomer #+# #+# # 9 | # Updated: 2019/12/12 23:24:03 by ncolomer ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | SRCS = main.c utils.c exit.c messages.c init.c forks.c eat.c 14 | OBJS = $(SRCS:.c=.o) 15 | 16 | CC = gcc 17 | RM = rm -f 18 | CFLAGS = -Wall -Wextra -Werror -I. 19 | LIBS = -lpthread 20 | 21 | NAME = philo_one 22 | 23 | all: $(NAME) 24 | 25 | $(NAME): $(OBJS) 26 | gcc ${CFLAGS} -o ${NAME} ${OBJS} ${LIBS} 27 | 28 | clean: 29 | $(RM) $(OBJS) $(BONUS_OBJS) 30 | 31 | fclean: clean 32 | $(RM) $(NAME) 33 | 34 | re: fclean $(NAME) 35 | 36 | .PHONY: all clean fclean re 37 | -------------------------------------------------------------------------------- /philo_two/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: ncolomer +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2019/12/09 19:06:43 by ncolomer #+# #+# # 9 | # Updated: 2019/12/13 17:02:33 by ncolomer ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | SRCS = main.c utils.c exit.c messages.c init.c forks.c eat.c \ 14 | semaphores.c 15 | OBJS = $(SRCS:.c=.o) 16 | 17 | CC = gcc 18 | RM = rm -f 19 | CFLAGS = -Wall -Wextra -Werror -I. 20 | LIBS = -lpthread 21 | 22 | NAME = philo_two 23 | 24 | all: $(NAME) 25 | 26 | $(NAME): $(OBJS) 27 | gcc ${CFLAGS} -o ${NAME} ${OBJS} ${LIBS} 28 | 29 | clean: 30 | $(RM) $(OBJS) $(BONUS_OBJS) 31 | 32 | fclean: clean 33 | $(RM) $(NAME) 34 | 35 | re: fclean $(NAME) 36 | 37 | .PHONY: all clean fclean re 38 | -------------------------------------------------------------------------------- /philo_three/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: ncolomer +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2019/12/09 19:06:43 by ncolomer #+# #+# # 9 | # Updated: 2019/12/13 16:08:44 by ncolomer ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | SRCS = main.c utils.c exit.c messages.c init.c forks.c eat.c \ 14 | semaphores.c monitor.c 15 | OBJS = $(SRCS:.c=.o) 16 | 17 | CC = gcc 18 | RM = rm -f 19 | CFLAGS = -Wall -Wextra -Werror -I. 20 | LIBS = -lpthread 21 | 22 | NAME = philo_three 23 | 24 | all: $(NAME) 25 | 26 | $(NAME): $(OBJS) 27 | gcc ${CFLAGS} -o ${NAME} ${OBJS} ${LIBS} 28 | 29 | clean: 30 | $(RM) $(OBJS) $(BONUS_OBJS) 31 | 32 | fclean: clean 33 | $(RM) $(NAME) 34 | 35 | re: fclean $(NAME) 36 | 37 | .PHONY: all clean fclean re 38 | -------------------------------------------------------------------------------- /philo_two/eat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* eat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:41:58 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 20:46:54 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | eat(t_philo *philo) 17 | { 18 | if (sem_wait(philo->mutex) != 0) 19 | return (1); 20 | philo->is_eating = 1; 21 | philo->last_eat = get_time(); 22 | philo->limit = philo->last_eat + philo->state->time_to_die; 23 | if (display_message(philo, TYPE_EAT)) 24 | return (1); 25 | usleep(philo->state->time_to_eat * 1000); 26 | philo->eat_count++; 27 | philo->is_eating = 0; 28 | if (sem_post(philo->mutex)) 29 | return (1); 30 | if (sem_post(philo->eat_count_m)) 31 | return (1); 32 | return (0); 33 | } 34 | -------------------------------------------------------------------------------- /philo_one/forks.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* forks.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:40:23 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/12 23:04:46 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | void 16 | take_forks(t_philo *philo) 17 | { 18 | pthread_mutex_lock(&philo->state->forks_m[philo->lfork]); 19 | display_message(philo, TYPE_FORK); 20 | pthread_mutex_lock(&philo->state->forks_m[philo->rfork]); 21 | display_message(philo, TYPE_FORK); 22 | } 23 | 24 | void 25 | clean_forks(t_philo *philo) 26 | { 27 | display_message(philo, TYPE_SLEEP); 28 | pthread_mutex_unlock(&philo->state->forks_m[philo->lfork]); 29 | pthread_mutex_unlock(&philo->state->forks_m[philo->rfork]); 30 | usleep(philo->state->time_to_sleep * 1000); 31 | } 32 | -------------------------------------------------------------------------------- /philo_two/forks.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* forks.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:40:23 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 20:47:12 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "philosophers.h" 15 | 16 | int 17 | take_forks(t_philo *philo) 18 | { 19 | if (sem_wait(philo->state->forks_m)) 20 | return (1); 21 | if (display_message(philo, TYPE_FORK)) 22 | return (1); 23 | if (sem_wait(philo->state->forks_m)) 24 | return (1); 25 | if (display_message(philo, TYPE_FORK)) 26 | return (1); 27 | return (0); 28 | } 29 | 30 | int 31 | clean_forks(t_philo *philo) 32 | { 33 | if (display_message(philo, TYPE_SLEEP)) 34 | return (1); 35 | if (sem_post(philo->state->forks_m)) 36 | return (1); 37 | if (sem_post(philo->state->forks_m)) 38 | return (1); 39 | usleep(philo->state->time_to_sleep * 1000); 40 | return (0); 41 | } 42 | -------------------------------------------------------------------------------- /philo_two/exit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* exit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:02:59 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 20:50:10 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "philosophers.h" 15 | 16 | int 17 | clear_state(t_state *state) 18 | { 19 | int i; 20 | char semaphore[255]; 21 | 22 | sem_unlink(SEMAPHORE_FORK); 23 | sem_unlink(SEMAPHORE_WRITE); 24 | sem_unlink(SEMAPHORE_DEAD); 25 | if (state->philos) 26 | { 27 | i = 0; 28 | while (i < state->amount) 29 | { 30 | make_semaphore_name(SEMAPHORE_PHILO, (char*)semaphore, i); 31 | sem_unlink(semaphore); 32 | make_semaphore_name(SEMAPHORE_PHILOEAT, (char*)semaphore, i++); 33 | sem_unlink(semaphore); 34 | } 35 | free(state->philos); 36 | } 37 | return (1); 38 | } 39 | 40 | int 41 | exit_error(char const *str) 42 | { 43 | if (str) 44 | write(1, str, ft_strlen(str)); 45 | return (1); 46 | } 47 | -------------------------------------------------------------------------------- /philo_three/exit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* exit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:02:59 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 20:50:17 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | clear_state(t_state *state) 17 | { 18 | int i; 19 | char semaphore[255]; 20 | 21 | sem_unlink(SEMAPHORE_FORK); 22 | sem_unlink(SEMAPHORE_WRITE); 23 | sem_unlink(SEMAPHORE_DEAD); 24 | sem_unlink(SEMAPHORE_DEADW); 25 | if (state->philos) 26 | { 27 | i = 0; 28 | while (i < state->amount) 29 | { 30 | make_semaphore_name(SEMAPHORE_PHILO, (char*)semaphore, i); 31 | sem_unlink(semaphore); 32 | make_semaphore_name(SEMAPHORE_PHILOEAT, (char*)semaphore, i++); 33 | sem_unlink(semaphore); 34 | } 35 | free(state->philos); 36 | } 37 | return (1); 38 | } 39 | 40 | int 41 | exit_error(char const *str) 42 | { 43 | if (str) 44 | write(1, str, ft_strlen(str)); 45 | return (1); 46 | } 47 | -------------------------------------------------------------------------------- /philo_one/exit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* exit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/12 22:02:59 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:09:51 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | clear_state(t_state *state) 17 | { 18 | int i; 19 | 20 | if (state->forks_m) 21 | { 22 | i = 0; 23 | while (i < state->amount) 24 | pthread_mutex_destroy(&state->forks_m[i++]); 25 | free(state->forks_m); 26 | } 27 | if (state->philos) 28 | { 29 | i = 0; 30 | while (i < state->amount) 31 | { 32 | pthread_mutex_destroy(&state->philos[i].mutex); 33 | pthread_mutex_destroy(&state->philos[i++].eat_m); 34 | } 35 | free(state->philos); 36 | } 37 | pthread_mutex_destroy(&state->write_m); 38 | pthread_mutex_destroy(&state->somebody_dead_m); 39 | return (1); 40 | } 41 | 42 | int 43 | exit_error(char const *str) 44 | { 45 | if (str) 46 | write(1, str, ft_strlen(str)); 47 | return (1); 48 | } 49 | -------------------------------------------------------------------------------- /philo_three/messages.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* messages.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 18:31:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 16:01:52 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static char 16 | *get_message(int type) 17 | { 18 | if (type == TYPE_EAT) 19 | return (" is eating\n"); 20 | else if (type == TYPE_SLEEP) 21 | return (" is sleeping\n"); 22 | else if (type == TYPE_FORK) 23 | return (" has taken a fork\n"); 24 | else if (type == TYPE_THINK) 25 | return (" is thinking\n"); 26 | else if (type == TYPE_OVER) 27 | return ("must eat count reached\n"); 28 | return (" died\n"); 29 | } 30 | 31 | void 32 | display_message(t_philo *philo, int type) 33 | { 34 | sem_wait(philo->state->write_m); 35 | sem_wait(philo->state->dead_write_m); 36 | ft_putnbr_fd(get_time() - philo->state->start, 1); 37 | write(1, "\t", 1); 38 | if (type != TYPE_OVER) 39 | ft_putnbr_fd(philo->position + 1, 1); 40 | write(1, get_message(type), ft_strlen(get_message(type))); 41 | if (type < TYPE_DIED) 42 | sem_post(philo->state->dead_write_m); 43 | sem_post(philo->state->write_m); 44 | } 45 | -------------------------------------------------------------------------------- /philo_one/messages.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* messages.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 18:31:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 14:08:39 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static char 16 | *get_message(int type) 17 | { 18 | if (type == TYPE_EAT) 19 | return (" is eating\n"); 20 | else if (type == TYPE_SLEEP) 21 | return (" is sleeping\n"); 22 | else if (type == TYPE_FORK) 23 | return (" has taken a fork\n"); 24 | else if (type == TYPE_THINK) 25 | return (" is thinking\n"); 26 | else if (type == TYPE_OVER) 27 | return ("must eat count reached\n"); 28 | return (" died\n"); 29 | } 30 | 31 | void 32 | display_message(t_philo *philo, int type) 33 | { 34 | static int done = 0; 35 | 36 | pthread_mutex_lock(&philo->state->write_m); 37 | if (!done) 38 | { 39 | ft_putnbr_fd(get_time() - philo->state->start, 1); 40 | write(1, "\t", 1); 41 | if (type != TYPE_OVER) 42 | ft_putnbr_fd(philo->position + 1, 1); 43 | if (type >= TYPE_DIED) 44 | done = 1; 45 | write(1, get_message(type), ft_strlen(get_message(type))); 46 | } 47 | pthread_mutex_unlock(&philo->state->write_m); 48 | } 49 | -------------------------------------------------------------------------------- /philo_two/messages.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* messages.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 18:31:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 20:47:19 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static char 16 | *get_message(int type) 17 | { 18 | if (type == TYPE_EAT) 19 | return (" is eating\n"); 20 | else if (type == TYPE_SLEEP) 21 | return (" is sleeping\n"); 22 | else if (type == TYPE_FORK) 23 | return (" has taken a fork\n"); 24 | else if (type == TYPE_THINK) 25 | return (" is thinking\n"); 26 | else if (type == TYPE_OVER) 27 | return ("must eat count reached\n"); 28 | return (" died\n"); 29 | } 30 | 31 | int 32 | display_message(t_philo *philo, int type) 33 | { 34 | static int done = 0; 35 | int ret; 36 | 37 | if (sem_wait(philo->state->write_m) != 0) 38 | return (1); 39 | ret = 1; 40 | if (!done) 41 | { 42 | ft_putnbr_fd(get_time() - philo->state->start, 1); 43 | write(1, "\t", 1); 44 | if (type != TYPE_OVER) 45 | ft_putnbr_fd(philo->position + 1, 1); 46 | if (type >= TYPE_DIED) 47 | done = 1; 48 | write(1, get_message(type), ft_strlen(get_message(type))); 49 | ret = 0; 50 | } 51 | if (sem_post(philo->state->write_m)) 52 | return (1); 53 | return (ret); 54 | } 55 | -------------------------------------------------------------------------------- /philo_three/monitor.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* monitor.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/13 16:08:16 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 16:08:39 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | void 16 | *monitor_count(void *state_v) 17 | { 18 | t_state *state; 19 | int total; 20 | int i; 21 | 22 | state = (t_state*)state_v; 23 | total = 0; 24 | while (total < state->must_eat_count) 25 | { 26 | i = 0; 27 | while (i < state->amount) 28 | sem_wait(state->philos[i++].eat_count_m); 29 | total++; 30 | } 31 | display_message(&state->philos[0], TYPE_OVER); 32 | sem_post(state->somebody_dead_m); 33 | return ((void*)0); 34 | } 35 | 36 | void 37 | *monitor(void *philo_v) 38 | { 39 | t_philo *philo; 40 | 41 | philo = (t_philo*)philo_v; 42 | while (1) 43 | { 44 | sem_wait(philo->mutex); 45 | if (!philo->is_eating && get_time() > philo->limit) 46 | { 47 | display_message(philo, TYPE_DIED); 48 | sem_post(philo->mutex); 49 | sem_post(philo->state->somebody_dead_m); 50 | return ((void*)0); 51 | } 52 | sem_post(philo->mutex); 53 | usleep(1000); 54 | } 55 | return ((void*)0); 56 | } 57 | 58 | int 59 | start_monitor_thread(t_state *state) 60 | { 61 | pthread_t tid; 62 | 63 | if (state->must_eat_count > 0) 64 | { 65 | if (pthread_create(&tid, NULL, &monitor_count, (void*)state) != 0) 66 | return (1); 67 | pthread_detach(tid); 68 | } 69 | return (0); 70 | } 71 | -------------------------------------------------------------------------------- /philo_one/utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:45 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/12 23:24:10 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | ft_strlen(char const *str) 17 | { 18 | int i; 19 | 20 | i = 0; 21 | while (str[i]) 22 | i++; 23 | return (i); 24 | } 25 | 26 | int 27 | ft_atoi(char const *str) 28 | { 29 | int i; 30 | int start; 31 | int is_neg; 32 | int res; 33 | 34 | if (!str) 35 | return (0); 36 | i = 0; 37 | while (str[i] == '\t' || str[i] == '\n' || str[i] == '\v' || 38 | str[i] == '\f' || str[i] == '\r' || str[i] == ' ') 39 | i++; 40 | is_neg = (str[i] == '-') ? -1 : 1; 41 | if (is_neg == -1 || str[i] == '+') 42 | i++; 43 | start = i; 44 | res = 0; 45 | while (str[i] >= '0' && str[i] <= '9') 46 | res = (res * 10) + (str[i++] - '0'); 47 | return (res * is_neg); 48 | } 49 | 50 | void 51 | ft_putnbr_fd(uint64_t n, int fd) 52 | { 53 | char str[13]; 54 | int length; 55 | 56 | if (n == 0) 57 | str[0] = '0'; 58 | length = 0; 59 | while (n != 0) 60 | { 61 | str[length++] = '0' + (n % 10); 62 | n = (n / 10); 63 | } 64 | if (length > 0) 65 | length--; 66 | while (length >= 0) 67 | write(fd, &str[length--], 1); 68 | } 69 | 70 | uint64_t 71 | get_time(void) 72 | { 73 | static struct timeval tv; 74 | 75 | gettimeofday(&tv, NULL); 76 | return ((tv.tv_sec * (uint64_t)1000) + (tv.tv_usec / 1000)); 77 | } 78 | -------------------------------------------------------------------------------- /philo_three/utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:45 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/12 23:27:06 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | ft_strlen(char const *str) 17 | { 18 | int i; 19 | 20 | i = 0; 21 | while (str[i]) 22 | i++; 23 | return (i); 24 | } 25 | 26 | int 27 | ft_atoi(char const *str) 28 | { 29 | int i; 30 | int start; 31 | int is_neg; 32 | int res; 33 | 34 | if (!str) 35 | return (0); 36 | i = 0; 37 | while (str[i] == '\t' || str[i] == '\n' || str[i] == '\v' || 38 | str[i] == '\f' || str[i] == '\r' || str[i] == ' ') 39 | i++; 40 | is_neg = (str[i] == '-') ? -1 : 1; 41 | if (is_neg == -1 || str[i] == '+') 42 | i++; 43 | start = i; 44 | res = 0; 45 | while (str[i] >= '0' && str[i] <= '9') 46 | res = (res * 10) + (str[i++] - '0'); 47 | return (res * is_neg); 48 | } 49 | 50 | void 51 | ft_putnbr_fd(uint64_t n, int fd) 52 | { 53 | char str[13]; 54 | int length; 55 | 56 | if (n == 0) 57 | str[0] = '0'; 58 | length = 0; 59 | while (n != 0) 60 | { 61 | str[length++] = '0' + (n % 10); 62 | n = (n / 10); 63 | } 64 | if (length > 0) 65 | length--; 66 | while (length >= 0) 67 | write(fd, &str[length--], 1); 68 | } 69 | 70 | int 71 | ft_strcpy(char *dst, const char *src) 72 | { 73 | int i; 74 | 75 | i = 0; 76 | while (src[i]) 77 | { 78 | dst[i] = src[i]; 79 | i++; 80 | } 81 | dst[i] = 0; 82 | return (i); 83 | } 84 | 85 | uint64_t 86 | get_time(void) 87 | { 88 | static struct timeval tv; 89 | 90 | gettimeofday(&tv, NULL); 91 | return ((tv.tv_sec * (uint64_t)1000) + (tv.tv_usec / 1000)); 92 | } 93 | -------------------------------------------------------------------------------- /philo_two/utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:45 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/12 23:27:06 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | int 16 | ft_strlen(char const *str) 17 | { 18 | int i; 19 | 20 | i = 0; 21 | while (str[i]) 22 | i++; 23 | return (i); 24 | } 25 | 26 | int 27 | ft_atoi(char const *str) 28 | { 29 | int i; 30 | int start; 31 | int is_neg; 32 | int res; 33 | 34 | if (!str) 35 | return (0); 36 | i = 0; 37 | while (str[i] == '\t' || str[i] == '\n' || str[i] == '\v' || 38 | str[i] == '\f' || str[i] == '\r' || str[i] == ' ') 39 | i++; 40 | is_neg = (str[i] == '-') ? -1 : 1; 41 | if (is_neg == -1 || str[i] == '+') 42 | i++; 43 | start = i; 44 | res = 0; 45 | while (str[i] >= '0' && str[i] <= '9') 46 | res = (res * 10) + (str[i++] - '0'); 47 | return (res * is_neg); 48 | } 49 | 50 | void 51 | ft_putnbr_fd(uint64_t n, int fd) 52 | { 53 | char str[13]; 54 | int length; 55 | 56 | if (n == 0) 57 | str[0] = '0'; 58 | length = 0; 59 | while (n != 0) 60 | { 61 | str[length++] = '0' + (n % 10); 62 | n = (n / 10); 63 | } 64 | if (length > 0) 65 | length--; 66 | while (length >= 0) 67 | write(fd, &str[length--], 1); 68 | } 69 | 70 | int 71 | ft_strcpy(char *dst, const char *src) 72 | { 73 | int i; 74 | 75 | i = 0; 76 | while (src[i]) 77 | { 78 | dst[i] = src[i]; 79 | i++; 80 | } 81 | dst[i] = 0; 82 | return (i); 83 | } 84 | 85 | uint64_t 86 | get_time(void) 87 | { 88 | static struct timeval tv; 89 | 90 | gettimeofday(&tv, NULL); 91 | return ((tv.tv_sec * (uint64_t)1000) + (tv.tv_usec / 1000)); 92 | } 93 | -------------------------------------------------------------------------------- /philo_one/philosophers.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* philosophers.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:07 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:09:38 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef PHILOSOPHERS_H 14 | # define PHILOSOPHERS_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include 20 | 21 | # define TYPE_EAT 0 22 | # define TYPE_SLEEP 1 23 | # define TYPE_FORK 2 24 | # define TYPE_THINK 3 25 | # define TYPE_DIED 4 26 | # define TYPE_OVER 5 27 | 28 | struct s_state; 29 | 30 | typedef struct s_philo 31 | { 32 | int position; 33 | int is_eating; 34 | uint64_t limit; 35 | uint64_t last_eat; 36 | int lfork; 37 | int rfork; 38 | int eat_count; 39 | struct s_state *state; 40 | pthread_mutex_t mutex; 41 | pthread_mutex_t eat_m; 42 | } t_philo; 43 | 44 | typedef struct s_state 45 | { 46 | int amount; 47 | uint64_t time_to_die; 48 | uint64_t time_to_eat; 49 | uint64_t time_to_sleep; 50 | int must_eat_count; 51 | 52 | uint64_t start; 53 | 54 | t_philo *philos; 55 | pthread_mutex_t *forks_m; 56 | pthread_mutex_t write_m; 57 | pthread_mutex_t somebody_dead_m; 58 | } t_state; 59 | 60 | int ft_strlen(char const *str); 61 | 62 | int ft_atoi(char const *str); 63 | 64 | void ft_putnbr_fd(uint64_t n, int fd); 65 | 66 | uint64_t get_time(void); 67 | 68 | int clear_state(t_state *state); 69 | 70 | int exit_error(char const *str); 71 | 72 | int init(t_state *state, int argc, char const **argv); 73 | 74 | void take_forks(t_philo *philo); 75 | 76 | void clean_forks(t_philo *philo); 77 | 78 | void eat(t_philo *philo); 79 | 80 | void display_message(t_philo *philo, int type); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /philo_three/main.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/09 15:30:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:12:30 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static int 16 | routine(t_philo *philo_v) 17 | { 18 | t_philo *philo; 19 | pthread_t tid; 20 | 21 | philo = (t_philo*)philo_v; 22 | philo->last_eat = get_time(); 23 | philo->limit = philo->last_eat + philo->state->time_to_die; 24 | if (pthread_create(&tid, NULL, &monitor, philo) != 0) 25 | return (1); 26 | pthread_detach(tid); 27 | while (1) 28 | { 29 | take_forks(philo); 30 | eat(philo); 31 | clean_forks(philo); 32 | display_message(philo, TYPE_THINK); 33 | } 34 | return (0); 35 | } 36 | 37 | static int 38 | start_process(t_state *state) 39 | { 40 | int i; 41 | void *philo; 42 | 43 | state->start = get_time(); 44 | i = 0; 45 | while (i < state->amount) 46 | { 47 | philo = (void*)(&state->philos[i]); 48 | state->philos[i].pid = fork(); 49 | if (state->philos[i].pid < 0) 50 | return (1); 51 | else if (state->philos[i].pid == 0) 52 | { 53 | routine(&state->philos[i]); 54 | exit(0); 55 | } 56 | usleep(100); 57 | i++; 58 | } 59 | return (0); 60 | } 61 | 62 | int 63 | main(int argc, char const **argv) 64 | { 65 | int i; 66 | t_state state; 67 | 68 | if (argc < 5 || argc > 6) 69 | return (exit_error("error: bad arguments\n")); 70 | if (init(&state, argc, argv) 71 | || start_monitor_thread(&state) 72 | || start_process(&state)) 73 | return (clear_state(&state) && exit_error("error: fatal\n")); 74 | sem_wait(state.somebody_dead_m); 75 | i = 0; 76 | while (i < state.amount) 77 | kill(state.philos[i++].pid, SIGKILL); 78 | clear_state(&state); 79 | return (0); 80 | } 81 | -------------------------------------------------------------------------------- /philo_one/init.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* init.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 19:26:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:14:29 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static int 16 | init_mutexes(t_state *state) 17 | { 18 | int i; 19 | 20 | pthread_mutex_init(&state->write_m, NULL); 21 | pthread_mutex_init(&state->somebody_dead_m, NULL); 22 | pthread_mutex_lock(&state->somebody_dead_m); 23 | if (!(state->forks_m = 24 | (pthread_mutex_t*)malloc(sizeof(*(state->forks_m)) * state->amount))) 25 | return (1); 26 | i = 0; 27 | while (i < state->amount) 28 | pthread_mutex_init(&state->forks_m[i++], NULL); 29 | return (0); 30 | } 31 | 32 | static void 33 | init_philos(t_state *state) 34 | { 35 | int i; 36 | 37 | i = 0; 38 | while (i < state->amount) 39 | { 40 | state->philos[i].is_eating = 0; 41 | state->philos[i].position = i; 42 | state->philos[i].lfork = i; 43 | state->philos[i].rfork = (i + 1) % state->amount; 44 | state->philos[i].eat_count = 0; 45 | state->philos[i].state = state; 46 | pthread_mutex_init(&state->philos[i].mutex, NULL); 47 | pthread_mutex_init(&state->philos[i].eat_m, NULL); 48 | pthread_mutex_lock(&state->philos[i].eat_m); 49 | i++; 50 | } 51 | } 52 | 53 | int 54 | init(t_state *state, int argc, char const **argv) 55 | { 56 | state->amount = ft_atoi(argv[1]); 57 | state->time_to_die = ft_atoi(argv[2]); 58 | state->time_to_eat = ft_atoi(argv[3]); 59 | state->time_to_sleep = ft_atoi(argv[4]); 60 | if (argc == 6) 61 | state->must_eat_count = ft_atoi(argv[5]); 62 | else 63 | state->must_eat_count = 0; 64 | if (state->amount < 2 || state->amount > 200 || state->time_to_die < 60 65 | || state->time_to_eat < 60 || state->time_to_sleep < 60 66 | || state->must_eat_count < 0) 67 | return (1); 68 | state->forks_m = NULL; 69 | state->philos = NULL; 70 | if (!(state->philos = 71 | (t_philo*)malloc(sizeof(*(state->philos)) * state->amount))) 72 | return (1); 73 | init_philos(state); 74 | return (init_mutexes(state)); 75 | } 76 | -------------------------------------------------------------------------------- /philo_two/init.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* init.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 19:26:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:14:45 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static int 16 | init_semaphores(t_state *state) 17 | { 18 | if ((state->forks_m = ft_sem_open(SEMAPHORE_FORK, state->amount)) < 0 19 | || (state->write_m = ft_sem_open(SEMAPHORE_WRITE, 1)) < 0 20 | || (state->somebody_dead_m = ft_sem_open(SEMAPHORE_DEAD, 0)) < 0) 21 | return (1); 22 | return (0); 23 | } 24 | 25 | static int 26 | init_philos(t_state *state) 27 | { 28 | int i; 29 | char semaphore[250]; 30 | 31 | i = 0; 32 | while (i < state->amount) 33 | { 34 | state->philos[i].is_eating = 0; 35 | state->philos[i].position = i; 36 | state->philos[i].lfork = i; 37 | state->philos[i].rfork = (i + 1) % state->amount; 38 | state->philos[i].eat_count = 0; 39 | state->philos[i].state = state; 40 | make_semaphore_name(SEMAPHORE_PHILO, (char*)semaphore, i); 41 | if ((state->philos[i].mutex = ft_sem_open(semaphore, 1)) < 0) 42 | return (1); 43 | make_semaphore_name(SEMAPHORE_PHILOEAT, (char*)semaphore, i); 44 | if ((state->philos[i].eat_count_m = ft_sem_open(semaphore, 0)) < 0) 45 | return (1); 46 | i++; 47 | } 48 | return (0); 49 | } 50 | 51 | int 52 | init(t_state *state, int argc, char const **argv) 53 | { 54 | state->amount = ft_atoi(argv[1]); 55 | state->time_to_die = ft_atoi(argv[2]); 56 | state->time_to_eat = ft_atoi(argv[3]); 57 | state->time_to_sleep = ft_atoi(argv[4]); 58 | if (argc == 6) 59 | state->must_eat_count = ft_atoi(argv[5]); 60 | else 61 | state->must_eat_count = 0; 62 | if (state->amount < 2 || state->amount > 200 || state->time_to_die < 60 63 | || state->time_to_eat < 60 || state->time_to_sleep < 60 64 | || state->must_eat_count < 0) 65 | return (1); 66 | state->forks_m = NULL; 67 | state->philos = NULL; 68 | state->cur_eat_count = 0; 69 | if (!(state->philos = 70 | (t_philo*)malloc(sizeof(*(state->philos)) * state->amount))) 71 | return (1); 72 | if (init_philos(state)) 73 | return (1); 74 | return (init_semaphores(state)); 75 | } 76 | -------------------------------------------------------------------------------- /philo_two/philosophers.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* philosophers.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:07 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:07:56 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef PHILOSOPHERS_H 14 | # define PHILOSOPHERS_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include 20 | # include 21 | 22 | # define SEMAPHORE_FORK "pSemaphoreFork" 23 | # define SEMAPHORE_WRITE "pSemaphoreWrite" 24 | # define SEMAPHORE_DEAD "pSemaphoreDead" 25 | # define SEMAPHORE_PHILO "pSemaphorePhilo" 26 | # define SEMAPHORE_PHILOEAT "pSemaphorePhiloEat" 27 | 28 | # define TYPE_EAT 0 29 | # define TYPE_SLEEP 1 30 | # define TYPE_FORK 2 31 | # define TYPE_THINK 3 32 | # define TYPE_DIED 4 33 | # define TYPE_OVER 5 34 | 35 | struct s_state; 36 | 37 | typedef struct s_philo 38 | { 39 | int position; 40 | int is_eating; 41 | uint64_t limit; 42 | uint64_t last_eat; 43 | int lfork; 44 | int rfork; 45 | struct s_state *state; 46 | int eat_count; 47 | sem_t *mutex; 48 | sem_t *eat_count_m; 49 | } t_philo; 50 | 51 | typedef struct s_state 52 | { 53 | int amount; 54 | uint64_t time_to_die; 55 | uint64_t time_to_eat; 56 | uint64_t time_to_sleep; 57 | int must_eat_count; 58 | int cur_eat_count; 59 | 60 | uint64_t start; 61 | int over; 62 | 63 | t_philo *philos; 64 | sem_t *forks_m; 65 | sem_t *write_m; 66 | sem_t *somebody_dead_m; 67 | } t_state; 68 | 69 | int ft_strlen(char const *str); 70 | 71 | int ft_atoi(char const *str); 72 | 73 | void ft_putnbr_fd(uint64_t n, int fd); 74 | 75 | int ft_strcpy(char *dst, const char *src); 76 | 77 | uint64_t get_time(void); 78 | 79 | int clear_state(t_state *state); 80 | 81 | int exit_error(char const *str); 82 | 83 | int init(t_state *state, int argc, char const **argv); 84 | 85 | sem_t *ft_sem_open(char const *name, int value); 86 | 87 | char *make_semaphore_name(char const *base, 88 | char *buffer, int position); 89 | 90 | int take_forks(t_philo *philo); 91 | 92 | int clean_forks(t_philo *philo); 93 | 94 | int eat(t_philo *philo); 95 | 96 | int display_message(t_philo *philo, int type); 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /philo_three/init.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* init.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 19:26:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:14:40 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static int 16 | init_semaphores(t_state *state) 17 | { 18 | sem_unlink(SEMAPHORE_FORK); 19 | sem_unlink(SEMAPHORE_WRITE); 20 | sem_unlink(SEMAPHORE_DEAD); 21 | sem_unlink(SEMAPHORE_DEADW); 22 | if ((state->forks_m = ft_sem_open(SEMAPHORE_FORK, state->amount)) < 0 23 | || (state->write_m = ft_sem_open(SEMAPHORE_WRITE, 1)) < 0 24 | || (state->somebody_dead_m = ft_sem_open(SEMAPHORE_DEAD, 0)) < 0 25 | || (state->dead_write_m = ft_sem_open(SEMAPHORE_DEADW, 1)) < 0) 26 | return (1); 27 | return (0); 28 | } 29 | 30 | static int 31 | init_philos(t_state *state) 32 | { 33 | int i; 34 | char semaphore[250]; 35 | 36 | i = 0; 37 | while (i < state->amount) 38 | { 39 | state->philos[i].is_eating = 0; 40 | state->philos[i].position = i; 41 | state->philos[i].lfork = i; 42 | state->philos[i].rfork = (i + 1) % state->amount; 43 | state->philos[i].state = state; 44 | make_semaphore_name(SEMAPHORE_PHILO, (char*)semaphore, i); 45 | sem_unlink(semaphore); 46 | if ((state->philos[i].mutex = ft_sem_open(semaphore, 1)) < 0) 47 | return (1); 48 | make_semaphore_name(SEMAPHORE_PHILOEAT, (char*)semaphore, i); 49 | sem_unlink(semaphore); 50 | if ((state->philos[i].eat_count_m = ft_sem_open(semaphore, 0)) < 0) 51 | return (1); 52 | i++; 53 | } 54 | return (0); 55 | } 56 | 57 | int 58 | init(t_state *state, int argc, char const **argv) 59 | { 60 | state->amount = ft_atoi(argv[1]); 61 | state->time_to_die = ft_atoi(argv[2]); 62 | state->time_to_eat = ft_atoi(argv[3]); 63 | state->time_to_sleep = ft_atoi(argv[4]); 64 | if (argc == 6) 65 | state->must_eat_count = ft_atoi(argv[5]); 66 | else 67 | state->must_eat_count = 0; 68 | if (state->amount < 2 || state->amount > 200 || state->time_to_die < 60 69 | || state->time_to_eat < 60 || state->time_to_sleep < 60 70 | || state->must_eat_count < 0) 71 | return (1); 72 | state->forks_m = NULL; 73 | state->philos = NULL; 74 | if (!(state->philos = 75 | (t_philo*)malloc(sizeof(*(state->philos)) * state->amount))) 76 | return (1); 77 | if (init_philos(state)) 78 | return (1); 79 | return (init_semaphores(state)); 80 | } 81 | -------------------------------------------------------------------------------- /philo_three/philosophers.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* philosophers.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/10 12:40:07 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 18:32:04 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef PHILOSOPHERS_H 14 | # define PHILOSOPHERS_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include 20 | # include 21 | # include 22 | 23 | # define SEMAPHORE_FORK "pSemaphoreFork" 24 | # define SEMAPHORE_WRITE "pSemaphoreWrite" 25 | # define SEMAPHORE_DEAD "pSemaphoreDead" 26 | # define SEMAPHORE_DEADW "pSemaphoreDeadWrite" 27 | # define SEMAPHORE_PHILO "pSemaphorePhilo" 28 | # define SEMAPHORE_PHILOEAT "pSemaphorePhiloEat" 29 | 30 | # define TYPE_EAT 0 31 | # define TYPE_SLEEP 1 32 | # define TYPE_FORK 2 33 | # define TYPE_THINK 3 34 | # define TYPE_DIED 4 35 | # define TYPE_OVER 5 36 | 37 | struct s_state; 38 | 39 | typedef struct s_philo 40 | { 41 | pid_t pid; 42 | int position; 43 | int is_eating; 44 | uint64_t limit; 45 | uint64_t last_eat; 46 | int lfork; 47 | int rfork; 48 | struct s_state *state; 49 | int eat_count; 50 | sem_t *mutex; 51 | sem_t *eat_count_m; 52 | } t_philo; 53 | 54 | typedef struct s_state 55 | { 56 | int amount; 57 | uint64_t time_to_die; 58 | uint64_t time_to_eat; 59 | uint64_t time_to_sleep; 60 | int must_eat_count; 61 | 62 | uint64_t start; 63 | 64 | t_philo *philos; 65 | sem_t *forks_m; 66 | sem_t *write_m; 67 | sem_t *somebody_dead_m; 68 | sem_t *dead_write_m; 69 | } t_state; 70 | 71 | int ft_strlen(char const *str); 72 | 73 | int ft_atoi(char const *str); 74 | 75 | void ft_putnbr_fd(uint64_t n, int fd); 76 | 77 | int ft_strcpy(char *dst, const char *src); 78 | 79 | uint64_t get_time(void); 80 | 81 | int clear_state(t_state *state); 82 | 83 | int exit_error(char const *str); 84 | 85 | int init(t_state *state, int argc, char const **argv); 86 | 87 | sem_t *ft_sem_open(char const *name, int value); 88 | 89 | char *make_semaphore_name(char const *base, 90 | char *buffer, int position); 91 | 92 | void *monitor_count(void *state_v); 93 | 94 | void *monitor(void *philo_v); 95 | 96 | int start_monitor_thread(t_state *state); 97 | 98 | void take_forks(t_philo *philo); 99 | 100 | void clean_forks(t_philo *philo); 101 | 102 | void eat(t_philo *philo); 103 | 104 | void display_message(t_philo *philo, int type); 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /philo_one/main.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/09 15:30:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/13 15:12:06 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "philosophers.h" 14 | 15 | static void 16 | *monitor_count(void *state_v) 17 | { 18 | t_state *state; 19 | int i; 20 | int total; 21 | 22 | state = (t_state*)state_v; 23 | total = 0; 24 | while (total < state->must_eat_count) 25 | { 26 | i = 0; 27 | while (i < state->amount) 28 | pthread_mutex_lock(&state->philos[i++].eat_m); 29 | total++; 30 | } 31 | display_message(&state->philos[0], TYPE_OVER); 32 | pthread_mutex_unlock(&state->somebody_dead_m); 33 | return ((void*)0); 34 | } 35 | 36 | static void 37 | *monitor(void *philo_v) 38 | { 39 | t_philo *philo; 40 | 41 | philo = (t_philo*)philo_v; 42 | while (1) 43 | { 44 | pthread_mutex_lock(&philo->mutex); 45 | if (!philo->is_eating && get_time() > philo->limit) 46 | { 47 | display_message(philo, TYPE_DIED); 48 | pthread_mutex_unlock(&philo->mutex); 49 | pthread_mutex_unlock(&philo->state->somebody_dead_m); 50 | return ((void*)0); 51 | } 52 | pthread_mutex_unlock(&philo->mutex); 53 | usleep(1000); 54 | } 55 | } 56 | 57 | static void 58 | *routine(void *philo_v) 59 | { 60 | t_philo *philo; 61 | pthread_t tid; 62 | 63 | philo = (t_philo*)philo_v; 64 | philo->last_eat = get_time(); 65 | philo->limit = philo->last_eat + philo->state->time_to_die; 66 | if (pthread_create(&tid, NULL, &monitor, philo_v) != 0) 67 | return ((void*)1); 68 | pthread_detach(tid); 69 | while (1) 70 | { 71 | take_forks(philo); 72 | eat(philo); 73 | clean_forks(philo); 74 | display_message(philo, TYPE_THINK); 75 | } 76 | return ((void*)0); 77 | } 78 | 79 | static int 80 | start_threads(t_state *state) 81 | { 82 | int i; 83 | pthread_t tid; 84 | void *philo; 85 | 86 | state->start = get_time(); 87 | if (state->must_eat_count > 0) 88 | { 89 | if (pthread_create(&tid, NULL, &monitor_count, (void*)state) != 0) 90 | return (1); 91 | pthread_detach(tid); 92 | } 93 | i = 0; 94 | while (i < state->amount) 95 | { 96 | philo = (void*)(&state->philos[i]); 97 | if (pthread_create(&tid, NULL, &routine, philo) != 0) 98 | return (1); 99 | pthread_detach(tid); 100 | usleep(100); 101 | i++; 102 | } 103 | return (0); 104 | } 105 | 106 | int 107 | main(int argc, char const **argv) 108 | { 109 | t_state state; 110 | 111 | if (argc < 5 || argc > 6) 112 | return (exit_error("error: bad arguments\n")); 113 | if (init(&state, argc, argv)) 114 | return (clear_state(&state) && exit_error("error: fatal\n")); 115 | if (start_threads(&state)) 116 | return (clear_state(&state) && exit_error("error: fatal\n")); 117 | pthread_mutex_lock(&state.somebody_dead_m); 118 | pthread_mutex_unlock(&state.somebody_dead_m); 119 | clear_state(&state); 120 | return (0); 121 | } 122 | -------------------------------------------------------------------------------- /philo_two/main.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ncolomer +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/09 15:30:46 by ncolomer #+# #+# */ 9 | /* Updated: 2019/12/19 21:44:50 by ncolomer ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "philosophers.h" 15 | 16 | static void 17 | *monitor_count(void *state_v) 18 | { 19 | t_state *state; 20 | int i; 21 | 22 | state = (t_state*)state_v; 23 | while (state->cur_eat_count < state->must_eat_count) 24 | { 25 | i = 0; 26 | while (i < state->amount) 27 | if (sem_wait(state->philos[i++].eat_count_m)) 28 | return ((void*)0); 29 | state->cur_eat_count++; 30 | } 31 | if (display_message(&state->philos[0], TYPE_OVER)) 32 | return ((void*)0); 33 | if (sem_post(state->somebody_dead_m)) 34 | return ((void*)0); 35 | return ((void*)0); 36 | } 37 | 38 | static void 39 | *monitor(void *philo_v) 40 | { 41 | t_philo *philo; 42 | 43 | philo = (t_philo*)philo_v; 44 | while (1) 45 | { 46 | if (sem_wait(philo->mutex) != 0) 47 | return ((void*)0); 48 | if (!philo->is_eating && get_time() > philo->limit) 49 | { 50 | if (display_message(philo, TYPE_DIED)) 51 | return ((void*)0); 52 | if (sem_post(philo->mutex)) 53 | return ((void*)0); 54 | if (sem_post(philo->state->somebody_dead_m)) 55 | return ((void*)0); 56 | return ((void*)0); 57 | } 58 | if (sem_post(philo->mutex)) 59 | return ((void*)0); 60 | } 61 | return ((void*)0); 62 | } 63 | 64 | static void 65 | *routine(void *philo_v) 66 | { 67 | t_philo *philo; 68 | pthread_t tid; 69 | int should_end; 70 | 71 | philo = (t_philo*)philo_v; 72 | philo->last_eat = get_time(); 73 | philo->limit = philo->last_eat + philo->state->time_to_die; 74 | if (pthread_create(&tid, NULL, &monitor, philo_v) != 0) 75 | return ((void*)1); 76 | pthread_detach(tid); 77 | while (1) 78 | { 79 | if (take_forks(philo)) 80 | return ((void*)0); 81 | should_end = eat(philo); 82 | if (clean_forks(philo)) 83 | return ((void*)0); 84 | if (should_end) 85 | return ((void*)0); 86 | if (display_message(philo, TYPE_THINK)) 87 | return ((void*)0); 88 | } 89 | return ((void*)0); 90 | } 91 | 92 | static int 93 | start_threads(t_state *state) 94 | { 95 | int i; 96 | pthread_t tid; 97 | void *philo; 98 | 99 | if (state->must_eat_count > 0) 100 | { 101 | if (pthread_create(&tid, NULL, &monitor_count, (void*)state) != 0) 102 | return (1); 103 | pthread_detach(tid); 104 | } 105 | state->start = get_time(); 106 | i = 0; 107 | while (i < state->amount) 108 | { 109 | philo = (void*)(&state->philos[i]); 110 | if (pthread_create(&tid, NULL, &routine, philo) != 0) 111 | return (1); 112 | pthread_detach(tid); 113 | usleep(100); 114 | i++; 115 | } 116 | return (0); 117 | } 118 | 119 | int 120 | main(int argc, char const **argv) 121 | { 122 | t_state state; 123 | 124 | if (argc < 5 || argc > 6) 125 | return (exit_error("error: bad arguments\n")); 126 | if (init(&state, argc, argv) 127 | || start_threads(&state)) 128 | return (clear_state(&state) && exit_error("error: fatal\n")); 129 | sem_wait(state.somebody_dead_m); 130 | clear_state(&state); 131 | return (0); 132 | } 133 | --------------------------------------------------------------------------------