Initial commit

This commit is contained in:
2026-01-09 15:45:59 +01:00
commit 2dbcbac9ef
43 changed files with 2547 additions and 0 deletions

42
philo_one/Makefile Executable file
View File

@@ -0,0 +1,42 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: lejulien <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/07/05 18:43:38 by lejulien #+# #+# #
# Updated: 2021/04/21 13:53:40 by lejulien ### ########.fr #
# #
# **************************************************************************** #
UTILS = ./srcs/utils/ft_atoi.c ./srcs/utils/ft_itoa.c \
./srcs/utils/ft_strcmp.c
SRCS = ./srcs/philo_one/main.c ./srcs/philo_one/init_data.c \
./srcs/philo_one/gen_philos.c ./srcs/philo_one/init_philos.c \
./srcs/philo_one/time.c ./srcs/philo_one/display.c \
./srcs/philo_one/eat.c ./srcs/philo_one/fork.c
SRCS_OBJS = ${SRCS:.c=.o}
UTILS_OBJS = ${UTILS:.c=.o}
FLAGS = -Wall -Wextra -Werror -lpthread
.c.o:
gcc -c $< -o $(<:.c=.o)
NAME = philo_one
$(NAME): $(SRCS_OBJS) $(UTILS_OBJS)
gcc -o $(NAME) $(SRCS_OBJS) $(UTILS_OBJS) $(FLAGS)
clean:
rm -f $(SRCS_OBJS) $(UTILS_OBJS)
fclean: clean
rm -f $(NAME)
re: fclean $(NAME)
.PHONY: clean fclean re

View File

@@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* display.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:13:20 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:41:05 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
void
display_state(t_philo *ptr)
{
unsigned long int time;
if (ptr->data->is_dead)
return ;
time = ft_get_ct(&ptr->start);
pthread_mutex_lock(&ptr->data->write_access);
if (ptr->state == DIED)
{
ptr->data->is_dead = 1;
printf("%ld %d died\n", time, ptr->id + 1);
}
if (ptr->state == EAT)
printf("%ld %d is eating\n", time, ptr->id + 1);
if (ptr->state == SLEEP)
printf("%ld %d is sleeping\n", time, ptr->id + 1);
if (ptr->state == THINK)
printf("%ld %d is thinking\n", time, ptr->id + 1);
pthread_mutex_unlock(&ptr->data->write_access);
}

View File

@@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* eat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:32:58 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:00:39 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
ft_r_fork(t_philo *phi)
{
pthread_mutex_unlock(phi->fork_l);
pthread_mutex_unlock(phi->fork_r);
}
void
ft_eat(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (++phi->nbr_of_eats == phi->data->max_launch)
phi->data->phi_filled++;
if (phi->state == DIED)
return ;
phi->last_eat = ft_get_ct(&phi->start);
if (ft_usleep(phi->data->time_to_eat, phi))
{
ft_r_fork(phi);
return ;
}
ft_r_fork(phi);
phi->state = SLEEP;
}
void
ft_sleep(void *ptr)
{
t_philo *phi;
unsigned long int start;
phi = (t_philo *)ptr;
display_state(phi);
if (ft_usleep(phi->data->time_to_sleep, phi))
return ;
phi->state = THINK;
}
void
ft_think(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (phi->state == DIED)
return ;
check_fork(phi);
if (!(phi->state == DIED))
phi->state = EAT;
}

View File

