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

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