narnaud
3 years ago
8 changed files with 290 additions and 272 deletions
@ -1,26 +1,26 @@ |
|||||
NAME = philosophers |
NAME = philo |
||||
|
|
||||
SRCS = philo_threads.c philo_launcher.c philo_utils.c |
SRCS = philo.c philo_init.c philo_life.c philo_utils.c |
||||
OBJS = ${SRCS:.c=.o} |
OBJS = ${SRCS:.c=.o} |
||||
|
|
||||
CC = clang |
CC = clang |
||||
CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT |
CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT |
||||
RM = rm -rf |
RM = rm -rf |
||||
|
|
||||
.c.o: |
%.o : %.c |
||||
$(CC) $(CFLAGS) -c $< -o $(<:.c=.o) |
$(CC) $(CFLAGS) -c $< -o $(<:.c=.o) |
||||
|
|
||||
all: $(NAME) |
all : $(NAME) |
||||
|
|
||||
$(NAME): $(OBJS) |
$(NAME) : $(OBJS) |
||||
${CC} ${CFLAGS} -lpthread ${OBJS} -o ${NAME} |
$(CC) $(CFLAGS) -lpthread $(OBJS) -o $(NAME) |
||||
|
|
||||
clean: |
clean : |
||||
${RM} ${OBJS} |
$(RM) $(OBJS) |
||||
|
|
||||
fclean: clean |
fclean : clean |
||||
${RM} ${NAME} |
$(RM) $(NAME) |
||||
|
|
||||
re: fclean all |
re : fclean all |
||||
|
|
||||
.PHONY: all clean fclean re |
.PHONY : all clean fclean re |
||||
|
@ -0,0 +1,88 @@ |
|||||
|
/* ************************************************************************** */ |
||||
|
/* */ |
||||
|
/* ::: :::::::: */ |
||||
|
/* philo.c :+: :+: :+: */ |
||||
|
/* +:+ +:+ +:+ */ |
||||
|
/* By: narnaud@student.42nice.fr <marvin@42.fr> +#+ +:+ +#+ */ |
||||
|
/* +#+#+#+#+#+ +#+ */ |
||||
|
/* Created: 2022/05/19 00:36:57 by narnaud@stude #+# #+# */ |
||||
|
/* Updated: 2022/05/19 00:47:15 by narnaud@stude ### ########.fr */ |
||||
|
/* */ |
||||
|
/* ************************************************************************** */ |
||||
|
|
||||
|
#include "philo.h" |
||||
|
|
||||
|
static int waiter(t_room *room, t_philo *philo); |
||||
|
static int clean_memory(t_room *room, t_philo *philos); |
||||
|
|
||||
|
int main(int argc, char **argv) |
||||
|
{ |
||||
|
t_room *room; |
||||
|
t_philo *philos; |
||||
|
|
||||
|
if (argc < 5 || argc > 6) |
||||
|
return (EXIT_FAILURE); |
||||
|
room = create_room(argv + 1); |
||||
|
philos = create_philos(room); |
||||
|
invit_philos(philos); |
||||
|
while (waiter(room, philos)) |
||||
|
usleep(1000); |
||||
|
pthread_mutex_lock(room->lock); |
||||
|
room->running = 0; |
||||
|
pthread_mutex_unlock(room->lock); |
||||
|
sleep(2); |
||||
|
return (clean_memory(room, philos)); |
||||
|
} |
||||
|
|
||||
|
static int waiter(t_room *room, t_philo *philo) |
||||
|
{ |
||||
|
int starvest; |
||||
|
int ret; |
||||
|
|
||||
|
ret = 1; |
||||
|
pthread_mutex_lock(room->lock); |
||||
|
starvest = room->param[MEALS_AMOUNT]; |
||||
|
while (ret && philo->id >= 0) |
||||
|
{ |
||||
|
pthread_mutex_lock(philo->lock); |
||||
|
if (philo->eat_time + room->param[DIE_TIME] < room_clock()) |
||||
|
{ |
||||
|
safe_print(philo, "%d %d died\n"); |
||||
|
ret = 0; |
||||
|
} |
||||
|
if (philo->eat_amount < starvest) |
||||
|
starvest = philo->eat_amount; |
||||
|
pthread_mutex_unlock(philo->lock); |
||||
|
philo++; |
||||
|
} |
||||
|
pthread_mutex_unlock(room->lock); |
||||
|
if (starvest == room->param[MEALS_AMOUNT]) |
||||
|
ret = 0; |
||||
|
return (ret); |
||||
|
} |
||||
|
|
||||
|
static int clean_memory(t_room *room, t_philo *philos) |
||||
|
{ |
||||
|
static int i = 0; |
||||
|
|
||||
|
pthread_mutex_lock(room->lock); |
||||
|
while (i < room->param[PHILO_AMOUNT]) |
||||
|
{ |
||||
|
pthread_mutex_lock(philos[i].lock); |
||||
|
pthread_mutex_unlock(philos[i].lock); |
||||
|
pthread_mutex_destroy(philos[i].lock); |
||||
|
pthread_mutex_lock(philos[i].fork); |
||||
|
pthread_mutex_unlock(philos[i].fork); |
||||
|
pthread_mutex_destroy(philos[i].fork); |
||||
|
free(philos[i].lock); |
||||
|
free(philos[i].thd); |
||||
|
i++; |
||||
|
} |
||||
|
pthread_mutex_unlock(room->lock); |
||||
|
pthread_mutex_destroy(room->lock); |
||||
|
free(room->lock); |
||||
|
free(room->forks); |
||||
|
free(philos); |
||||
|
free(room); |
||||
|
return (0); |
||||
|
} |
@ -0,0 +1,82 @@ |
|||||
|
/* ************************************************************************** */ |
||||
|
/* */ |
||||
|
/* ::: :::::::: */ |
||||
|
/* philo_init.c :+: :+: :+: */ |
||||
|
/* +:+ +:+ +:+ */ |
||||
|
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
||||
|
/* +#+#+#+#+#+ +#+ */ |
||||
|
/* Created: 2021/11/24 15:44:04 by narnaud #+# #+# */ |
||||
|
/* Updated: 2022/05/19 00:47:38 by narnaud@stude ### ########.fr */ |
||||
|
/* */ |
||||
|
/* ************************************************************************** */ |
||||
|
|
||||
|
#include "philo.h" |
||||
|
|
||||
|
t_room *create_room(char **argv) |
||||
|
{ |
||||
|
t_room *room; |
||||
|
|
||||
|
room = malloc(sizeof(t_room)); |
||||
|
room->param[PHILO_AMOUNT] = mini_atoi(argv[0]); |
||||
|
room->param[DIE_TIME] = mini_atoi(argv[1]); |
||||
|
room->param[EAT_DURATION] = mini_atoi(argv[2]); |
||||
|
room->param[SLEEP_DURATION] = mini_atoi(argv[3]); |
||||
|
if (argv[4]) |
||||
|
room->param[MEALS_AMOUNT] = mini_atoi(argv[4]); |
||||
|
else |
||||
|
room->param[MEALS_AMOUNT] = 2147483647; |
||||
|
room->lock = malloc(sizeof(pthread_mutex_t)); |
||||
|
room->forks = (pthread_mutex_t *)malloc( |
||||
|
(room->param[PHILO_AMOUNT]) * sizeof(pthread_mutex_t)); |
||||
|
pthread_mutex_init(room->lock, NULL); |
||||
|
room->running = 1; |
||||
|
return (room); |
||||
|
} |
||||
|
|
||||
|
t_philo *create_philos(t_room *room) |
||||
|
{ |
||||
|
t_philo *ret; |
||||
|
static int i; |
||||
|
|
||||
|
ret = (t_philo *)malloc((room->param[PHILO_AMOUNT] + 1) * sizeof(t_philo)); |
||||
|
while (i < room->param[PHILO_AMOUNT]) |
||||
|
{ |
||||
|
ret[i].fork = &room->forks[i]; |
||||
|
ret[i].fork_r = &room->forks[(i + 1) % room->param[PHILO_AMOUNT]]; |
||||
|
ret[i].lock = malloc(sizeof(pthread_mutex_t)); |
||||
|
ret[i].thd = malloc(sizeof(pthread_t)); |
||||
|
ret[i].room = room; |
||||
|
ret[i].eat_time = room_clock(); |
||||
|
ret[i].eat_amount = 0; |
||||
|
ret[i].id = i; |
||||
|
pthread_mutex_init(ret[i].fork, NULL); |
||||
|
pthread_mutex_init(ret[i++].lock, NULL); |
||||
|
} |
||||
|
ret[i].id = -1; |
||||
|
return (ret); |
||||
|
} |
||||
|
|
||||
|
void invit_philos(t_philo *philos) |
||||
|
{ |
||||
|
static int i; |
||||
|
t_room *room; |
||||
|
t_philo *philo; |
||||
|
|
||||
|
philo = philos; |
||||
|
room = philo->room; |
||||
|
while (i >= 0) |
||||
|
{ |
||||
|
pthread_create(philo->thd, NULL, philos_life, (void *)philo); |
||||
|
pthread_detach(*philo->thd); |
||||
|
usleep(100); |
||||
|
if ((i % 2) == 0) |
||||
|
{ |
||||
|
i += 2; |
||||
|
if (i >= room->param[PHILO_AMOUNT]) |
||||
|
i -= 1 + (room->param[PHILO_AMOUNT] % 2) * 2; |
||||
|
} |
||||
|
else if ((i % 2) == 1) |
||||
|
i -= 2; |
||||
|
philo = philos + i; |
||||
|
} |
||||
|
} |
@ -1,120 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* philo_launcher.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2021/11/24 15:44:04 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/05/18 19:27:01 by narnaud@stude ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "philosophers.h" |
|
||||
|
|
||||
void init_param(t_room *room, char **argv); |
|
||||
static t_room *init_room(char **argv); |
|
||||
static int clean_memory(t_room *room); |
|
||||
|
|
||||
int main(int argc, char **argv) |
|
||||
{ |
|
||||
t_room *room; |
|
||||
|
|
||||
if (argc < 5 || argc > 6) |
|
||||
return (1); |
|
||||
room = init_room(argv + 1); |
|
||||
while (room->i >= 0) |
|
||||
{ |
|
||||
pthread_create(room->philos[room->i]->thd, NULL, \ |
|
||||
philos_birth, (void *)room); |
|
||||
pthread_detach(*room->philos[room->i]->thd); |
|
||||
usleep(100); |
|
||||
pthread_mutex_lock(room->lock); |
|
||||
if ((room->i % 2) == 0) |
|
||||
{ |
|
||||
room->i += 2; |
|
||||
if (room->i >= room->param[PHILO_AMOUNT]) |
|
||||
room->i -= 1 + (room->param[PHILO_AMOUNT] % 2) * 2; |
|
||||
} |
|
||||
else if ((room->i % 2) == 1) |
|
||||
room->i -= 2; |
|
||||
pthread_mutex_unlock(room->lock); |
|
||||
} |
|
||||
while (waiter(room)) |
|
||||
usleep(CLOCK_TWO); |
|
||||
pthread_mutex_lock(room->lock); |
|
||||
room->running = 0; |
|
||||
pthread_mutex_unlock(room->lock); |
|
||||
sleep(2); |
|
||||
return (clean_memory(room)); |
|
||||
} |
|
||||
|
|
||||
void init_param(t_room *room, char **argv) |
|
||||
{ |
|
||||
room->param[PHILO_AMOUNT] = mini_atoi(argv[0]); |
|
||||
room->param[DIE_TIME] = mini_atoi(argv[1]); |
|
||||
room->param[EAT_DURATION] = mini_atoi(argv[2]); |
|
||||
room->param[SLEEP_DURATION] = mini_atoi(argv[3]); |
|
||||
if (argv[4]) |
|
||||
room->param[MEALS_AMOUNT] = mini_atoi(argv[4]); |
|
||||
else |
|
||||
room->param[MEALS_AMOUNT] = 2147483647; |
|
||||
} |
|
||||
|
|
||||
static t_room *init_room(char **argv) |
|
||||
{ |
|
||||
t_room *room; |
|
||||
static int i = 0; |
|
||||
|
|
||||
room = malloc(sizeof(t_room)); |
|
||||
init_param(room, argv); |
|
||||
room->lock = malloc(sizeof(pthread_mutex_t)); |
|
||||
pthread_mutex_init(room->lock, NULL); |
|
||||
room->philos = \ |
|
||||
(t_philo **)malloc(room->param[PHILO_AMOUNT] * sizeof(t_philo *)); |
|
||||
room->running = 1; |
|
||||
room->i = 0; |
|
||||
while (i < room->param[PHILO_AMOUNT]) |
|
||||
{ |
|
||||
room->philos[i] = (t_philo *)malloc(sizeof(t_philo)); |
|
||||
room->philos[i]->fork = malloc(sizeof(pthread_mutex_t)); |
|
||||
room->philos[i]->lock = malloc(sizeof(pthread_mutex_t)); |
|
||||
room->philos[i]->thd = malloc(sizeof(pthread_t)); |
|
||||
room->philos[i]->eat_time = room_clock(); |
|
||||
room->philos[i]->eat_amount = 0; |
|
||||
room->philos[i]->i = i; |
|
||||
pthread_mutex_init(room->philos[i]->fork, NULL); |
|
||||
pthread_mutex_init(room->philos[i++]->lock, NULL); |
|
||||
} |
|
||||
return (room); |
|
||||
} |
|
||||
|
|
||||
static int clean_memory(t_room *room) |
|
||||
{ |
|
||||
int *param; |
|
||||
static int i = 0; |
|
||||
|
|
||||
pthread_mutex_lock(room->lock); |
|
||||
param = room->param; |
|
||||
while (i < param[PHILO_AMOUNT]) |
|
||||
{ |
|
||||
|
|
||||
pthread_mutex_lock(room->philos[i]->lock); |
|
||||
pthread_mutex_unlock(room->philos[i]->lock); |
|
||||
pthread_mutex_destroy(room->philos[i]->lock); |
|
||||
pthread_mutex_lock(room->philos[i]->fork); |
|
||||
pthread_mutex_unlock(room->philos[i]->fork); |
|
||||
pthread_mutex_destroy(room->philos[i]->fork); |
|
||||
free(room->philos[i]->lock); |
|
||||
free(room->philos[i]->fork); |
|
||||
free(room->philos[i]->thd); |
|
||||
free(room->philos[i]); |
|
||||
i++; |
|
||||
} |
|
||||
pthread_mutex_unlock(room->lock); |
|
||||
pthread_mutex_destroy(room->lock); |
|
||||
free(room->lock); |
|
||||
free(room->philos); |
|
||||
free(room); |
|
||||
return (0); |
|
||||
} |
|
@ -0,0 +1,60 @@ |
|||||
|
/* ************************************************************************** */ |
||||
|
/* */ |
||||
|
/* ::: :::::::: */ |
||||
|
/* philo_life.c :+: :+: :+: */ |
||||
|
/* +:+ +:+ +:+ */ |
||||
|
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
||||
|
/* +#+#+#+#+#+ +#+ */ |
||||
|
/* Created: 2021/11/26 07:43:48 by narnaud #+# #+# */ |
||||
|
/* Updated: 2022/05/19 00:48:41 by narnaud@stude ### ########.fr */ |
||||
|
/* */ |
||||
|
/* ************************************************************************** */ |
||||
|
|
||||
|
#include "philo.h" |
||||
|
|
||||
|
static int eat(t_room *room, t_philo *philo) |
||||
|
{ |
||||
|
pthread_mutex_lock(philo->fork); |
||||
|
if (!safe_print(philo, "%d %d has taken a fork\n")) |
||||
|
return (1); |
||||
|
pthread_mutex_lock(philo->fork_r); |
||||
|
safe_print(philo, "%d %d has taken a fork\n"); |
||||
|
if (!safe_print(philo, "%d %d is eating\n")) |
||||
|
return (2); |
||||
|
pthread_mutex_lock(philo->lock); |
||||
|
philo->eat_time = room_clock(); |
||||
|
pthread_mutex_unlock(philo->lock); |
||||
|
if (!safe_wait(room, room_clock(), EAT_DURATION)) |
||||
|
return (2); |
||||
|
pthread_mutex_unlock(philo->fork); |
||||
|
pthread_mutex_unlock(philo->fork_r); |
||||
|
pthread_mutex_lock(philo->lock); |
||||
|
philo->eat_amount++; |
||||
|
pthread_mutex_unlock(philo->lock); |
||||
|
return (0); |
||||
|
} |
||||
|
|
||||
|
void *philos_life(void *ph) |
||||
|
{ |
||||
|
t_philo *philo; |
||||
|
int stop; |
||||
|
|
||||
|
philo = (t_philo *)ph; |
||||
|
while (1) |
||||
|
{ |
||||
|
stop = eat(philo->room, philo); |
||||
|
if (stop) |
||||
|
break ; |
||||
|
if (!safe_print(philo, "%d %d is sleeping\n")) |
||||
|
break ; |
||||
|
if (!safe_wait(philo->room, room_clock(), SLEEP_DURATION)) |
||||
|
break ; |
||||
|
if (!safe_print(philo, "%d %d is thinking\n")) |
||||
|
break ; |
||||
|
} |
||||
|
if (stop--) |
||||
|
pthread_mutex_unlock(philo->fork); |
||||
|
if (stop--) |
||||
|
pthread_mutex_unlock(philo->fork_r); |
||||
|
return (NULL); |
||||
|
} |
@ -1,101 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* philo_threads.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2021/11/26 07:43:48 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/05/18 19:22:57 by narnaud@stude ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "philosophers.h" |
|
||||
|
|
||||
int waiter(t_room *room) |
|
||||
{ |
|
||||
int *param; |
|
||||
int i; |
|
||||
int starvest; |
|
||||
t_philo *philo; |
|
||||
int ret; |
|
||||
|
|
||||
ret = 1; |
|
||||
pthread_mutex_lock(room->lock); |
|
||||
i = 0; |
|
||||
param = room->param; |
|
||||
starvest = param[MEALS_AMOUNT]; |
|
||||
while (ret && i < param[PHILO_AMOUNT]) |
|
||||
{ |
|
||||
philo = room->philos[i]; |
|
||||
pthread_mutex_lock(philo->lock); |
|
||||
if (philo->eat_time + param[DIE_TIME] < room_clock()) |
|
||||
{ |
|
||||
printf("%d %d died\n", room_clock(), i); |
|
||||
ret = 0; |
|
||||
} |
|
||||
if (philo->eat_amount < starvest) |
|
||||
starvest = philo->eat_amount; |
|
||||
pthread_mutex_unlock(philo->lock); |
|
||||
i++; |
|
||||
} |
|
||||
pthread_mutex_unlock(room->lock); |
|
||||
if (starvest == param[MEALS_AMOUNT]) |
|
||||
ret = 0; |
|
||||
return (ret); |
|
||||
} |
|
||||
|
|
||||
static int philo_life(t_room *room, t_philo *philo, int id, int id_p, int *param) |
|
||||
{ |
|
||||
pthread_mutex_lock(philo->fork); |
|
||||
if (!safe_print("%d %d has taken a fork\n", room, id)) |
|
||||
return (1); |
|
||||
pthread_mutex_lock(room->philos[id_p]->fork); |
|
||||
safe_print("%d %d has taken a fork\n", room, id); |
|
||||
if(!safe_print("%d %d is eating\n", room, id)) |
|
||||
return (2); |
|
||||
pthread_mutex_lock(philo->lock); |
|
||||
philo->eat_time = room_clock(); |
|
||||
pthread_mutex_unlock(philo->lock); |
|
||||
if (!safe_wait(room, room_clock(), param[EAT_DURATION])) |
|
||||
return (2); |
|
||||
pthread_mutex_unlock(philo->fork); |
|
||||
pthread_mutex_unlock(room->philos[id_p]->fork); |
|
||||
if(!safe_print("%d %d is sleeping\n", room, id)) |
|
||||
return (-1); |
|
||||
pthread_mutex_lock(philo->lock); |
|
||||
philo->eat_amount++; |
|
||||
pthread_mutex_unlock(philo->lock); |
|
||||
if (!safe_wait(room, room_clock(), param[SLEEP_DURATION])) |
|
||||
return (-1); |
|
||||
if (!safe_print("%d %d is thinking\n", room, id)) |
|
||||
return (-1); |
|
||||
return (0); |
|
||||
} |
|
||||
|
|
||||
void *philos_birth(void *r) |
|
||||
{ |
|
||||
t_room *room; |
|
||||
int *param; |
|
||||
t_philo *philo; |
|
||||
int id; |
|
||||
int id_p; |
|
||||
int stop; |
|
||||
|
|
||||
stop = 0; |
|
||||
room = (t_room *)r; |
|
||||
param = room->param; |
|
||||
pthread_mutex_lock(room->lock); |
|
||||
id = room->i; |
|
||||
philo = room->philos[id]; |
|
||||
philo->eat_time = room_clock(); |
|
||||
id_p = (id + 1) % param[PHILO_AMOUNT]; |
|
||||
pthread_mutex_unlock(room->lock); |
|
||||
while (!stop) |
|
||||
stop = philo_life(room, philo, id, id_p, param); |
|
||||
if (stop-- > 0) |
|
||||
pthread_mutex_unlock(philo->fork); |
|
||||
if (stop-- > 0) |
|
||||
pthread_mutex_unlock(room->philos[id_p]->fork); |
|
||||
return (NULL); |
|
||||
} |
|
Loading…
Reference in new issue