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 |
|||
OBJS = ${SRCS:.c=.o} |
|||
SRCS = philo.c philo_init.c philo_life.c philo_utils.c |
|||
OBJS = ${SRCS:.c=.o} |
|||
|
|||
CC = clang |
|||
CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT |
|||
RM = rm -rf |
|||
CC = clang |
|||
CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT |
|||
RM = rm -rf |
|||
|
|||
.c.o: |
|||
$(CC) $(CFLAGS) -c $< -o $(<:.c=.o) |
|||
%.o : %.c |
|||
$(CC) $(CFLAGS) -c $< -o $(<:.c=.o) |
|||
|
|||
all: $(NAME) |
|||
all : $(NAME) |
|||
|
|||
$(NAME): $(OBJS) |
|||
${CC} ${CFLAGS} -lpthread ${OBJS} -o ${NAME} |
|||
$(NAME) : $(OBJS) |
|||
$(CC) $(CFLAGS) -lpthread $(OBJS) -o $(NAME) |
|||
|
|||
clean: |
|||
${RM} ${OBJS} |
|||
clean : |
|||
$(RM) $(OBJS) |
|||
|
|||
fclean: clean |
|||
${RM} ${NAME} |
|||
fclean : clean |
|||
$(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