@@ -0,0 +1,49 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* fork.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:48:17 by lejulien #+# #+# */
/* Updated: 2021/04/18 12:22:43 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
display_fork(t_philo *phi)
{
if (!phi->data->is_dead)
{
pthread_mutex_lock(&phi->data->write_access);
printf("%ld %d has taken a fork\n", ft_get_ct(&phi->start),
phi->id + 1);
pthread_mutex_unlock(&phi->data->write_access);
}
}
static void
take_l_fork(t_philo *phi)
{
pthread_mutex_lock(phi->fork_l);
display_fork(phi);
}
static void
take_r_fork(t_philo *phi)
{
pthread_mutex_lock(phi->fork_r);
display_fork(phi);
}
void
check_fork(t_philo *phi)
{
take_r_fork(phi);
if (phi->data->nbr != 1)
take_l_fork(phi);
else
ft_usleep(phi->data->time_to_die + 1, phi);
}

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* gen_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:59:19 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:52:51 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
t_philo
*gen_philos(int ac, char **av, t_data *data)
{
int i;
t_philo *philos;
if (!(philos = malloc(ft_atoi(av[1]) * sizeof(t_philo))))
return (NULL);
i = -1;
while (++i < ft_atoi(av[1]))
{
philos[i].id = i;
philos[i].state = SLEEP;
philos[i].last_eat = SLEEP;
philos[i].nbr_of_eats = 0;
philos[i].data = data;
if (i == 0)
philos[i].fork_l = &data->forks[data->nbr - 1];
else
philos[i].fork_l = &data->forks[i - 1];
philos[i].fork_r = &data->forks[i];
}
return (philos);
}

View File

@@ -0,0 +1,115 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_data.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:07:28 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:31:06 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
check_int(char **av, int index)
{
int test_i;
char *test;
test_i = ft_atoi(av[index]);
if (test_i > 100000)
return (1);
test = ft_itoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_uli(char **av, int index)
{
int test_i;
char *test;
if (av[index][0] == '-')
return (1);
test_i = ft_atouli(av[index]);
test = ft_ulitoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_data(int ac, char **av)
{
if (check_int(av, 1))
return (1);
if (ft_atoi(av[1]) < 1)
return (1);
if (check_uli(av, 2))
return (1);
if (check_uli(av, 3))
return (1);
if (check_uli(av, 4))
return (1);
if (ac == 6)
{
if (check_int(av, 5))
return (1);
if (ft_atoi(av[5]) < 1)
return (1);
}
return (0);
}
static void
init_data_helper(t_data *data, int ac, char **av)
{
data->routine[EAT] = ft_eat;
data->routine[SLEEP] = ft_sleep;
data->routine[THINK] = ft_think;
data->phi_filled = 0;
data->nbr = ft_atoi(av[1]);
data->time_to_die = ft_atouli(av[2]);
data->time_to_eat = ft_atouli(av[3]);
data->time_to_sleep = ft_atouli(av[4]);
if (ac == 6)
data->max_launch = ft_atoi(av[5]);
else
data->max_launch = -1;
}
t_data
*init_data(int ac, char **av)
{
t_data *data;
int i;
if (check_data(ac, av) || !(data = malloc(sizeof(t_data))))
return (NULL);
if (!(data->forks = malloc(ft_atoi(av[1]) * sizeof(pthread_mutex_t))))
return (NULL);
data->is_dead = 0;
i = 0;
while (i < ft_atoi(av[1]))
{
if (pthread_mutex_init(&data->forks[i], NULL) != 0)
return (NULL);
i++;
}
if (pthread_mutex_init(&data->write_access, NULL) != 0)
return (NULL);
init_data_helper(data, ac, av);
return (data);
}

View File

@@ -0,0 +1,82 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:24:12 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:46:01 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
*philosopher(void *philos)
{
t_philo *phi;
phi = (t_philo *)philos;
phi->state = (phi->id % 2 == 0) ? SLEEP : THINK;
usleep(500);
while (!phi->data->is_dead && phi->state != DIED)
phi->data->routine[phi->state](phi);
if (phi->state == DIED)
{
display_state(phi);
phi->data->is_dead = 1;
}
pthread_mutex_unlock(phi->fork_l);
pthread_mutex_unlock(phi->fork_r);
return (NULL);
}
static void
check_death(t_philo *phi)
{
int i;
i = 0;
while (1)
{
if (ft_get_ct(&phi[i].start) - phi[i].last_eat > phi->data->time_to_die
&& (phi[i].state != EAT || phi->data->time_to_die <
phi->data->time_to_eat))
{
if (phi[i].state == THINK)
{
phi[i].state = DIED;
display_state(&phi[i]);
phi[i].state = THINK;
phi->data->is_dead = 1;
}
else
phi[i].state = DIED;
break ;
}
if (phi->data->phi_filled == phi->data->nbr)
phi->data->is_dead = 1;
i++;
(i == phi->data->nbr) ? (i = 0) : 0;
}
}
void
init_philos(t_philo *philos)
{
int i;
pthread_t origin[philos->data->nbr];
i = -1;
while (++i < philos->data->nbr)
{
gettimeofday(&philos[i].start, NULL);
pthread_create(&origin[i], NULL, philosopher, &philos[i]);
}
usleep(2000);
check_death(philos);
i = -1;
while (++i < philos->data->nbr)
pthread_join(origin[i], NULL);
}

View File

@@ -0,0 +1,59 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:19 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:27:57 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
print_usage(void)
{
write(2, "Usage : ./philo_one nbr_of_philos time_to_die time_", 51);
write(2, "to_eat time_to_sleep [minimum_eat_for_each_philos]\n", 51);
return (1);
}
static void
free_data(t_data *data, char **av)
{
int i;
i = -1;
while (++i < ft_atoi(av[1]))
pthread_mutex_destroy(&data->forks[i]);
free(data->forks);
pthread_mutex_destroy(&data->write_access);
free(data);
}
int
main(int ac, char **av)
{
t_philo *philos;
t_data *data;
philos = NULL;
if (ac == 5 || ac == 6)
{
if (!(data = init_data(ac, av)))
return (print_usage());
if (!(philos = gen_philos(ac, av, data)))
{
free_data(data, av);
return (print_usage());
}
init_philos(philos);
free_data(data, av);
free(philos);
}
else
return (print_usage());
return (0);
}

View File

@@ -0,0 +1,62 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philo.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:57 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:56:54 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PHILO_H
# define PHILO_H
# include "../utils/utils.h"
# include <sys/time.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <pthread.h>
# define EAT 0
# define SLEEP 1
# define THINK 2
# define DIED 3
typedef struct s_data
{
int nbr;
unsigned long int time_to_die;
unsigned long int time_to_eat;
unsigned long int time_to_sleep;
int max_launch;
int phi_filled;
pthread_mutex_t *forks;
pthread_mutex_t write_access;
int is_dead;
void (*routine[4])(void *);
} t_data;
typedef struct s_philo
{
int id;
int state;
struct timeval start;
t_data *data;
pthread_mutex_t *fork_l;
pthread_mutex_t *fork_r;
int nbr_of_eats;
unsigned long int last_eat;
} t_philo;
t_data *init_data(int ac, char **av);
t_philo *gen_philos(int ac, char **av, t_data *data);
unsigned long int ft_get_ct(struct timeval *start);
void init_philos(t_philo *philos);
void display_state(t_philo *ptr);
int ft_usleep(unsigned long int time, t_philo *phi);
void ft_eat(void *ptr);
void ft_sleep(void *ptr);
void ft_think(void *ptr);
void check_fork(t_philo *phi);
#endif

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* time.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:42:27 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:52:31 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
unsigned long int
ft_get_ct(struct timeval *start)
{
struct timeval now;
gettimeofday(&now, NULL);
return (((now.tv_sec * 1000000 + now.tv_usec) -
(start->tv_sec * 1000000 + start->tv_usec)) / 1000);
}
int
ft_usleep(unsigned long int time, t_philo *phi)
{
unsigned long int now;
now = ft_get_ct(&phi->start);
while (!phi->data->is_dead && ft_get_ct(&phi->start) - now < time)
{
usleep(500);
if (phi->state == DIED)
return (1);
}
return (0);
}

74
philo_one/srcs/utils/ft_atoi.c Executable file
View File

@@ -0,0 +1,74 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/05 13:06:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:34:00 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
static int
ft_isspace(char c)
{
if ((c == '\f') || (c == '\t') || (c == '\n') || (c == '\r')
|| (c == '\v') || (c == ' '))
{
return (1);
}
return (0);
}
int
ft_atoi(const char *str)
{
int nbr;
int sign;
int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}
unsigned long int
ft_atouli(const char *str)
{
unsigned long int nbr;
int sign;
unsigned long int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}

View File

@@ -0,0 +1,111 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_itoa.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/15 10:35:00 by lejulien #+# #+# */
/* Updated: 2021/04/15 11:15:45 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
static char *ft_itoa2(int iszero, unsigned int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_itoa(int n)
{
unsigned int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}
static char *ft_ulitoa2(int iszero, unsigned long int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_ulitoa(unsigned long int n)
{
unsigned long int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}

View File

@@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/31 15:46:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:58:32 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
int ft_strcmp(char *s1, char *s2)
{
int index;
index = 0;
while (s2[index] && s1[index])
{
if (s1[index] == s2[index])
index++;
else
return (1);
}
if (s1[index] == '\0' && s2[index] == '\0')
return (0);
return (1);
}

21
philo_one/srcs/utils/utils.h Executable file
View File

@@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/03 15:42:26 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:54:39 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef UTILS_H
# define UTILS_H
int ft_atoi(char *str);
unsigned long int ft_atouli(char *str);
char *ft_itoa(int n);
char *ft_ulitoa(unsigned long int n);
int ft_strcmp(char *s1, char *s2);
#endif

43
philo_three/Makefile Executable file
View File

@@ -0,0 +1,43 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: lejulien <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/07/05 18:43:38 by lejulien #+# #+# #
# Updated: 2021/04/21 17:54:50 by lejulien ### ########.fr #
# #
# **************************************************************************** #
UTILS = ./srcs/utils/ft_atoi.c ./srcs/utils/ft_itoa.c \
./srcs/utils/ft_strcmp.c
SRCS = ./srcs/philo_three/main.c ./srcs/philo_three/init_data.c \
./srcs/philo_three/gen_philos.c ./srcs/philo_three/init_philos.c \
./srcs/philo_three/time.c ./srcs/philo_three/display.c \
./srcs/philo_three/eat.c ./srcs/philo_three/fork.c \
./srcs/philo_three/display2.c
SRCS_OBJS = ${SRCS:.c=.o}
UTILS_OBJS = ${UTILS:.c=.o}
FLAGS = -Wall -Wextra -Werror -lpthread
.c.o:
gcc -c $< -o $(<:.c=.o)
NAME = philo_three
$(NAME): $(SRCS_OBJS) $(UTILS_OBJS)
gcc -o $(NAME) $(SRCS_OBJS) $(UTILS_OBJS) $(FLAGS)
clean:
rm -f $(SRCS_OBJS) $(UTILS_OBJS)
fclean: clean
rm -f $(NAME)
re: fclean $(NAME)
.PHONY: clean fclean re

View File

@@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* display.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:13:20 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:54:31 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
void
display_state(t_philo *ptr)
{
unsigned long int time;
int i;
if (ptr->data->is_dead)
return ;
sem_wait(ptr->data->write_access);
time = ft_get_ct(&ptr->start);
if (ptr->state == DIED)
{
ptr->data->is_dead = 1;
display_helper(time, ptr->id + 1, "died");
i = -1;
while (++i < ptr->data->nbr)
sem_post(ptr->data->phi_filled);
return ;
}
if (ptr->state == EAT)
display_helper(time, ptr->id + 1, "is eating");
if (ptr->state == SLEEP)
display_helper(time, ptr->id + 1, "is sleeping");
if (ptr->state == THINK)
display_helper(time, ptr->id + 1, "is thinking");
sem_post(ptr->data->write_access);
}

View File

@@ -0,0 +1,100 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* display2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/21 17:54:12 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:54:33 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
ft_strlen(char *str)
{
int i;
i = 0;
while (str[i] != '\0')
i++;
return (i);
}
static void
ft_itobuff2(int iszero, unsigned int nu, int i, char *res)
{
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
}
static int
ft_itobuff(unsigned long int n, char *buffer)
{
unsigned long int nu;
unsigned long int i;
int iszero;
i = 0;
buffer[i] = '\0';
if (n == 0)
{
i = 1;
nu = 0;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
ft_itobuff2(iszero, nu, i, buffer);
return (i);
}
static int
str_cpy(char *str, char *buff)
{
int i;
i = 0;
while (str[i] != '\0')
{
buff[i] = str[i];
i++;
}
return (i);
}
void
display_helper(unsigned long int time, int id, char *str)
{
char buff[34];
int i;
i = ft_itobuff(time, buff);
buff[i] = ' ';
i = (i + 1 + ft_itobuff((unsigned long int)id, &buff[i + 1]));
buff[i] = ' ';
i = (i + 1 + str_cpy(str, &buff[i + 1]));
buff[i] = '\n';
buff[i + 1] = '\0';
write(1, buff, ft_strlen(buff));
}

View File

@@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* eat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:32:58 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:20:51 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
void
ft_eat(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (++phi->nbr_of_eats == phi->data->max_launch)
sem_post(phi->data->phi_filled);
if (phi->state == DIED)
return ;
phi->last_eat = ft_get_ct(&phi->start);
if (ft_usleep(phi->data->time_to_eat, phi))
{
sem_post(phi->data->forks);
return ;
}
sem_post(phi->data->forks);
phi->state = SLEEP;
}
void
ft_sleep(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (ft_usleep(phi->data->time_to_sleep, phi))
return ;
phi->state = THINK;
}
void
ft_think(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (phi->state == DIED)
return ;
check_fork(phi);
if (!(phi->state == DIED))
phi->state = EAT;
}

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* fork.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:48:17 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:52:12 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
display_fork(t_philo *phi)
{
sem_wait(phi->data->write_access);
if (!phi->data->is_dead)
display_helper(ft_get_ct(&phi->start), phi->id + 1, "has taken a fork");
sem_post(phi->data->write_access);
}
void
check_fork(t_philo *phi)
{
if (phi->data->nbr != 1)
{
sem_wait(phi->data->forks);
display_fork(phi);
display_fork(phi);
}
else
{
display_fork(phi);
ft_usleep(phi->data->time_to_die, phi);
}
}

View File

@@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* gen_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:59:19 by lejulien #+# #+# */
/* Updated: 2021/04/17 16:45:17 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
t_philo
*gen_philos(int ac, char **av, t_data *data)
{
int i;
t_philo *philos;
if (!(philos = malloc(ft_atoi(av[1]) * sizeof(t_philo))))
return (NULL);
i = -1;
while (++i < ft_atoi(av[1]))
{
philos[i].id = i;
philos[i].state = SLEEP;
philos[i].last_eat = SLEEP;
philos[i].nbr_of_eats = 0;
philos[i].data = data;
}
return (philos);
}

View File

@@ -0,0 +1,112 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_data.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:07:28 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:32:47 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
check_int(char **av, int index)
{
int test_i;
char *test;
test_i = ft_atoi(av[index]);
if (test_i > 100000)
return (1);
test = ft_itoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_uli(char **av, int index)
{
int test_i;
char *test;
if (av[index][0] == '-')
return (1);
test_i = ft_atouli(av[index]);
test = ft_ulitoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_data(int ac, char **av)
{
if (check_int(av, 1))
return (1);
if (ft_atoi(av[1]) < 1)
return (1);
if (check_uli(av, 2))
return (1);
if (check_uli(av, 3))
return (1);
if (check_uli(av, 4))
return (1);
if (ac == 6)
{
if (check_int(av, 5))
return (1);
if (ft_atoi(av[5]) < 1)
return (1);
}
return (0);
}
static void
init_data_helper(t_data *data, int ac, char **av)
{
data->routine[EAT] = ft_eat;
data->routine[SLEEP] = ft_sleep;
data->routine[THINK] = ft_think;
data->nbr = ft_atoi(av[1]);
sem_unlink("phi_filled");
sem_unlink("start");
data->phi_filled = sem_open("phi_filled", O_CREAT | O_EXCL, 0644, 0);
data->start = sem_open("start", O_CREAT | O_EXCL, 0644, 0);
data->time_to_die = ft_atouli(av[2]);
data->time_to_eat = ft_atouli(av[3]);
data->time_to_sleep = ft_atouli(av[4]);
if (ac == 6)
data->max_launch = ft_atoi(av[5]);
else
data->max_launch = -1;
}
t_data
*init_data(int ac, char **av)
{
t_data *data;
int i;
if (check_data(ac, av) || !(data = malloc(sizeof(t_data))))
return (NULL);
data->is_dead = 0;
i = 0;
init_data_helper(data, ac, av);
sem_unlink("forks");
sem_unlink("write_access");
data->forks = sem_open("forks", O_CREAT | O_EXCL, 0644, data->nbr / 2);
data->write_access = sem_open("write_access", O_CREAT | O_EXCL, 0644, 1);
return (data);
}

View File

@@ -0,0 +1,104 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:24:12 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:53:00 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
*check_death(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
gettimeofday(&phi->start, NULL);
phi->last_eat = ft_get_ct(&phi->start);
while (!phi->data->is_dead)
{
usleep(1000);
if (ft_get_ct(&phi->start) - phi->last_eat >
phi->data->time_to_die && (phi->state != EAT ||
phi->data->time_to_die < phi->data->time_to_eat))
{
if (phi->state == THINK)
{
phi->state = DIED;
display_state(phi);
phi->state = THINK;
phi->data->is_dead = 1;
}
else
phi->state = DIED;
return (NULL);
}
}
return (NULL);
}
static void
*philosopher(void *philos)
{
t_philo *phi;
pthread_t monitors;
int i;
phi = (t_philo *)philos;
phi->state = (phi->id % 2 == 0) ? SLEEP : THINK;
sem_wait(phi->data->start);
pthread_create(&monitors, NULL, check_death, philos);
gettimeofday(&phi->start, NULL);
while (phi->state != DIED && !phi->data->is_dead)
phi->data->routine[phi->state](phi);
if (phi->state == DIED)
{
display_state(phi);
phi->data->is_dead = 1;
}
sem_post(phi->data->forks);
i = -1;
while (++i < phi->data->nbr)
sem_post(phi->data->phi_filled);
return (NULL);
}
static void
monitor_sim(pid_t *origin, t_philo *philos)
{
int i;
i = -1;
while (++i < philos->data->nbr + 1)
sem_post(philos->data->start);
i = -1;
while (++i < philos->data->nbr)
sem_wait(philos->data->phi_filled);
i = -1;
while (++i < philos->data->nbr)
kill(origin[i], SIGKILL);
}
void
init_philos(t_philo *philos)
{
int i;
pid_t origin[philos->data->nbr];
i = -1;
while (++i < philos->data->nbr)
{
if ((origin[i] = fork()) == 0)
{
philosopher(&philos[i]);
exit(0);
}
}
usleep(1000);
monitor_sim(origin, philos);
}

View File

@@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:19 by lejulien #+# #+# */
/* Updated: 2021/04/19 17:09:58 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
print_usage(void)
{
write(2, "Usage : ./philo_one nbr_of_philos time_to_die time_", 51);
write(2, "to_eat time_to_sleep [minimum_eat_for_each_philos]\n", 51);
return (1);
}
static void
free_data(t_data *data, char **av)
{
sem_close(data->forks);
sem_unlink("forks");
sem_close(data->write_access);
sem_unlink("write_access");
sem_close(data->phi_filled);
sem_unlink("write_access");
sem_close(data->start);
sem_unlink("write_access");
free(data);
}
int
main(int ac, char **av)
{
t_philo *philos;
t_data *data;
philos = NULL;
if (ac == 5 || ac == 6)
{
if (!(data = init_data(ac, av)))
return (print_usage());
if (!(philos = gen_philos(ac, av, data)))
{
free_data(data, av);
return (print_usage());
}
init_philos(philos);
free_data(data, av);
free(philos);
}
else
return (print_usage());
return (0);
}

View File

@@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philo.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:57 by lejulien #+# #+# */
/* Updated: 2021/04/20 17:19:55 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PHILO_H
# define PHILO_H
# include "../utils/utils.h"
# include <sys/time.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <pthread.h>
# include <semaphore.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <signal.h>
# define EAT 0
# define SLEEP 1
# define THINK 2
# define DIED 3
typedef struct s_data
{
int nbr;
unsigned long int time_to_die;
unsigned long int time_to_eat;
unsigned long int time_to_sleep;
int max_launch;
sem_t *phi_filled;
sem_t *forks;
sem_t *start;
sem_t *write_access;
int is_dead;
void (*routine[4])(void *);
} t_data;
typedef struct s_philo
{
int id;
int state;
struct timeval start;
t_data *data;
int nbr_of_eats;
unsigned long int last_eat;
} t_philo;
t_data *init_data(int ac, char **av);
t_philo *gen_philos(int ac, char **av, t_data *data);
unsigned long int ft_get_ct(struct timeval *start);
void init_philos(t_philo *philos);
void display_state(t_philo *ptr);
int ft_usleep(unsigned long int time, t_philo *phi);
void ft_eat(void *ptr);
void ft_sleep(void *ptr);
void ft_think(void *ptr);
void check_fork(t_philo *phi);
void display_helper(unsigned long int time, int id,
char *str);
#endif

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* time.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:42:27 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:52:31 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
unsigned long int
ft_get_ct(struct timeval *start)
{
struct timeval now;
gettimeofday(&now, NULL);
return (((now.tv_sec * 1000000 + now.tv_usec) -
(start->tv_sec * 1000000 + start->tv_usec)) / 1000);
}
int
ft_usleep(unsigned long int time, t_philo *phi)
{
unsigned long int now;
now = ft_get_ct(&phi->start);
while (!phi->data->is_dead && ft_get_ct(&phi->start) - now < time)
{
usleep(500);
if (phi->state == DIED)
return (1);
}
return (0);
}

View File

@@ -0,0 +1,74 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/05 13:06:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:34:00 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
static int
ft_isspace(char c)
{
if ((c == '\f') || (c == '\t') || (c == '\n') || (c == '\r')
|| (c == '\v') || (c == ' '))
{
return (1);
}
return (0);
}
int
ft_atoi(const char *str)
{
int nbr;
int sign;
int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}
unsigned long int
ft_atouli(const char *str)
{
unsigned long int nbr;
int sign;
unsigned long int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}

View File

@@ -0,0 +1,111 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_itoa.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/15 10:35:00 by lejulien #+# #+# */
/* Updated: 2021/04/15 11:15:45 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
static char *ft_itoa2(int iszero, unsigned int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_itoa(int n)
{
unsigned int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}
static char *ft_ulitoa2(int iszero, unsigned long int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_ulitoa(unsigned long int n)
{
unsigned long int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}

View File

@@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/31 15:46:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:58:32 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
int ft_strcmp(char *s1, char *s2)
{
int index;
index = 0;
while (s2[index] && s1[index])
{
if (s1[index] == s2[index])
index++;
else
return (1);
}
if (s1[index] == '\0' && s2[index] == '\0')
return (0);
return (1);
}

21
philo_three/srcs/utils/utils.h Executable file
View File

@@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/03 15:42:26 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:54:39 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef UTILS_H
# define UTILS_H
int ft_atoi(char *str);
unsigned long int ft_atouli(char *str);
char *ft_itoa(int n);
char *ft_ulitoa(unsigned long int n);
int ft_strcmp(char *s1, char *s2);
#endif

42
philo_two/Makefile Executable file
View File

@@ -0,0 +1,42 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: lejulien <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/07/05 18:43:38 by lejulien #+# #+# #
# Updated: 2021/04/17 16:28:56 by lejulien ### ########.fr #
# #
# **************************************************************************** #
UTILS = ./srcs/utils/ft_atoi.c ./srcs/utils/ft_itoa.c \
./srcs/utils/ft_strcmp.c
SRCS = ./srcs/philo_two/main.c ./srcs/philo_two/init_data.c \
./srcs/philo_two/gen_philos.c ./srcs/philo_two/init_philos.c \
./srcs/philo_two/time.c ./srcs/philo_two/display.c \
./srcs/philo_two/eat.c ./srcs/philo_two/fork.c
SRCS_OBJS = ${SRCS:.c=.o}
UTILS_OBJS = ${UTILS:.c=.o}
FLAGS = -Wall -Wextra -Werror -lpthread -g3
.c.o:
gcc -c $< -o $(<:.c=.o)
NAME = philo_two
$(NAME): $(SRCS_OBJS) $(UTILS_OBJS)
gcc -o $(NAME) $(SRCS_OBJS) $(UTILS_OBJS) $(FLAGS)
clean:
rm -f $(SRCS_OBJS) $(UTILS_OBJS)
fclean: clean
rm -f $(NAME)
re: fclean $(NAME)
.PHONY: clean fclean re

View File

@@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* display.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:13:20 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:41:37 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
void
display_state(t_philo *ptr)
{
unsigned long int time;
if (ptr->data->is_dead)
return ;
sem_wait(ptr->data->write_access);
time = ft_get_ct(&ptr->start);
if (ptr->state == DIED)
{
ptr->data->is_dead = 1;
printf("%ld %d died\n", time, ptr->id + 1);
}
if (ptr->state == EAT)
printf("%ld %d is eating\n", time, ptr->id + 1);
if (ptr->state == SLEEP)
printf("%ld %d is sleeping\n", time, ptr->id + 1);
if (ptr->state == THINK)
printf("%ld %d is thinking\n", time, ptr->id + 1);
sem_post(ptr->data->write_access);
}

View File

@@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* eat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:32:58 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:19:33 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
void
ft_eat(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (++phi->nbr_of_eats == phi->data->max_launch)
phi->data->phi_filled++;
phi->last_eat = ft_get_ct(&phi->start);
if (phi->state == DIED)
return ;
if (ft_usleep(phi->data->time_to_eat, phi))
{
sem_post(phi->data->forks);
return ;
}
sem_post(phi->data->forks);
phi->state = SLEEP;
}
void
ft_sleep(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (ft_usleep(phi->data->time_to_sleep, phi))
return ;
phi->state = THINK;
}
void
ft_think(void *ptr)
{
t_philo *phi;
phi = (t_philo *)ptr;
display_state(phi);
if (phi->state == DIED)
return ;
check_fork(phi);
if (!(phi->state == DIED))
phi->state = EAT;
}

View File

@@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* fork.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 17:48:17 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:48:54 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
display_fork(t_philo *phi)
{
sem_wait(phi->data->write_access);
if (!phi->data->is_dead)
{
printf("%ld %d has taken a fork\n", ft_get_ct(&phi->start),
phi->id + 1);
}
sem_post(phi->data->write_access);
}
void
check_fork(t_philo *phi)
{
if (phi->data->nbr != 1)
{
sem_wait(phi->data->forks);
display_fork(phi);
display_fork(phi);
}
else
{
display_fork(phi);
ft_usleep(phi->data->time_to_die + 1, phi);
}
}

View File

@@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* gen_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:59:19 by lejulien #+# #+# */
/* Updated: 2021/04/17 16:45:17 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
t_philo
*gen_philos(int ac, char **av, t_data *data)
{
int i;
t_philo *philos;
if (!(philos = malloc(ft_atoi(av[1]) * sizeof(t_philo))))
return (NULL);
i = -1;
while (++i < ft_atoi(av[1]))
{
philos[i].id = i;
philos[i].state = SLEEP;
philos[i].last_eat = SLEEP;
philos[i].nbr_of_eats = 0;
philos[i].data = data;
}
return (philos);
}

View File

@@ -0,0 +1,109 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_data.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 14:07:28 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:32:23 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
check_int(char **av, int index)
{
int test_i;
char *test;
test_i = ft_atoi(av[index]);
if (test_i > 100000)
return (1);
test = ft_itoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_uli(char **av, int index)
{
int test_i;
char *test;
if (av[index][0] == '-')
return (1);
test_i = ft_atouli(av[index]);
test = ft_ulitoa(test_i);
if (ft_strcmp(av[index], test))
{
free(test);
return (1);
}
free(test);
return (0);
}
static int
check_data(int ac, char **av)
{
if (check_int(av, 1))
return (1);
if (ft_atoi(av[1]) < 1)
return (1);
if (check_uli(av, 2))
return (1);
if (check_uli(av, 3))
return (1);
if (check_uli(av, 4))
return (1);
if (ac == 6)
{
if (check_int(av, 5))
return (1);
if (ft_atoi(av[5]) < 1)
return (1);
}
return (0);
}
static void
init_data_helper(t_data *data, int ac, char **av)
{
data->routine[EAT] = ft_eat;
data->routine[SLEEP] = ft_sleep;
data->routine[THINK] = ft_think;
data->phi_filled = 0;
data->nbr = ft_atoi(av[1]);
data->time_to_die = ft_atouli(av[2]);
data->time_to_eat = ft_atouli(av[3]);
data->time_to_sleep = ft_atouli(av[4]);
if (ac == 6)
data->max_launch = ft_atoi(av[5]);
else
data->max_launch = -1;
}
t_data
*init_data(int ac, char **av)
{
t_data *data;
int i;
if (check_data(ac, av) || !(data = malloc(sizeof(t_data))))
return (NULL);
data->is_dead = 0;
i = 0;
init_data_helper(data, ac, av);
sem_unlink("forks");
sem_unlink("write_access");
data->forks = sem_open("forks", O_CREAT | O_EXCL, 0644, data->nbr / 2);
data->write_access = sem_open("write_access", O_CREAT | O_EXCL, 0644, 1);
return (data);
}

View File

@@ -0,0 +1,81 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_philos.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:24:12 by lejulien #+# #+# */
/* Updated: 2021/04/21 17:49:22 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static void
*philosopher(void *philos)
{
t_philo *phi;
phi = (t_philo *)philos;
phi->state = (phi->id % 2 == 0) ? SLEEP : THINK;
usleep(500);
while (!phi->data->is_dead && phi->state != DIED)
phi->data->routine[phi->state](phi);
if (phi->state == DIED)
{
display_state(phi);
phi->data->is_dead = 1;
}
sem_post(phi->data->forks);
return (NULL);
}
static void
check_death(t_philo *phi)
{
int i;
i = 0;
while (1)
{
if (ft_get_ct(&phi[i].start) - phi[i].last_eat > phi->data->time_to_die
&& (phi[i].state != EAT || phi->data->time_to_die <
phi->data->time_to_eat))
{
if (phi[i].state == THINK)
{
phi[i].state = DIED;
display_state(&phi[i]);
phi[i].state = THINK;
phi->data->is_dead = 1;
}
else
phi[i].state = DIED;
break ;
}
if (phi->data->phi_filled == phi->data->nbr)
phi->data->is_dead = 1;
i++;
(i == phi->data->nbr) ? i = 0 : 0;
}
}
void
init_philos(t_philo *philos)
{
int i;
pthread_t origin[philos->data->nbr];
i = -1;
while (++i < philos->data->nbr)
{
gettimeofday(&philos[i].start, NULL);
pthread_create(&origin[i], NULL, philosopher, &philos[i]);
}
usleep(2000);
check_death(philos);
i = -1;
while (++i < philos->data->nbr)
pthread_join(origin[i], NULL);
}

View File

@@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:19 by lejulien #+# #+# */
/* Updated: 2021/04/17 16:49:27 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
static int
print_usage(void)
{
write(2, "Usage : ./philo_one nbr_of_philos time_to_die time_", 51);
write(2, "to_eat time_to_sleep [minimum_eat_for_each_philos]\n", 51);
return (1);
}
static void
free_data(t_data *data, char **av)
{
sem_close(data->forks);
sem_unlink("forks");
sem_close(data->write_access);
sem_unlink("write_access");
free(data);
}
int
main(int ac, char **av)
{
t_philo *philos;
t_data *data;
philos = NULL;
if (ac == 5 || ac == 6)
{
if (!(data = init_data(ac, av)))
return (print_usage());
if (!(philos = gen_philos(ac, av, data)))
{
free_data(data, av);
return (print_usage());
}
init_philos(philos);
free_data(data, av);
free(philos);
}
else
return (print_usage());
return (0);
}

View File

@@ -0,0 +1,63 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philo.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 13:48:57 by lejulien #+# #+# */
/* Updated: 2021/04/17 16:51:58 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PHILO_H
# define PHILO_H
# include "../utils/utils.h"
# include <sys/time.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <pthread.h>
# include <semaphore.h>
# include <fcntl.h>
# include <sys/stat.h>
# define EAT 0
# define SLEEP 1
# define THINK 2
# define DIED 3
typedef struct s_data
{
int nbr;
unsigned long int time_to_die;
unsigned long int time_to_eat;
unsigned long int time_to_sleep;
int max_launch;
int phi_filled;
sem_t *forks;
sem_t *write_access;
int is_dead;
void (*routine[4])(void *);
} t_data;
typedef struct s_philo
{
int id;
int state;
struct timeval start;
t_data *data;
int nbr_of_eats;
unsigned long int last_eat;
} t_philo;
t_data *init_data(int ac, char **av);
t_philo *gen_philos(int ac, char **av, t_data *data);
unsigned long int ft_get_ct(struct timeval *start);
void init_philos(t_philo *philos);
void display_state(t_philo *ptr);
int ft_usleep(unsigned long int time, t_philo *phi);
void ft_eat(void *ptr);
void ft_sleep(void *ptr);
void ft_think(void *ptr);
void check_fork(t_philo *phi);
#endif

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* time.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/16 16:42:27 by lejulien #+# #+# */
/* Updated: 2021/04/17 15:52:31 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
unsigned long int
ft_get_ct(struct timeval *start)
{
struct timeval now;
gettimeofday(&now, NULL);
return (((now.tv_sec * 1000000 + now.tv_usec) -
(start->tv_sec * 1000000 + start->tv_usec)) / 1000);
}
int
ft_usleep(unsigned long int time, t_philo *phi)
{
unsigned long int now;
now = ft_get_ct(&phi->start);
while (!phi->data->is_dead && ft_get_ct(&phi->start) - now < time)
{
usleep(500);
if (phi->state == DIED)
return (1);
}
return (0);
}

74
philo_two/srcs/utils/ft_atoi.c Executable file
View File

@@ -0,0 +1,74 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/05 13:06:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:34:00 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
static int
ft_isspace(char c)
{
if ((c == '\f') || (c == '\t') || (c == '\n') || (c == '\r')
|| (c == '\v') || (c == ' '))
{
return (1);
}
return (0);
}
int
ft_atoi(const char *str)
{
int nbr;
int sign;
int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}
unsigned long int
ft_atouli(const char *str)
{
unsigned long int nbr;
int sign;
unsigned long int index;
nbr = 0;
sign = 1;
index = 0;
while ((ft_isspace(str[index]) == 1) && str[index] != '\0')
index++;
if ((str[index] == '+') || (str[index] == '-'))
{
if (str[index] == '-')
sign = -1;
index++;
}
while ((str[index] >= '0') && (str[index] <= '9'))
{
nbr = (nbr * 10) + (str[index] - '0');
index++;
}
return (sign * nbr);
}

View File

@@ -0,0 +1,111 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_itoa.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/15 10:35:00 by lejulien #+# #+# */
/* Updated: 2021/04/15 11:15:45 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
static char *ft_itoa2(int iszero, unsigned int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_itoa(int n)
{
unsigned int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}
static char *ft_ulitoa2(int iszero, unsigned long int nu, int i)
{
char *res;
if (!(res = malloc((i + 1) * sizeof(char))))
return (0);
res[i] = '\0';
while (nu > 0)
{
i--;
res[i] = nu % 10 + '0';
nu = nu / 10;
}
i--;
if (iszero)
{
res[i] = nu + '0';
i--;
}
if (i == 0)
res[i] = '-';
return (res);
}
char *ft_ulitoa(unsigned long int n)
{
unsigned long int nu;
int i;
int iszero;
i = 0;
if (n <= 0)
{
nu = -n;
i++;
}
else
nu = n;
iszero = 0;
while (n != 0)
{
n = n / 10;
i++;
}
if (nu == 0)
iszero++;
return (ft_itoa2(iszero, nu, i));
}

View File

@@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/03/31 15:46:04 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:58:32 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
int ft_strcmp(char *s1, char *s2)
{
int index;
index = 0;
while (s2[index] && s1[index])
{
if (s1[index] == s2[index])
index++;
else
return (1);
}
if (s1[index] == '\0' && s2[index] == '\0')
return (0);
return (1);
}

21
philo_two/srcs/utils/utils.h Executable file
View File

@@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lejulien <lejulien@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/04/03 15:42:26 by lejulien #+# #+# */
/* Updated: 2021/04/15 10:54:39 by lejulien ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef UTILS_H
# define UTILS_H
int ft_atoi(char *str);
unsigned long int ft_atouli(char *str);
char *ft_itoa(int n);
char *ft_ulitoa(unsigned long int n);
int ft_strcmp(char *s1, char *s2);
#endif