From 0dad3463b22e541153dcfded178eb0f3fe428cbd Mon Sep 17 00:00:00 2001 From: Dominik Kaiser Date: Sun, 26 Jan 2025 12:44:13 +0100 Subject: [PATCH] Update simulation and fix norme errors --- philo/Makefile | 2 +- philo/include/ft_utils.h | 12 +-- philo/include/philo.h | 57 ++++++------ philo/src/ft_utils.c | 16 ++-- philo/src/main.c | 162 +++++++++++++++++--------------- philo/src/simulation.c | 196 ++++++++++++++------------------------- 6 files changed, 202 insertions(+), 243 deletions(-) diff --git a/philo/Makefile b/philo/Makefile index 9cc953f..0d55726 100644 --- a/philo/Makefile +++ b/philo/Makefile @@ -9,7 +9,7 @@ CFLAGS = -Wall -Wextra -Werror HEADERS = -Iinclude VPATH := src -SRC := main.c ft_utils.c simulation.c +SRC := main.c ft_utils.c simulation.c philo_eat.c OBJ_DIR := _obj OBJ := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o)) diff --git a/philo/include/ft_utils.h b/philo/include/ft_utils.h index fb0455e..2299cd9 100644 --- a/philo/include/ft_utils.h +++ b/philo/include/ft_utils.h @@ -6,34 +6,34 @@ /* By: dkaiser # include +# include # include /* ** Prints error message and returns EXIT_FAILURE */ -int ft_err(const char *str); +int ft_err(const char *str); /* ** Returns integer value from str */ -int ft_atoi(const char *str); +int ft_atoi(const char *str); /* ** Returns current time in milliseconds */ -int ft_cur_time_in_ms(); +int ft_cur_time_in_ms(void); /* ** Prints "timestamp_in_ms id str" */ -void ft_log(int id, const char *str); +void ft_log(int id, const char *str); #endif diff --git a/philo/include/philo.h b/philo/include/philo.h index fbcf53f..bbc1bc2 100644 --- a/philo/include/philo.h +++ b/philo/include/philo.h @@ -6,51 +6,54 @@ /* By: dkaiser -# include -# include -# include # include "ft_utils.h" +# include +# include +# include +# include # define ERR_USAGE "Usage: [times_must_eat]" # define ERR_MALLOC "Memory allocation failed" typedef struct s_fork { - int available; - pthread_mutex_t mutex; -} t_fork; + int owner; + pthread_mutex_t mutex; +} t_fork; typedef struct s_phdata { - int nbr_of_philos; - int time_to_die; - int time_to_eat; - int time_to_sleep; - int times_must_eat; - int philos_must_eat; - pthread_mutex_t pme_mutex; - int simulation_running; - t_fork *forks; -} t_phdata; + int nbr_of_philos; + int time_to_die; + int time_to_eat; + int time_to_sleep; + int times_must_eat; + int philos_must_eat; + pthread_mutex_t pme_mutex; + int simulation_running; + t_fork *forks; +} t_phdata; typedef struct s_philo { - int id; - int last_time_eaten; - int times_must_eat; - int is_alive; - pthread_t thread; - t_phdata *data; -} t_philo; - -int run_simulation(int nbr_of_philos, t_philo *philos, t_phdata *data); + int id; + int last_time_eaten; + int times_must_eat; + int is_alive; + pthread_t thread; + t_phdata *data; +} t_philo; + +int run_simulation(int nbr_of_philos, t_philo *philos, + t_phdata *data); +int philo_die(t_philo *philo); +void philo_eat(t_philo *philo); #endif diff --git a/philo/src/ft_utils.c b/philo/src/ft_utils.c index 5b62882..ba5756d 100644 --- a/philo/src/ft_utils.c +++ b/philo/src/ft_utils.c @@ -6,29 +6,29 @@ /* By: dkaiser nbr_of_philos = ft_atoi(argv[1]); + data->time_to_die = ft_atoi(argv[2]); + data->time_to_eat = ft_atoi(argv[3]); + data->time_to_sleep = ft_atoi(argv[4]); + if (argc == 6) + data->times_must_eat = ft_atoi(argv[5]); + else + data->times_must_eat = -1; + if (data->nbr_of_philos <= 0) + return (ft_err("Must have at least one philosopher")); + if (data->time_to_die < 0) + return (ft_err("ttd can't be negative")); + if (data->time_to_eat < 0) + return (ft_err("tte can't be negative")); + if (data->time_to_sleep < 0) + return (ft_err("tts can't be negative")); + data->philos_must_eat = data->nbr_of_philos; + return (EXIT_SUCCESS); +} + +void init_philo(t_philo *philo, t_phdata *data, int id) +{ + philo->id = id; + philo->is_alive = 1; + philo->times_must_eat = data->times_must_eat; + philo->data = data; + philo->last_time_eaten = ft_cur_time_in_ms(); +} -int load_data(t_phdata *data, int argc, char *argv[]) +int init_philos(t_philo **philos, t_phdata *data) { - data->nbr_of_philos = ft_atoi(argv[1]); - data->time_to_die = ft_atoi(argv[2]); - data->time_to_eat = ft_atoi(argv[3]); - data->time_to_sleep = ft_atoi(argv[4]); - if (argc == 6) - data->times_must_eat = ft_atoi(argv[5]); - else - data->times_must_eat = -1; - if (data->nbr_of_philos <= 0) - return (ft_err("Must have at least one philosopher")); - if (data->time_to_die < 0) - return (ft_err("ttd can't be negative")); - if (data->time_to_eat < 0) - return (ft_err("tte can't be negative")); - if (data->time_to_sleep < 0) - return (ft_err("tts can't be negative")); - data->philos_must_eat = data->nbr_of_philos; - return (EXIT_SUCCESS); + int i; + int result; + + i = 0; + while (i < data->nbr_of_philos) + { + init_philo(&(*philos)[i], data, i + 1); + data->forks[i].owner = 0; + result = pthread_mutex_init(&(data->forks[i].mutex), NULL); + if (result != 0) + { + free(*philos); + free(data->forks); + return (result); + } + i++; + } + return (EXIT_SUCCESS); } -int init(t_philo **philos, t_phdata *data) +int init(t_philo **philos, t_phdata *data) { - int i; - int result; + int result; - *philos = (t_philo *)malloc(sizeof(t_philo) * data->nbr_of_philos); - if (*philos == NULL) - return (ft_err(ERR_MALLOC)); - data->forks = (t_fork *)malloc(sizeof(t_fork) * data->nbr_of_philos); - if (data->forks == NULL) - { - free(*philos); - return (ft_err(ERR_MALLOC)); - } - i = 0; - result = pthread_mutex_init(&(data->forks[i].mutex), NULL); - if (result != 0) - { - free(*philos); - free(data->forks); - return (result); - } - while (i < data->nbr_of_philos) - { - (*philos)[i].id = i + 1; - (*philos)[i].is_alive = 1; - (*philos)[i].times_must_eat = data->times_must_eat; - (*philos)[i].data = data; - (*philos)[i].last_time_eaten = ft_cur_time_in_ms(); - data->forks[i].available = 1; - result = pthread_mutex_init(&(data->forks[i].mutex), NULL); - if (result != 0) - { - free(*philos); - free(data->forks); - return (result); - } - i++; - } - return (EXIT_SUCCESS); + *philos = (t_philo *)malloc(sizeof(t_philo) * data->nbr_of_philos); + if (*philos == NULL) + return (ft_err(ERR_MALLOC)); + data->forks = (t_fork *)malloc(sizeof(t_fork) * data->nbr_of_philos); + if (data->forks == NULL) + { + free(*philos); + return (ft_err(ERR_MALLOC)); + } + result = pthread_mutex_init(&(data->pme_mutex), NULL); + if (result != 0) + { + free(*philos); + free(data->forks); + return (result); + } + result = init_philos(philos, data); + return (result); } -int main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - t_phdata data; - t_philo *philos; - int result; + t_phdata data; + t_philo *philos; + int result; - if (argc != 5 && argc != 6) - return(ft_err(ERR_USAGE)); - result = load_data(&data, argc, argv); - if (result != EXIT_SUCCESS) - return (result); - result = init(&philos, &data); - if (result != EXIT_SUCCESS) - return (result); - data.simulation_running = 1; - result = run_simulation(data.nbr_of_philos, philos, &data); - free(philos); - free(data.forks); - return (result); + if (argc != 5 && argc != 6) + return (ft_err(ERR_USAGE)); + result = load_data(&data, argc, argv); + if (result != EXIT_SUCCESS) + return (result); + result = init(&philos, &data); + if (result != EXIT_SUCCESS) + return (result); + data.simulation_running = 1; + result = run_simulation(data.nbr_of_philos, philos, &data); + free(philos); + free(data.forks); + return (result); } diff --git a/philo/src/simulation.c b/philo/src/simulation.c index fa8e886..fd9f40b 100644 --- a/philo/src/simulation.c +++ b/philo/src/simulation.c @@ -6,148 +6,92 @@ /* By: dkaiser philo->last_time_eaten + philo->data->time_to_die) - { - philo->is_alive = 0; - ft_log(philo->id, "has died"); - philo->data->simulation_running = 0; - return (1); - } - return (0); + if (ft_cur_time_in_ms() > philo->last_time_eaten + philo->data->time_to_die) + { + philo->is_alive = 0; + ft_log(philo->id, "has died"); + philo->data->simulation_running = 0; + return (1); + } + return (0); } -void philo_eat(t_philo *philo) +void philo_sleep(t_philo *philo) { - t_fork *left_fork; - t_fork *right_fork; - int started_eating; - int tte; + int started_sleeping; + int tts; - left_fork = &philo->data->forks[philo->id - 1]; - right_fork = &philo->data->forks[philo->id % philo->data->nbr_of_philos]; - while (!left_fork->available || !right_fork->available) - { - if (!philo->data->simulation_running) - return; - if (philo_die(philo)) - return ; - usleep(1000); - } - pthread_mutex_lock(&left_fork->mutex); - pthread_mutex_lock(&right_fork->mutex); - if (philo->data->simulation_running) - { - - left_fork->available = 0; - ft_log(philo->id, "has taken a fork"); - right_fork->available = 0; - ft_log(philo->id, "has taken a fork"); - started_eating = ft_cur_time_in_ms(); - tte = philo->data->time_to_eat; - philo->last_time_eaten = started_eating; - philo->times_must_eat -= 1; - ft_log(philo->id, "is eating"); - while (ft_cur_time_in_ms() < started_eating + tte) - { - if (philo_die(philo)) - return; - usleep(1000); - } - left_fork->available = 1; - right_fork->available = 1; - } - pthread_mutex_unlock(&left_fork->mutex); - pthread_mutex_unlock(&right_fork->mutex); -} - -void philo_sleep(t_philo *philo) -{ - int started_sleeping; - int tts; - - started_sleeping = ft_cur_time_in_ms(); - tts = philo->data->time_to_sleep; - ft_log(philo->id, "is sleeping"); - while (ft_cur_time_in_ms() < started_sleeping + tts) - { - if (philo_die(philo)) - return; - usleep(1000); - } -} - -void philo_think(t_philo *philo) -{ - ft_log(philo->id, "is thinking"); + started_sleeping = ft_cur_time_in_ms(); + tts = philo->data->time_to_sleep; + ft_log(philo->id, "is sleeping"); + while (ft_cur_time_in_ms() < started_sleeping + tts) + { + if (philo_die(philo)) + return ; + usleep(1000); + } } -int *process_philo(void *arg) +void process_philo(void *arg) { - t_philo *philo; - int *result; + t_philo *philo; - result = malloc(sizeof(int)); - if (result == NULL) - return (NULL); - philo = (t_philo *)arg; - *result = EXIT_SUCCESS; - while (philo->data->simulation_running) - { - philo_eat(philo); - if (philo->times_must_eat == 0) - { - pthread_mutex_lock(&philo->data->pme_mutex); - philo->data->philos_must_eat -= 1; - pthread_mutex_unlock(&philo->data->pme_mutex); - } - if (!philo->data->simulation_running) - break; - philo_sleep(philo); - if (!philo->data->simulation_running) - break; - philo_think(philo); - } - return (result); + philo = (t_philo *)arg; + while (philo->data->simulation_running) + { + philo_eat(philo); + if (philo->times_must_eat == 0) + { + pthread_mutex_lock(&philo->data->pme_mutex); + philo->data->philos_must_eat -= 1; + pthread_mutex_unlock(&philo->data->pme_mutex); + } + if (!philo->data->simulation_running) + break ; + if (philo->data->nbr_of_philos < 2) + { + if (philo_die(philo)) + break ; + continue ; + } + philo_sleep(philo); + if (!philo->data->simulation_running) + break ; + ft_log(philo->id, "is thinking"); + } } -int run_simulation(int nbr_of_philos, t_philo *philos, t_phdata *data) +int run_simulation(int nbr_of_philos, t_philo *philos, t_phdata *data) { - int i; - int result; - void *retval; + int i; + int result; - i = 0; - result = EXIT_SUCCESS; - while (i < nbr_of_philos) - { - result = pthread_create(&(philos[i].thread), NULL, (void*) process_philo, &philos[i]); - if (result != 0) - break; - i++; - } - while (data->simulation_running) - { - if (data->philos_must_eat <= 0) - data->simulation_running = 0; - } - while (i--) - { - pthread_join(philos[i].thread, &retval); - if (retval == NULL) - result = ft_err(ERR_MALLOC); - else if (*(int *)retval != EXIT_SUCCESS) - { - result = *(int *)retval; - free(retval); - } - } - return (result); + i = 0; + result = EXIT_SUCCESS; + while (i < nbr_of_philos) + { + result = pthread_create(&(philos[i].thread), NULL, + (void *)process_philo, &philos[i]); + if (result != 0) + break ; + i++; + } + while (data->simulation_running) + { + if (data->philos_must_eat <= 0) + data->simulation_running = 0; + } + while (i--) + { + pthread_join(philos[i].thread, NULL); + } + return (result); } -- 2.47.2