Browse Source

rework

master
narnaud 3 years ago
parent
commit
f352d98bf6
  1. 24
      philo/Makefile
  2. 88
      philo/philo.c
  3. 47
      philo/philo.h
  4. 82
      philo/philo_init.c
  5. 120
      philo/philo_launcher.c
  6. 60
      philo/philo_life.c
  7. 101
      philo/philo_threads.c
  8. 20
      philo/philo_utils.c

24
philo/Makefile

@ -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}
CC = clang
CFLAGS = -Werror -Wextra -Wall -g -D_REENTRANT
RM = rm -rf
.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

88
philo/philo.c

@ -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);
}

47
philo/philosophers.h → philo/philo.h

@ -1,19 +1,17 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philosophers.h :+: :+: :+: */
/* philo.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* By: narnaud@student.42nice.fr <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/11/24 15:44:06 by narnaud #+# #+# */
/* Updated: 2022/05/18 19:26:02 by narnaud@stude ### ########.fr */
/* Created: 2022/05/18 22:23:52 by narnaud@stude #+# #+# */
/* Updated: 2022/05/19 00:42:59 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PHILOSOPHERS_H
# define PHILOSOPHERS_H
# define CLOCK_ONE 500
# define CLOCK_TWO 1000
#ifndef PHILO_H
# define PHILO_H
# include <unistd.h>
# include <stdio.h>
@ -31,30 +29,37 @@ enum e_params
MEALS_AMOUNT,
};
typedef struct s_room
{
int param[5];
pthread_mutex_t *lock;
pthread_mutex_t *forks;
int running;
} t_room;
typedef struct s_philo
{
t_room *room;
pthread_mutex_t *fork;
pthread_mutex_t *fork_r;
pthread_mutex_t *next;
pthread_mutex_t *lock;
pthread_t *thd;
int eat_time;
int eat_amount;
int i;
int id;
} t_philo;
typedef struct s_room
{
int param[5];
t_philo **philos;
pthread_mutex_t *lock;
int running;
int i;
} t_room;
int waiter(t_room *room);
// ---------------------------------- philo_init
t_room *create_room(char **argv);
t_philo *create_philos(t_room *room);
void invit_philos(t_philo *philos);
void *philos_birth(void *r);
// ---------------------------------- philo_life
void *philos_life(void *r);
int safe_print(char *str, t_room *room, int id);
// ---------------------------------- philo_utils
int safe_print(t_philo *philo, char *str);
int safe_wait(t_room *room, int start, int duration);
int room_clock();
int mini_atoi(char *nbr);

82
philo/philo_init.c

@ -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;
}
}

120
philo/philo_launcher.c

@ -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);
}

60
philo/philo_life.c

@ -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);
}

101
philo/philo_threads.c

@ -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);
}

20
philo/philo_utils.c

@ -6,11 +6,11 @@
/* By: narnaud@student.42nice.fr <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/18 19:10:41 by narnaud@stude #+# #+# */
/* Updated: 2022/05/18 19:27:30 by narnaud@stude ### ########.fr */
/* Updated: 2022/05/19 00:50:56 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
#include "philosophers.h"
#include "philo.h"
int is_running(t_room *room)
{
@ -22,13 +22,16 @@ int is_running(t_room *room)
return (ret);
}
int safe_print(char *str, t_room *room, int id)
int safe_print(t_philo *philo, char *str)
{
int ret;
ret = is_running(room);
ret = is_running(philo->room);
if (!ret)
return (0);
printf(str, room_clock(), id);
pthread_mutex_lock(philo->room->lock);
printf(str, room_clock(), philo->id);
pthread_mutex_unlock(philo->room->lock);
return (ret);
}
@ -37,7 +40,8 @@ int safe_wait(t_room *room, int start, int duration)
int ret;
ret = is_running(room);
while (ret && (room_clock() < (start + duration)))
while (ret && (room_clock()
< (start + room->param[duration])))
{
ret = is_running(room);
usleep(50);
@ -45,7 +49,7 @@ int safe_wait(t_room *room, int start, int duration)
return (ret);
}
int room_clock()
int room_clock(void)
{
struct timeval time;
int ret;
@ -68,5 +72,5 @@ int mini_atoi(char *nbr)
ret = (*nbr - '0') + (10 * ret);
nbr++;
}
return (ret);
return (ret);
}

Loading…
Cancel
Save