intra to gitea
This commit is contained in:
commit
34c92494e8
|
|
@ -0,0 +1,82 @@
|
|||
# **************************************************************************** #
|
||||
# #
|
||||
# ::: :::::::: #
|
||||
# Makefile :+: :+: :+: #
|
||||
# +:+ +:+ +:+ #
|
||||
# By: lfirmin lfirmim@student.42.fr> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# Created: 2024/08/12 07:07:31 by lfirmin #+# #+# #
|
||||
# Updated: 2024/08/12 09:15:05 by lfirmin ### ########.fr #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
NAME = philo
|
||||
SRC_FILES = main.c parsing.c utils.c utils_2.c routine.c threads.c routine_utils.c init.c death.c routine_utils_2.c
|
||||
INCLUDES_FILES = include/philo.h
|
||||
SRC_DIR = srcs/
|
||||
SRC = $(addprefix $(SRC_DIR), $(SRC_FILES))
|
||||
OBJ_DIR = obj/
|
||||
OBJ = $(addprefix $(OBJ_DIR), $(SRC_FILES:.c=.o))
|
||||
CC = cc
|
||||
CFLAGS = -Wall -Werror -Wextra -g3 -pthread
|
||||
INCLUDE = -I include
|
||||
RM = rm -rf
|
||||
MKDIR = mkdir -p
|
||||
|
||||
GREEN = \033[0;32m
|
||||
YELLOW = \033[0;33m
|
||||
CYAN = \033[0;36m
|
||||
RESET = \033[0m
|
||||
BOLD = \033[1m
|
||||
WHITE = \033[0;97m
|
||||
|
||||
LOADING_CHARS = ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏
|
||||
|
||||
define PHILO_ART
|
||||
|
||||
|||| _____ _ _ _ ||||
|
||||
|||| | __ \| | (_) | ||||
|
||||
\__/ | |__) | |__ _| | ___ \__/
|
||||
|| | ___/| '_ \| | |/ _ \ ||
|
||||
|| | | | | | | | | (_) | ||
|
||||
|| |_| |_| |_|_|_|\___/ ||
|
||||
"" ""
|
||||
endef
|
||||
export PHILO_ART
|
||||
|
||||
all: print_art $(NAME)
|
||||
|
||||
print_art:
|
||||
@printf "$(YELLOW)%s$(RESET)\n" "$$PHILO_ART"
|
||||
|
||||
$(NAME): $(OBJ) $(INCLUDES_FILES)
|
||||
@printf "$(BOLD)$(WHITE)Welcome to the $(GREEN)Philosophers$(WHITE) compilation process.\nPlease hold on as we prepare your program.\n\n$(RESET)"
|
||||
@printf "$(YELLOW)Compiling Philosophers, Please wait...$(RESET)"
|
||||
@for char in $(LOADING_CHARS); do \
|
||||
printf "\r$(YELLOW)Compiling Philosophers, Please wait... $$char$(RESET)"; \
|
||||
sleep 0.1; \
|
||||
done
|
||||
@$(CC) $(CFLAGS) $(OBJ) $(INCLUDE) -o $(NAME)
|
||||
@printf "\r$(GREEN)Nice ! $(WHITE)Philosophers compiled successfully ! $(RESET)\n\n"
|
||||
@printf "$(BOLD)$(WHITE)Compilation complete !\n$(GREEN)Philosophers$(WHITE) is ready to use !\n"
|
||||
|
||||
$(OBJ_DIR)%.o: $(SRC_DIR)%.c
|
||||
@$(MKDIR) $(OBJ_DIR)
|
||||
@$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@$(RM) $(OBJ_DIR)
|
||||
@printf "$(WHITE)Clean process completed for $(GREEN)Philosophers.$(RESET)\n"
|
||||
|
||||
fclean: clean
|
||||
@$(RM) $(NAME)
|
||||
@$(RM) $(PRINTF)
|
||||
@$(RM) $(LIBFT)
|
||||
@printf "$(WHITE)Full clean process completed for $(GREEN)Philosophers.$(RESET)\n"
|
||||
|
||||
re: fclean all
|
||||
|
||||
.PHONY: all clean fclean re print_art norminette
|
||||
|
||||
norminette:
|
||||
norminette srcs/* include/* | grep "Error"
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* philo.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/21 15:38:19 by lfirmin #+# #+# */
|
||||
/* Updated: 2024/11/21 15:38:19 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef PHILO_H
|
||||
# define PHILO_H
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <limits.h>
|
||||
# include <pthread.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
|
||||
# define USAGE_MESS "Usage ► ./philo <number_of_philosophers> <time_to_die> \
|
||||
<time_to_eat> <time_to_sleep> [number_of_times_each_philosopher_must_eat]"
|
||||
|
||||
typedef struct s_philo
|
||||
{
|
||||
long long id;
|
||||
int l_fork;
|
||||
int r_fork;
|
||||
long long last_meal;
|
||||
int m_eaten;
|
||||
pthread_t thread;
|
||||
pthread_mutex_t meal_lock;
|
||||
struct s_data *data;
|
||||
} t_philo;
|
||||
|
||||
typedef struct s_data
|
||||
{
|
||||
long long nb_philo;
|
||||
long long t_die;
|
||||
long long t_eat;
|
||||
long long t_sleep;
|
||||
long long must_eat;
|
||||
long long start_time;
|
||||
pthread_mutex_t *forks;
|
||||
pthread_mutex_t print;
|
||||
pthread_mutex_t dead_mutex;
|
||||
int dead_flag;
|
||||
t_philo *philos;
|
||||
int threads_active;
|
||||
pthread_mutex_t threads_count_mutex;
|
||||
pthread_cond_t threads_done_cond;
|
||||
} t_data;
|
||||
|
||||
//utils//
|
||||
long long ft_atoll(const char *str);
|
||||
t_data *init_data(void);
|
||||
void free_data(t_data *data);
|
||||
long long get_time(void);
|
||||
void *death_check(void *arg);
|
||||
int create_threads(t_data *data);
|
||||
int check_if_dead(t_philo *philo);
|
||||
int check_if_dead_data(t_data *data);
|
||||
int print_message(t_philo *philo, char *message);
|
||||
|
||||
//init//
|
||||
int init_forks(t_data *data);
|
||||
int init_philos(t_data *data);
|
||||
int init_philo_forks(t_data *data);
|
||||
|
||||
//parsing//
|
||||
void ft_put_and_check_2(t_data *data, char **av, int *c);
|
||||
int ft_put_and_check(t_data *data, char **av);
|
||||
int validate_number(char **av, int i);
|
||||
int ft_check_av(char **av);
|
||||
int parsing(int ac, char **av, t_data *data);
|
||||
|
||||
//routine//
|
||||
int thinking(t_philo *philo);
|
||||
int sleeping(t_philo *philo);
|
||||
int eating(t_philo *philo);
|
||||
void philo_routine_init(t_philo *philo);
|
||||
void *philo_routine(void *arg);
|
||||
|
||||
//routine_utils//
|
||||
int eating_1_philo(t_philo *philo);
|
||||
int take_fork_and_eat(t_philo *philo);
|
||||
int take_fork_and_eat_alt(t_philo *philo);
|
||||
int safe_sleep(t_philo *philo, long time);
|
||||
int take_fork(t_philo *philo);
|
||||
int ft_should_continue(t_philo *philo);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* death.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:20:46 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 04:52:57 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
void set_dead_and_print(t_data *data, int philo_idx, long long current_time)
|
||||
{
|
||||
pthread_mutex_lock(&data->dead_mutex);
|
||||
data->dead_flag = 1;
|
||||
pthread_mutex_unlock(&data->dead_mutex);
|
||||
pthread_mutex_unlock(&data->philos[philo_idx].meal_lock);
|
||||
pthread_mutex_lock(&data->print);
|
||||
printf("%lld %lld died\n", current_time - data->start_time,
|
||||
data->philos[philo_idx].id);
|
||||
pthread_mutex_unlock(&data->print);
|
||||
}
|
||||
|
||||
static void set_all_ate_and_print(t_data *data)
|
||||
{
|
||||
pthread_mutex_lock(&data->dead_mutex);
|
||||
data->dead_flag = 1;
|
||||
pthread_mutex_unlock(&data->dead_mutex);
|
||||
pthread_mutex_lock(&data->print);
|
||||
printf("Each philosopher has eaten %lld times\n", data->must_eat);
|
||||
pthread_mutex_unlock(&data->print);
|
||||
}
|
||||
|
||||
static int check_philo_death(t_data *data, int idx, int *all_ate_enough)
|
||||
{
|
||||
long long current_time;
|
||||
long long time_since_last_meal;
|
||||
|
||||
if (check_if_dead_data(data))
|
||||
return (1);
|
||||
pthread_mutex_lock(&data->philos[idx].meal_lock);
|
||||
current_time = get_time();
|
||||
time_since_last_meal = current_time - data->philos[idx].last_meal;
|
||||
if (time_since_last_meal > data->t_die)
|
||||
{
|
||||
set_dead_and_print(data, idx, current_time);
|
||||
return (1);
|
||||
}
|
||||
if (data->must_eat != -1 && data->philos[idx].m_eaten < data->must_eat)
|
||||
*all_ate_enough = 0;
|
||||
pthread_mutex_unlock(&data->philos[idx].meal_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int check_all_philos(t_data *data)
|
||||
{
|
||||
int i;
|
||||
int all_ate_enough;
|
||||
|
||||
i = 0;
|
||||
all_ate_enough = 1;
|
||||
while (i < data->nb_philo)
|
||||
{
|
||||
if (check_philo_death(data, i, &all_ate_enough))
|
||||
return (1);
|
||||
i++;
|
||||
}
|
||||
if (data->must_eat != -1 && all_ate_enough && !check_if_dead_data(data))
|
||||
{
|
||||
set_all_ate_and_print(data);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *death_check(void *arg)
|
||||
{
|
||||
t_data *data;
|
||||
|
||||
data = (t_data *)arg;
|
||||
while (1)
|
||||
{
|
||||
if (check_if_dead_data(data))
|
||||
return (NULL);
|
||||
usleep(500);
|
||||
if (check_all_philos(data))
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* init.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:20:46 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 04:12:57 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
int init_forks(t_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < data->nb_philo)
|
||||
{
|
||||
if (pthread_mutex_init(&data->forks[i], NULL))
|
||||
return (1);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int init_philos(t_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < data->nb_philo)
|
||||
{
|
||||
data->philos[i].id = i + 1;
|
||||
data->philos[i].l_fork = i;
|
||||
data->philos[i].r_fork = (i + 1) % data->nb_philo;
|
||||
data->philos[i].last_meal = data->start_time;
|
||||
data->philos[i].m_eaten = 0;
|
||||
data->philos[i].data = data;
|
||||
if (pthread_mutex_init(&data->philos[i].meal_lock, NULL))
|
||||
return (1);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int init_all(t_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
if (init_philo_forks(data))
|
||||
return (printf("Error : Failed to allocate memory\n"), 1);
|
||||
if (init_forks(data))
|
||||
{
|
||||
free(data->philos);
|
||||
free(data->forks);
|
||||
return (printf("Error : Failed to initialize forks mutex\n"), 1);
|
||||
}
|
||||
if (init_philos(data))
|
||||
{
|
||||
while (++i < data->nb_philo)
|
||||
pthread_mutex_destroy(&data->forks[i]);
|
||||
free(data->philos);
|
||||
free(data->forks);
|
||||
return (printf("Error : Failed to initialize philosophers\n"), 1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int init_philo_forks(t_data *data)
|
||||
{
|
||||
data->philos = malloc(sizeof(t_philo) * data->nb_philo);
|
||||
if (!data->philos)
|
||||
return (1);
|
||||
data->forks = malloc(sizeof(pthread_mutex_t) * data->nb_philo);
|
||||
if (!data->forks)
|
||||
return (free(data->philos), 1);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* main.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/21 15:42:31 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/04/17 13:48:43 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../include/philo.h"
|
||||
|
||||
int setup_simulation(int ac, char **av, t_data **data, pthread_t *death_thread)
|
||||
{
|
||||
*data = init_data();
|
||||
if (!*data)
|
||||
return (1);
|
||||
if (parsing(ac, av, *data))
|
||||
return (free_data(*data), 1);
|
||||
if ((*data)->t_die <= 0 || (*data)->t_eat <= 0 || (*data)->t_sleep <= 0)
|
||||
{
|
||||
printf("Error: Time values must be positive integers\n");
|
||||
return (free_data(*data), 1);
|
||||
}
|
||||
if (init_philo_forks(*data))
|
||||
return (free_data(*data), 1);
|
||||
if (init_forks(*data))
|
||||
return (free_data(*data), 1);
|
||||
(*data)->start_time = get_time();
|
||||
if (init_philos(*data))
|
||||
return (free_data(*data), 1);
|
||||
if (pthread_create(death_thread, NULL, &death_check, *data))
|
||||
{
|
||||
printf("Error: Failed to create death check thread\n");
|
||||
return (free_data(*data), 1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
t_data *data;
|
||||
pthread_t death_thread;
|
||||
|
||||
if (setup_simulation(ac, av, &data, &death_thread))
|
||||
return (1);
|
||||
if (create_threads(data))
|
||||
{
|
||||
pthread_mutex_lock(&data->dead_mutex);
|
||||
data->dead_flag = 1;
|
||||
pthread_mutex_unlock(&data->dead_mutex);
|
||||
pthread_join(death_thread, NULL);
|
||||
printf("Error: Failed to create philosopher threads\n");
|
||||
return (free_data(data), 1);
|
||||
}
|
||||
if (pthread_join(death_thread, NULL))
|
||||
{
|
||||
printf("Error: Failed to join death check thread\n");
|
||||
return (free_data(data), 1);
|
||||
}
|
||||
return (free_data(data), 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parsing.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/21 16:16:19 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 04:00:28 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
int ft_put_and_check(t_data *data, char **av)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
data->nb_philo = ft_atoll(av[1]);
|
||||
if (data->nb_philo <= 0)
|
||||
(printf("Error : Invalid number of philo, expected 1 "\
|
||||
"or more, You gave \"%s\"\n", av[1]), c++);
|
||||
data->t_die = ft_atoll(av[2]);
|
||||
if (data->t_die <= 0)
|
||||
(printf("Error : Invalid time for die, expected 1ms "\
|
||||
"or more, You gave \"%s\"\n", av[2]), c++);
|
||||
data->t_eat = ft_atoll(av[3]);
|
||||
if (data->t_eat < 0 || !av[3][0])
|
||||
(printf("Error : Invalid time for eat, expected 0ms "\
|
||||
"or more, You gave \"%s\"\n", av[3]), c++);
|
||||
data->t_sleep = ft_atoll(av[4]);
|
||||
if (data->t_sleep < 0 || !av[4][0])
|
||||
(printf("Error : Invalid time for sleep, expected 0ms "\
|
||||
"or more, You gave \"%s\"\n", av[4]), c++);
|
||||
if (av[5] != NULL)
|
||||
ft_put_and_check_2(data, av, &c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
void ft_put_and_check_2(t_data *data, char **av, int *c)
|
||||
{
|
||||
data->must_eat = ft_atoll(av[5]);
|
||||
if (data->must_eat < 1)
|
||||
(printf("Error : Invalid number of philo must eat, expected 1 or more"\
|
||||
", You gave \"%s\"\n", av[5]), (*c)++);
|
||||
}
|
||||
|
||||
int ft_check_av(char **av)
|
||||
{
|
||||
int i;
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
i = 1;
|
||||
while (av[i])
|
||||
{
|
||||
if (validate_number(av, i) == 1)
|
||||
(printf("Error : argument %d isn't a number\n", i + 1), c++);
|
||||
i++;
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
int validate_number(char **av, int i)
|
||||
{
|
||||
int j;
|
||||
|
||||
j = 0;
|
||||
while (av[i][j])
|
||||
{
|
||||
if ((av[i][j] < '0' || av[i][j] > '9') && \
|
||||
(av[i][j] != '-' && av[i][j] != '+'))
|
||||
return (1);
|
||||
if (av[i][j] == '-' || av[i][j] == '+')
|
||||
{
|
||||
if (av[i][j + 1] < '0' || av[i][j + 1] > '9' || j != 0)
|
||||
return (1);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int parsing(int ac, char **av, t_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ac < 5 || ac > 6)
|
||||
return (printf("%s\n", USAGE_MESS), 1);
|
||||
ret = ft_check_av(av);
|
||||
if (ret != 0)
|
||||
return (1);
|
||||
ret = ft_put_and_check(data, av);
|
||||
if (ret != 0)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* routine.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:47:26 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/04/17 14:27:04 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
int eating(t_philo *philo)
|
||||
{
|
||||
if (!philo)
|
||||
return (1);
|
||||
if (check_if_dead(philo))
|
||||
return (1);
|
||||
if (take_fork_and_eat(philo))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int sleeping(t_philo *philo)
|
||||
{
|
||||
if (check_if_dead(philo))
|
||||
return (1);
|
||||
print_message(philo, "is sleeping");
|
||||
if (safe_sleep(philo, philo->data->t_sleep * 1000))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int thinking(t_philo *philo)
|
||||
{
|
||||
if (print_message(philo, "is thinking"))
|
||||
return (1);
|
||||
if (philo->data->nb_philo % 2 == 0)
|
||||
{
|
||||
if (philo->data->t_eat > philo->data->t_sleep)
|
||||
usleep((philo->data->t_eat - philo->data->t_sleep) * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (2 * philo->data->t_eat > philo->data->t_sleep)
|
||||
usleep((2 * philo->data->t_eat - philo->data->t_sleep) * 1000);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void philo_routine_init(t_philo *philo)
|
||||
{
|
||||
if (philo->id % 2 == 0)
|
||||
{
|
||||
if (philo->data->nb_philo > 100)
|
||||
usleep(500);
|
||||
else
|
||||
usleep(1000);
|
||||
}
|
||||
pthread_mutex_lock(&philo->meal_lock);
|
||||
philo->last_meal = get_time();
|
||||
pthread_mutex_unlock(&philo->meal_lock);
|
||||
}
|
||||
|
||||
void *philo_routine(void *arg)
|
||||
{
|
||||
t_philo *philo;
|
||||
int should_continue;
|
||||
|
||||
philo = (t_philo *)arg;
|
||||
if (philo->data->nb_philo == 1)
|
||||
return (eating_1_philo(philo), NULL);
|
||||
if (philo->id % 2 == 0)
|
||||
usleep(philo->data->t_eat * 500);
|
||||
while (1)
|
||||
{
|
||||
pthread_mutex_lock(&philo->data->dead_mutex);
|
||||
should_continue = ft_should_continue(philo);
|
||||
pthread_mutex_unlock(&philo->data->dead_mutex);
|
||||
if (!should_continue)
|
||||
break ;
|
||||
if (eating(philo) == 1)
|
||||
break ;
|
||||
if (sleeping(philo) == 1)
|
||||
break ;
|
||||
if (thinking(philo) == 1)
|
||||
break ;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* routine_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:47:26 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 03:59:51 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
int eating_1_philo(t_philo *philo)
|
||||
{
|
||||
pthread_mutex_lock(&philo->data->forks[philo->l_fork]);
|
||||
print_message(philo, "has taken a fork");
|
||||
safe_sleep(philo, philo->data->t_die * 1000);
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->l_fork]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int safe_sleep(t_philo *philo, long time)
|
||||
{
|
||||
long long start_t;
|
||||
long long target_time;
|
||||
long sleep_interval;
|
||||
|
||||
start_t = get_time();
|
||||
target_time = start_t + (time / 1000);
|
||||
if (philo->data->nb_philo > 150)
|
||||
sleep_interval = 400;
|
||||
else if (philo->data->nb_philo > 100)
|
||||
sleep_interval = 300;
|
||||
else if (philo->data->nb_philo > 50)
|
||||
sleep_interval = 200;
|
||||
else
|
||||
sleep_interval = 100;
|
||||
while (get_time() < target_time)
|
||||
{
|
||||
if (check_if_dead(philo))
|
||||
return (1);
|
||||
usleep(sleep_interval);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int take_fork_2(t_philo *philo)
|
||||
{
|
||||
pthread_mutex_lock(&philo->data->forks[philo->r_fork]);
|
||||
if (check_if_dead(philo))
|
||||
return (pthread_mutex_unlock(&philo->data->forks[philo->r_fork]), 1);
|
||||
if (print_message(philo, "has taken a fork"))
|
||||
return (pthread_mutex_unlock(&philo->data->forks[philo->r_fork]), 1);
|
||||
pthread_mutex_lock(&philo->data->forks[philo->l_fork]);
|
||||
if (check_if_dead(philo))
|
||||
{
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->l_fork]);
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->r_fork]);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int take_fork(t_philo *philo)
|
||||
{
|
||||
if (check_if_dead(philo))
|
||||
return (1);
|
||||
if (philo->l_fork < philo->r_fork)
|
||||
{
|
||||
pthread_mutex_lock(&philo->data->forks[philo->l_fork]);
|
||||
if (check_if_dead(philo))
|
||||
return (pthread_mutex_unlock
|
||||
(&philo->data->forks[philo->l_fork]), 1);
|
||||
if (print_message(philo, "has taken a fork"))
|
||||
return (pthread_mutex_unlock
|
||||
(&philo->data->forks[philo->l_fork]), 1);
|
||||
pthread_mutex_lock(&philo->data->forks[philo->r_fork]);
|
||||
if (check_if_dead(philo))
|
||||
{
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->r_fork]);
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->l_fork]);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (take_fork_2(philo))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* routine_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:47:26 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 03:59:51 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
void unlock_forks(t_philo *philo)
|
||||
{
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->r_fork]);
|
||||
pthread_mutex_unlock(&philo->data->forks[philo->l_fork]);
|
||||
}
|
||||
|
||||
int take_fork_and_eat(t_philo *philo)
|
||||
{
|
||||
long long current_time;
|
||||
int sleep_result;
|
||||
|
||||
if (check_if_dead(philo))
|
||||
return (1);
|
||||
if (take_fork(philo))
|
||||
return (1);
|
||||
if (print_message(philo, "has taken a fork"))
|
||||
{
|
||||
unlock_forks(philo);
|
||||
return (1);
|
||||
}
|
||||
current_time = get_time();
|
||||
pthread_mutex_lock(&philo->meal_lock);
|
||||
philo->last_meal = current_time;
|
||||
pthread_mutex_unlock(&philo->meal_lock);
|
||||
if (print_message(philo, "is eating"))
|
||||
return (unlock_forks(philo), 1);
|
||||
pthread_mutex_lock(&philo->meal_lock);
|
||||
philo->m_eaten++;
|
||||
pthread_mutex_unlock(&philo->meal_lock);
|
||||
sleep_result = safe_sleep(philo, philo->data->t_eat * 1000);
|
||||
return (unlock_forks(philo), sleep_result);
|
||||
}
|
||||
|
||||
int ft_should_continue(t_philo *philo)
|
||||
{
|
||||
if (philo->data->dead_flag)
|
||||
return (0);
|
||||
else if (philo->data->must_eat != -1)
|
||||
{
|
||||
if (philo->m_eaten >= philo->data->must_eat)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* threads.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 15:42:23 by lfirmin #+# #+# */
|
||||
/* Updated: 2024/11/22 15:44:44 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
int create_threads(t_data *data)
|
||||
{
|
||||
int i;
|
||||
pthread_t *threads;
|
||||
|
||||
i = 0;
|
||||
threads = malloc(sizeof(pthread_t) * data->nb_philo);
|
||||
if (!threads)
|
||||
return (1);
|
||||
while (i < data->nb_philo)
|
||||
{
|
||||
if (pthread_create(&data->philos[i].thread,
|
||||
NULL, &philo_routine, &data->philos[i]))
|
||||
{
|
||||
pthread_mutex_lock(&data->dead_mutex);
|
||||
data->dead_flag = 1;
|
||||
pthread_mutex_unlock(&data->dead_mutex);
|
||||
return (free(threads), 1);
|
||||
}
|
||||
threads[i] = data->philos[i].thread;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (i < data->nb_philo)
|
||||
pthread_join(threads[i++], NULL);
|
||||
return (free(threads), 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/21 17:11:19 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 04:00:00 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
t_data *init_data(void)
|
||||
{
|
||||
t_data *data;
|
||||
|
||||
data = malloc(sizeof(t_data));
|
||||
if (!data)
|
||||
return (NULL);
|
||||
data->nb_philo = 0;
|
||||
data->t_die = 0;
|
||||
data->t_eat = 0;
|
||||
data->t_sleep = 0;
|
||||
data->must_eat = -1;
|
||||
data->dead_flag = 0;
|
||||
data->forks = NULL;
|
||||
data->philos = NULL;
|
||||
data->start_time = 0;
|
||||
if (pthread_mutex_init(&data->print, NULL))
|
||||
return (free(data), NULL);
|
||||
if (pthread_mutex_init(&data->dead_mutex, NULL))
|
||||
return (free(data), NULL);
|
||||
return (data);
|
||||
}
|
||||
|
||||
void free_data(t_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (data)
|
||||
{
|
||||
if (data->forks)
|
||||
{
|
||||
i = -1;
|
||||
while (++i < data->nb_philo)
|
||||
{
|
||||
pthread_mutex_destroy(&data->forks[i]);
|
||||
pthread_mutex_destroy(&data->philos[i].meal_lock);
|
||||
}
|
||||
free(data->forks);
|
||||
}
|
||||
if (data->philos)
|
||||
free(data->philos);
|
||||
pthread_mutex_destroy(&data->print);
|
||||
pthread_mutex_destroy(&data->dead_mutex);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
long long ft_atoll(const char *str)
|
||||
{
|
||||
long long result;
|
||||
int sign;
|
||||
|
||||
result = 0;
|
||||
sign = 1;
|
||||
while (*str == ' ' || (*str >= 9 && *str <= 13))
|
||||
str++;
|
||||
if (*str == '-' || *str == '+')
|
||||
{
|
||||
if (*str == '-')
|
||||
sign = -1;
|
||||
str++;
|
||||
}
|
||||
while (*str >= '0' && *str <= '9')
|
||||
{
|
||||
if (result > INT_MAX || result < INT_MIN)
|
||||
return (2147483648);
|
||||
result = result * 10 + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
return (result * sign);
|
||||
}
|
||||
|
||||
int check_if_dead(t_philo *philo)
|
||||
{
|
||||
int result;
|
||||
|
||||
pthread_mutex_lock(&philo->data->dead_mutex);
|
||||
result = philo->data->dead_flag;
|
||||
pthread_mutex_unlock(&philo->data->dead_mutex);
|
||||
return (result);
|
||||
}
|
||||
|
||||
int check_if_dead_data(t_data *data)
|
||||
{
|
||||
int result;
|
||||
|
||||
pthread_mutex_lock(&data->dead_mutex);
|
||||
result = data->dead_flag;
|
||||
pthread_mutex_unlock(&data->dead_mutex);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils_2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/22 14:20:46 by lfirmin #+# #+# */
|
||||
/* Updated: 2025/03/17 04:00:06 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include "../include/philo.h"
|
||||
|
||||
long long get_time(void)
|
||||
{
|
||||
struct timeval time;
|
||||
|
||||
if (gettimeofday(&time, NULL) == -1)
|
||||
return (write(2, "gettimeofday() error\n", 22), 0);
|
||||
return ((time.tv_sec * 1000) + (time.tv_usec / 1000));
|
||||
}
|
||||
|
||||
int print_message(t_philo *philo, char *message)
|
||||
{
|
||||
int is_dead;
|
||||
|
||||
pthread_mutex_lock(&philo->data->dead_mutex);
|
||||
is_dead = philo->data->dead_flag;
|
||||
pthread_mutex_unlock(&philo->data->dead_mutex);
|
||||
if (is_dead)
|
||||
return (1);
|
||||
if (pthread_mutex_lock(&philo->data->print) != 0)
|
||||
return (1);
|
||||
pthread_mutex_lock(&philo->data->dead_mutex);
|
||||
is_dead = philo->data->dead_flag;
|
||||
pthread_mutex_unlock(&philo->data->dead_mutex);
|
||||
if (is_dead)
|
||||
return (pthread_mutex_unlock(&philo->data->print), 1);
|
||||
printf("%lld %lld %s\n", get_time()
|
||||
- philo->data->start_time, philo->id, message);
|
||||
pthread_mutex_unlock(&philo->data->print);
|
||||
return (0);
|
||||
}
|
||||
Loading…
Reference in New Issue