mirror of
https://github.com/Ladebeze66/philosophers.git
synced 2026-11-09 13:47:13 +01:00
philosophers
This commit is contained in:
76
Makefile
Executable file
76
Makefile
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# Makefile :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2023/10/23 16:10:39 by fgras-ca #+# #+# #
|
||||||
|
# Updated: 2023/10/23 16:10:46 by fgras-ca ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
LOGO = @echo " __, ____, ____, ____, ____ ____, ___, ____,";\
|
||||||
|
echo "(-| (-/_| (-| \ (-|_, (-|__) (-|_, (- / (-|_,";\
|
||||||
|
echo " _|__, _/ |, _|__/ _|__, _|__) _|__, _/__, _|__,";\
|
||||||
|
echo "( ( ( ( ( ( ( ("
|
||||||
|
|
||||||
|
RST = \033[0m
|
||||||
|
GRAY = \033[0;90m
|
||||||
|
RED = \033[0;91m
|
||||||
|
GREEN = \033[0;92m
|
||||||
|
YELLOW = \033[0;93m
|
||||||
|
BLUE = \033[0;94m
|
||||||
|
MAGENTA = \033[0;95m
|
||||||
|
CYAN = \033[0;96m
|
||||||
|
WHITE = \033[0;97m
|
||||||
|
ORANGE = \033[38;5;214m
|
||||||
|
|
||||||
|
NAME = philo
|
||||||
|
|
||||||
|
SRCS = main.c \
|
||||||
|
threads.c \
|
||||||
|
initialize.c \
|
||||||
|
time.c \
|
||||||
|
philos.c \
|
||||||
|
utils.c \
|
||||||
|
memory.c \
|
||||||
|
routine.c \
|
||||||
|
forks.c \
|
||||||
|
monitoring.c \
|
||||||
|
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
RM = rm -f
|
||||||
|
CFLAGS = -Wall -Werror -Wextra -g
|
||||||
|
|
||||||
|
all: $(NAME)
|
||||||
|
|
||||||
|
$(NAME): $(OBJS)
|
||||||
|
@echo "$(RED)Compilation philosopher... $(RST)"
|
||||||
|
@$(CC) $(CFLAGS) $(OBJS) -o $(NAME) -lpthread
|
||||||
|
@echo "$(GREEN)Compilation complete. $(ORANGE)Type "./philo" for the menu!!$(RST)"
|
||||||
|
$(LOGO)
|
||||||
|
|
||||||
|
t : $(NAME)
|
||||||
|
@echo "$(RED)Compilation philosopher with fsanitize... $(RST)"
|
||||||
|
@$(CC) $(CFLAGS) -fsanitize=thread $(OBJS) -o $(NAME) -lpthread
|
||||||
|
@echo "$(GREEN)Compilation complete. $(ORANGE)Type "./philo" for the menu!!$(RST)"
|
||||||
|
$(LOGO)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "$(RED)Deleating files objects... $(RST)"
|
||||||
|
@$(RM) $(OBJS)
|
||||||
|
@echo "$(GREEN)files deleted!! $(RST)"
|
||||||
|
$(LOGO)
|
||||||
|
|
||||||
|
fclean: clean
|
||||||
|
@echo "$(RED)Deleting program... $(RST)"
|
||||||
|
@$(RM) $(NAME)
|
||||||
|
@echo "$(GREEN)files deleted!! $(RST)"
|
||||||
|
$(LOGO)
|
||||||
|
|
||||||
|
re: fclean all
|
||||||
|
|
||||||
|
.PHONY: all t clean fclean re
|
||||||
BIN
en.subject.pdf
Normal file
BIN
en.subject.pdf
Normal file
Binary file not shown.
69
forks.c
Executable file
69
forks.c
Executable file
@@ -0,0 +1,69 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* forks.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 11:50:15 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/23 16:09:52 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
static void single_philosopher(t_philo *philo)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->left_fork->mutex_fork);
|
||||||
|
print_action(philo, BLUE"has taken a fork🍴"RST, 0);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->sim->end_mutex);
|
||||||
|
if (philo->sim->is_philosopher_dead)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&philo->left_fork->mutex_fork);
|
||||||
|
}
|
||||||
|
|
||||||
|
void take_forks(t_philo *philo)
|
||||||
|
{
|
||||||
|
if (philo->sim->num_philosophers == 1)
|
||||||
|
{
|
||||||
|
single_philosopher(philo);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
usleep(300);
|
||||||
|
if (philo->id % 2 == 0)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->left_fork->mutex_fork);
|
||||||
|
print_action(philo, BLUE"has taken a fork🍴"RST, 0);
|
||||||
|
pthread_mutex_lock(&philo->right_fork->mutex_fork);
|
||||||
|
print_action(philo, BLUE"has taken a fork🍴"RST, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->right_fork->mutex_fork);
|
||||||
|
print_action(philo, BLUE"has taken a fork🍴"RST, 0);
|
||||||
|
pthread_mutex_lock(&philo->left_fork->mutex_fork);
|
||||||
|
print_action(philo, BLUE"has taken a fork🍴"RST, 0);
|
||||||
|
}
|
||||||
|
philo->can_eat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_forks(t_philo *philo)
|
||||||
|
{
|
||||||
|
if (philo->can_eat)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->left_fork->mutex_fork);
|
||||||
|
if (philo->sim->num_philosophers > 1)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->right_fork->mutex_fork);
|
||||||
|
}
|
||||||
|
philo->can_eat = 0;
|
||||||
|
}
|
||||||
|
usleep(300);
|
||||||
|
}
|
||||||
60
initialize.c
Executable file
60
initialize.c
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* initialize.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 11:54:03 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 12:27:25 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
int initialize_default_values(t_simulation *sim)
|
||||||
|
{
|
||||||
|
sim->num_philosophers = 0;
|
||||||
|
sim->time_to_die = 0;
|
||||||
|
sim->time_to_eat = 0;
|
||||||
|
sim->time_to_sleep = 0;
|
||||||
|
sim->max_meals = 0;
|
||||||
|
sim->start_time = initialize_start_time();
|
||||||
|
sim->is_philosopher_dead = 0;
|
||||||
|
sim->simulation_end = 0;
|
||||||
|
pthread_mutex_init(&sim->print_mutex, NULL);
|
||||||
|
pthread_mutex_init(&sim->end_mutex, NULL);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int args_values(t_simulation *sim, int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 5 || argc > 6)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&sim->print_mutex);
|
||||||
|
printf(RED"Usage: %s num_philosophers time_to_die "
|
||||||
|
"time_to_eat time_to_sleep [max_meals]\n" RST, argv[0]);
|
||||||
|
pthread_mutex_unlock(&sim->print_mutex);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sim->num_philosophers = ft_atoi(argv[1]);
|
||||||
|
sim->time_to_die = ft_atoi(argv[2]);
|
||||||
|
sim->time_to_eat = ft_atoi(argv[3]);
|
||||||
|
sim->time_to_sleep = ft_atoi(argv[4]);
|
||||||
|
if (argc == 6)
|
||||||
|
{
|
||||||
|
sim->max_meals = ft_atoi(argv[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int initialize_simulation(t_simulation *sim, int argc, char **argv)
|
||||||
|
{
|
||||||
|
initialize_default_values(sim);
|
||||||
|
args_values(sim, argc, argv);
|
||||||
|
initialize_philosophers(sim);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
23
main.c
Executable file
23
main.c
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* main.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 12:28:04 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 12:29:50 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
t_simulation sim;
|
||||||
|
|
||||||
|
initialize_simulation(&sim, argc, argv);
|
||||||
|
join_threads(&sim);
|
||||||
|
cleanup(&sim);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
44
memory.c
Executable file
44
memory.c
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* clean.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 11:45:37 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 11:48:26 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
int allocate_memory(t_simulation *sim)
|
||||||
|
{
|
||||||
|
sim->forks = ft_calloc(sim->num_philosophers, sizeof(t_fork));
|
||||||
|
if (!sim->forks)
|
||||||
|
return (-1);
|
||||||
|
sim->philos = ft_calloc(sim->num_philosophers, sizeof(t_philo));
|
||||||
|
if (!sim->philos)
|
||||||
|
{
|
||||||
|
free(sim->forks);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&sim->forks[i].mutex_fork);
|
||||||
|
pthread_mutex_destroy(&sim->philos[i].eating_mutex);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
free(sim->philos);
|
||||||
|
free(sim->forks);
|
||||||
|
pthread_mutex_destroy(&sim->end_mutex);
|
||||||
|
pthread_mutex_destroy(&sim->print_mutex);
|
||||||
|
}
|
||||||
106
monitoring.c
Executable file
106
monitoring.c
Executable file
@@ -0,0 +1,106 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* monitoring.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 12:32:18 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/23 16:22:19 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
int check_philosopher_death(t_philo *philo)
|
||||||
|
{
|
||||||
|
long time_since_last_meal;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&philo->eating_mutex);
|
||||||
|
time_since_last_meal = get_time(philo->sim->start_time)
|
||||||
|
- philo->last_meal_time;
|
||||||
|
if (time_since_last_meal <= philo->sim->time_to_die)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->eating_mutex);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&philo->eating_mutex);
|
||||||
|
pthread_mutex_lock(&philo->sim->end_mutex);
|
||||||
|
if (!philo->sim->is_philosopher_dead)
|
||||||
|
{
|
||||||
|
philo->sim->is_philosopher_dead = 1;
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
print_action(philo, RED"died☠️" RST, 1);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int all_philosophers_have_eaten_required_meals(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
if (sim->philos[i].meals_eaten < sim->max_meals)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_all_philosophers_ate(t_philo *philo)
|
||||||
|
{
|
||||||
|
if (!philo->sim->simulation_end)
|
||||||
|
{
|
||||||
|
philo->sim->simulation_end = 1;
|
||||||
|
printf(RED"ALL PHILOSOPHERS EAT %d MEALS!!"RST"\n",
|
||||||
|
philo->sim->max_meals);
|
||||||
|
print_action(philo, NULL, 1);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_max_meals(t_philo *philo)
|
||||||
|
{
|
||||||
|
if (philo->sim->max_meals == 0)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&philo->sim->end_mutex);
|
||||||
|
if (all_philosophers_have_eaten_required_meals(philo->sim))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
return (handle_all_philosophers_ate(philo));
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *philo_monitor(void *arg)
|
||||||
|
{
|
||||||
|
t_philo *philo;
|
||||||
|
int dead;
|
||||||
|
int simulation_end;
|
||||||
|
|
||||||
|
philo = (t_philo *)arg;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->sim->end_mutex);
|
||||||
|
dead = philo->sim->is_philosopher_dead;
|
||||||
|
simulation_end = philo->sim->simulation_end;
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
if (dead || simulation_end)
|
||||||
|
break ;
|
||||||
|
if (check_philosopher_death(philo))
|
||||||
|
return (NULL);
|
||||||
|
if (check_max_meals(philo))
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
91
philo.h
Executable file
91
philo.h
Executable file
@@ -0,0 +1,91 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* philo.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/12 10:44:03 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/23 16:29:16 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef PHILO_H
|
||||||
|
# define PHILO_H
|
||||||
|
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <sys/time.h>
|
||||||
|
# include <pthread.h>
|
||||||
|
# include <limits.h>
|
||||||
|
|
||||||
|
# define RST "\033[0;39m"
|
||||||
|
# define GRAY "\033[0;90m"
|
||||||
|
# define RED "\033[0;91m"
|
||||||
|
# define GREEN "\033[0;92m"
|
||||||
|
# define YELLOW "\033[0;93m"
|
||||||
|
# define BLUE "\033[0;94m"
|
||||||
|
# define MAGENTA "\033[0;95m"
|
||||||
|
# define CYAN "\033[0;96m"
|
||||||
|
# define WHITE "\033[0;97m"
|
||||||
|
# define ORANGE "\033[38;5;214m"
|
||||||
|
|
||||||
|
typedef struct s_simulation t_simulation;
|
||||||
|
|
||||||
|
typedef struct s_fork
|
||||||
|
{
|
||||||
|
pthread_mutex_t mutex_fork;
|
||||||
|
} t_fork;
|
||||||
|
|
||||||
|
typedef struct s_philo
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
int meals_eaten;
|
||||||
|
int can_eat;
|
||||||
|
long last_meal_time;
|
||||||
|
t_fork *left_fork;
|
||||||
|
t_fork *right_fork;
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_t philosopher_monitor;
|
||||||
|
pthread_mutex_t eating_mutex;
|
||||||
|
t_simulation *sim;
|
||||||
|
} t_philo;
|
||||||
|
|
||||||
|
typedef struct s_simulation
|
||||||
|
{
|
||||||
|
int num_philosophers;
|
||||||
|
int time_to_die;
|
||||||
|
int time_to_eat;
|
||||||
|
int time_to_sleep;
|
||||||
|
int max_meals;
|
||||||
|
long start_time;
|
||||||
|
t_philo *philos;
|
||||||
|
t_fork *forks;
|
||||||
|
volatile int is_philosopher_dead;
|
||||||
|
volatile int simulation_end;
|
||||||
|
pthread_mutex_t print_mutex;
|
||||||
|
pthread_mutex_t end_mutex;
|
||||||
|
} t_simulation;
|
||||||
|
|
||||||
|
int initialize_simulation(t_simulation *sim, int argc, char **argv);
|
||||||
|
int initialize_philosophers(t_simulation *sim);
|
||||||
|
int ft_atoi(const char *nptr);
|
||||||
|
int init_threads(t_simulation *sim);
|
||||||
|
int join_threads(t_simulation *sim);
|
||||||
|
int args_values(t_simulation *sim, int argc, char **argv);
|
||||||
|
int initialize_default_values(t_simulation *sim);
|
||||||
|
int allocate_memory(t_simulation *sim);
|
||||||
|
long initialize_start_time(void);
|
||||||
|
long get_time(long start_time);
|
||||||
|
void *philosopher_life(void *arg);
|
||||||
|
void cleanup(t_simulation *sim);
|
||||||
|
void take_forks(t_philo *philo);
|
||||||
|
void release_forks(t_philo *philo);
|
||||||
|
void print_action(t_philo *philo, char *action, int death_action);
|
||||||
|
void eat(t_philo *philo);
|
||||||
|
void think(t_philo *philo);
|
||||||
|
void *philo_monitor(void *arg);
|
||||||
|
void *ft_calloc(size_t nmemb, size_t size);
|
||||||
|
|
||||||
|
#endif
|
||||||
38
philos.c
Executable file
38
philos.c
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* philos.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 14:31:06 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 15:05:24 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
int initialize_philosophers(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
if (allocate_memory(sim) < 0)
|
||||||
|
return (-1);
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
sim->philos[i].id = i + 1;
|
||||||
|
pthread_mutex_init(&sim->forks[i].mutex_fork, NULL);
|
||||||
|
sim->philos[i].left_fork = &sim->forks[i];
|
||||||
|
sim->philos[i].right_fork = &sim->forks[(i + 1)
|
||||||
|
% sim->num_philosophers];
|
||||||
|
sim->philos[i].sim = sim;
|
||||||
|
sim->philos[i].meals_eaten = 0;
|
||||||
|
sim->philos[i].can_eat = 0;
|
||||||
|
sim->philos[i].last_meal_time = get_time(sim->start_time);
|
||||||
|
pthread_mutex_init(&sim->philos[i].eating_mutex, NULL);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
init_threads(sim);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
73
routine.c
Executable file
73
routine.c
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* routine.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 15:20:10 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/23 16:27:02 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
void eat(t_philo *philo)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->eating_mutex);
|
||||||
|
if (get_time(philo->sim->start_time)
|
||||||
|
- philo->last_meal_time > philo->sim->time_to_die)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->eating_mutex);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
if (!philo->can_eat)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&philo->eating_mutex);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
philo->last_meal_time = get_time(philo->sim->start_time);
|
||||||
|
philo->meals_eaten++;
|
||||||
|
usleep(philo->sim->time_to_eat * 1000);
|
||||||
|
pthread_mutex_unlock(&philo->eating_mutex);
|
||||||
|
usleep(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
void philo_sleep(t_philo *philo)
|
||||||
|
{
|
||||||
|
philo->can_eat = 0;
|
||||||
|
usleep(philo->sim->time_to_sleep * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void think(t_philo *philo)
|
||||||
|
{
|
||||||
|
philo->can_eat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *philosopher_life(void *arg)
|
||||||
|
{
|
||||||
|
t_philo *philo;
|
||||||
|
int continue_running;
|
||||||
|
|
||||||
|
philo = (t_philo *)arg;
|
||||||
|
continue_running = 1;
|
||||||
|
while (continue_running)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&philo->sim->end_mutex);
|
||||||
|
continue_running = !philo->sim->is_philosopher_dead
|
||||||
|
&& !philo->sim->simulation_end;
|
||||||
|
pthread_mutex_unlock(&philo->sim->end_mutex);
|
||||||
|
if (!continue_running)
|
||||||
|
break ;
|
||||||
|
take_forks(philo);
|
||||||
|
print_action(philo, GREEN"is eating😋"RST, 0);
|
||||||
|
eat(philo);
|
||||||
|
release_forks(philo);
|
||||||
|
philo->can_eat = 0;
|
||||||
|
print_action(philo, ORANGE"is sleeping😴"RST, 0);
|
||||||
|
usleep(philo->sim->time_to_sleep * 1000);
|
||||||
|
print_action(philo, CYAN"is thinking🤔" RST, 0);
|
||||||
|
think(philo);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
72
threads.c
Executable file
72
threads.c
Executable file
@@ -0,0 +1,72 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* threads.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/12 10:45:20 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/23 16:28:10 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
static int create_philosopher_threads(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
if (i % 2 == 0)
|
||||||
|
pthread_create(&sim->philos[i].thread, NULL,
|
||||||
|
philosopher_life, &sim->philos[i]);
|
||||||
|
else
|
||||||
|
pthread_create(&sim->philos[i].thread, NULL,
|
||||||
|
philosopher_life, &sim->philos[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_monitoring_threads(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
if (i % 2 == 0)
|
||||||
|
pthread_create(&sim->philos[i].philosopher_monitor, NULL,
|
||||||
|
philo_monitor, &sim->philos[i]);
|
||||||
|
else
|
||||||
|
pthread_create(&sim->philos[i].philosopher_monitor, NULL,
|
||||||
|
philo_monitor, &sim->philos[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int init_threads(t_simulation *sim)
|
||||||
|
{
|
||||||
|
if (!create_philosopher_threads(sim))
|
||||||
|
return (0);
|
||||||
|
if (!create_monitoring_threads(sim))
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int join_threads(t_simulation *sim)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < sim->num_philosophers)
|
||||||
|
{
|
||||||
|
pthread_join(sim->philos[i].philosopher_monitor, NULL);
|
||||||
|
pthread_join(sim->philos[i].thread, NULL);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
29
time.c
Executable file
29
time.c
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* time.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 15:31:00 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 16:20:32 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
long initialize_start_time(void)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
return ((now.tv_sec * 1000) + (now.tv_usec / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_time(long start_time)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
return (((now.tv_sec * 1000) + (now.tv_usec / 1000)) - start_time);
|
||||||
|
}
|
||||||
90
utils.c
Executable file
90
utils.c
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* utils.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/10/17 16:21:02 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2023/10/17 16:27:28 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "philo.h"
|
||||||
|
|
||||||
|
static void ft_bzero(void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < len)
|
||||||
|
{
|
||||||
|
*(char *)(ptr + i) = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ft_calloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (!nmemb || !size)
|
||||||
|
return (malloc(0));
|
||||||
|
if ((nmemb * size) / size != nmemb)
|
||||||
|
return (NULL);
|
||||||
|
ptr = malloc(size * nmemb);
|
||||||
|
if (!ptr)
|
||||||
|
return (0);
|
||||||
|
ft_bzero(ptr, size * nmemb);
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ft_atoi(const char *nptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int sign;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
sign = 1;
|
||||||
|
res = 0;
|
||||||
|
while (nptr[i] == 32 || (nptr[i] >= 9 && nptr[i] <= 13))
|
||||||
|
i++;
|
||||||
|
if (nptr[i] == '-' || nptr[i] == '+')
|
||||||
|
{
|
||||||
|
if (nptr[i] == '-')
|
||||||
|
sign = - (1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (nptr[i] >= 48 && nptr[i] <= 57)
|
||||||
|
{
|
||||||
|
res = res * 10 + nptr[i] - 48;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (res * sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_action(t_philo *philo, char *action, int death_action)
|
||||||
|
{
|
||||||
|
t_simulation *sim;
|
||||||
|
int is_dead;
|
||||||
|
int all_eat;
|
||||||
|
|
||||||
|
sim = philo->sim;
|
||||||
|
pthread_mutex_lock(&sim->print_mutex);
|
||||||
|
pthread_mutex_lock(&sim->end_mutex);
|
||||||
|
is_dead = sim->is_philosopher_dead;
|
||||||
|
all_eat = sim->simulation_end;
|
||||||
|
pthread_mutex_unlock(&sim->end_mutex);
|
||||||
|
if ((is_dead || all_eat) && !death_action)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&sim->print_mutex);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
if (action)
|
||||||
|
{
|
||||||
|
printf("%ld ms"YELLOW" %d %s\n", get_time(sim->start_time),
|
||||||
|
philo->id, action);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&sim->print_mutex);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user