#include "philo.h" #include "struct.h" #include "time.h" #include "data.h" #include #include #include #include #include #include "./print.h" void philo_destroyer(t_philo *philo) { pthread_mutex_destroy(&philo->nb_meal_mutex); pthread_mutex_destroy(&philo->last_sleep_mutex); pthread_mutex_destroy(&philo->last_eat_mutex); free(philo); } bool check(t_philo *philo, t_data *data) { bool stop; 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); } void eat(t_philo *philo, t_data *data) { print_take_a_fork(philo); print_take_a_fork(philo); print_eating(philo); pthread_mutex_lock(&philo->last_eat_mutex); if (get_time() - philo->last_eat + data->eat_time > data->life_expectency) { pthread_mutex_unlock(&philo->last_eat_mutex); usleep((data->life_expectency - (get_time() - philo->last_eat)) * 1000); return ; } else usleep(data->eat_time * 1000); pthread_mutex_unlock(&philo->last_eat_mutex); pthread_mutex_lock(&philo->nb_meal_mutex); philo->nb_meal++; pthread_mutex_unlock(&philo->nb_meal_mutex); pthread_mutex_lock(&data->forks_mutex); data->forks[philo->id] = 1; data->forks[(philo->id + 1) % data->nb_philos] = 1; pthread_mutex_unlock(&data->forks_mutex); } bool philo_eat(t_philo *philo, t_data *data) { bool left_fork; bool right_fork; left_fork = 0; right_fork = 0; while (left_fork == 0 || right_fork == 0) { if (check(philo, data)) return (1); pthread_mutex_lock(&data->forks_mutex); left_fork = data->forks[philo->id]; if (((philo->id + 1) % data->nb_philos) != philo->id) right_fork = data->forks[(philo->id + 1) % data->nb_philos]; if (right_fork && left_fork) { data->forks[philo->id] = 0; data->forks[(philo->id + 1) % data->nb_philos] = 0; } pthread_mutex_unlock(&data->forks_mutex); usleep(10); } eat(philo, data); pthread_mutex_lock(&philo->last_eat_mutex); philo->last_eat = get_time(); pthread_mutex_unlock(&philo->last_eat_mutex); return (0); } void philo_sleep(t_data *data, t_philo *philo) { print_sleeping(philo); pthread_mutex_lock(&philo->last_sleep_mutex); // printf("time=%zu, last_sleep=%zu, sleep_time=%zu, life_expectency=%zu\n", get_time(), philo->last_sleep, data->sleep_time, data->life_expectency); if (get_time() - philo->last_sleep + data->sleep_time > data->life_expectency) { pthread_mutex_unlock(&philo->last_sleep_mutex); // printf("rompiche=%zu\n", (data->life_expectency - // (get_time() - philo->last_sleep))); usleep((data->life_expectency - (get_time() - philo->last_sleep)) * 1000); return ; } else usleep(data->sleep_time * 1000); philo->last_sleep = get_time(); pthread_mutex_unlock(&philo->last_sleep_mutex); } void *philo_routine(void *arg) { t_philo *philo; t_data *data; philo = arg; data = philo->data; print_thinking(philo); usleep(philo->id * (data->life_expectency / data->nb_philos)); 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(); philo->last_sleep = get_time(); pthread_mutex_init(&philo->nb_meal_mutex, NULL); pthread_mutex_init(&philo->last_eat_mutex, NULL); pthread_mutex_init(&philo->last_sleep_mutex, NULL); pthread_mutex_init(&philo->stop_mutex, NULL); return (philo); }