#include #include #include #include #include #include "./print.h" #include "philo.h" #include "time.h" #include "data.h" void philo_destroyer(t_philo *philo) { pthread_mutex_destroy(&philo->nb_meal_mutex); pthread_mutex_destroy(&philo->last_eat_mutex); free(philo); } bool check(t_philo *philo, t_data *data) { bool stop; if (get_min_meal(data) == data->nb_meals) { pthread_mutex_lock(&philo->stop_mutex); philo->stop = 1; pthread_mutex_unlock(&philo->stop_mutex); return (1); } pthread_mutex_lock(&data->stop_mutex); stop = data->stop; pthread_mutex_unlock(&data->stop_mutex); if (stop) { pthread_mutex_lock(&philo->stop_mutex); philo->stop = 1; pthread_mutex_unlock(&philo->stop_mutex); } return (stop); } bool philo_eat(t_philo *philo, t_data *data) { size_t time; pthread_mutex_lock(&data->forks[philo->id]); print_take_a_fork(philo); if (check(philo, data)) { pthread_mutex_unlock(&data->forks[philo->id]); return (1); } while ((philo->id + 1) % data->nb_philos == philo->id) if (check(philo, data)) { pthread_mutex_unlock(&data->forks[philo->id]); return (1); } pthread_mutex_lock(&data->forks[(philo->id + 1) % data->nb_philos]); print_take_a_fork(philo); if (check(philo, data)) { pthread_mutex_unlock(&data->forks[(philo->id + 1) % data->nb_philos]); pthread_mutex_unlock(&data->forks[philo->id]); return (1); } print_eating(philo); time = get_time(); if (time - philo->last_eat + data->eat_time > data->life_expectency) usleep((time - philo->last_eat + data->eat_time) * 1000); else usleep(data->eat_time * 1000); pthread_mutex_unlock(&data->forks[philo->id]); pthread_mutex_unlock(&data->forks[(philo->id + 1) % data->nb_philos]); if (check(philo, data)) return (1); pthread_mutex_lock(&philo->last_eat_mutex); philo->last_eat = get_time(); pthread_mutex_unlock(&philo->last_eat_mutex); pthread_mutex_lock(&philo->nb_meal_mutex); philo->nb_meal++; pthread_mutex_unlock(&philo->nb_meal_mutex); return (0); } void philo_sleep(t_data *data, t_philo *philo) { size_t time; print_sleeping(philo); time = get_time(); if (time - philo->last_eat + data->eat_time > data->life_expectency) usleep((time - philo->last_eat + data->eat_time) * 1000); else usleep(data->eat_time * 1000); } void *philo_routine(void *arg) { t_philo *philo; t_data *data; philo = arg; data = philo->data; print_thinking(philo); usleep((philo->id % 2) * (data->eat_time) * 1000); while (true) { if (check(philo, data)) { return (NULL); } if (philo_eat(philo, data)) { return (NULL); } if (check(philo, data)) { return (NULL); } philo_sleep(data, philo); if (check(philo, data)) { return (NULL); } print_thinking(philo); } return (NULL); } t_philo *philo_init(t_data *data) { t_philo *philo; static size_t id = 0; philo = malloc(sizeof(t_philo)); if (philo == NULL) return (NULL); philo->id = id++; philo->data = data; philo->nb_meal = 0; philo->stop = 0; philo->last_eat = get_time(); pthread_mutex_init(&philo->nb_meal_mutex, NULL); pthread_mutex_init(&philo->last_eat_mutex, NULL); pthread_mutex_init(&philo->stop_mutex, NULL); return (philo); }