diff --git a/philo/manage_threads.c b/philo/manage_threads.c index cae7655..85dc77b 100644 --- a/philo/manage_threads.c +++ b/philo/manage_threads.c @@ -12,6 +12,20 @@ #include "philo.h" +int *init_forks(t_config *config) +{ + int *forks; + int i; + + forks = ft_calloc(sizeof(int), config->nbr_philo); + if (!forks) + return (NULL); + i = 0; + while (i < config->nbr_philo) + forks[i++] = 1; + return (forks); +} + static t_same *create_struct_same(t_config *config) { t_same *same; @@ -19,7 +33,7 @@ static t_same *create_struct_same(t_config *config) same = ft_calloc(sizeof(t_same), 1); if (!same) return (NULL); - same->forks = ft_calloc(sizeof(int), config->nbr_philo + 1); + same->forks = init_forks(config); if (!same->forks) { free(same); diff --git a/philo/threads.c b/philo/threads.c index 87ae739..dfc0fc0 100644 --- a/philo/threads.c +++ b/philo/threads.c @@ -12,6 +12,36 @@ #include "philo.h" +void take_fork(t_philo *philo, int id_fork) +{ + pthread_mutex_lock(&philo->same->mutex[id_fork]); + philo->same->forks[id_fork] = 0; + pthread_mutex_unlock(&philo->same->mutex[id_fork]); +} + +void drop_fork(t_philo *philo, int id_fork, int next_id_fork) +{ + pthread_mutex_lock(&philo->same->mutex[id_fork]); + philo->same->forks[id_fork] = 1; + pthread_mutex_unlock(&philo->same->mutex[id_fork]); + if (next_id_fork >= 0) + { + pthread_mutex_lock(&philo->same->mutex[next_id_fork]); + philo->same->forks[next_id_fork] = 1; + pthread_mutex_unlock(&philo->same->mutex[next_id_fork]); + } +} + +int get_fork(t_philo *philo, int id_fork) +{ + int fork; + + pthread_mutex_lock(&philo->same->mutex[id_fork]); + fork = philo->same->forks[id_fork]; + pthread_mutex_unlock(&philo->same->mutex[id_fork]); + return (fork); +} + int finish(t_philo *philo, long long last_eat_time) { int dead; @@ -70,8 +100,7 @@ int in_loop_eat_sleep(t_philo *philo, t_only *only, pthread_mutex_unlock(&philo->same->mutex[nbr_philo + 1]); } message(philo, "is sleeping\n"); - pthread_mutex_unlock(&philo->same->mutex[only->next_id]); - pthread_mutex_unlock(&philo->same->mutex[only->id]); + drop_fork(philo, only->id, only->next_id); if (get_utime() - only->last_eat_time + config->time_sleep >= config->time_die) { @@ -88,15 +117,14 @@ void loop_philosopher(t_philo *philo, t_only *only, { while (!finish(philo, only->last_eat_time)) { - if (!finish(philo, only->last_eat_time) - && !pthread_mutex_lock(&philo->same->mutex[only->id])) + while (!finish(philo, only->last_eat_time) && get_fork(philo, only->id)) { + take_fork(philo, only->id); message(philo, "has taken a fork\n"); while (only->id == only->next_id && !finish(philo, only->last_eat_time)) ; - if (!finish(philo, only->last_eat_time) - && !pthread_mutex_lock(&philo->same->mutex[only->next_id])) + while (!finish(philo, only->last_eat_time) && get_fork(philo, only->next_id)) { if (verif_finish(philo, only)) break ; @@ -105,8 +133,7 @@ void loop_philosopher(t_philo *philo, t_only *only, if (!in_loop_eat_sleep(philo, only, config, nbr_philo)) break ; } - else - pthread_mutex_unlock(&philo->same->mutex[only->id]); + drop_fork(philo, only->id, -1); } if (!finish(philo, only->last_eat_time)) message(philo, "is thinking\n"); @@ -123,7 +150,6 @@ void *philosopher(t_philo *philo) config = philo->same->config; init_philo(philo, only, config, &nbr_philo); loop_philosopher(philo, only, config, nbr_philo); - pthread_mutex_lock(&philo->same->mutex[nbr_philo + 1]); pthread_mutex_lock(&philo->same->mutex[nbr_philo]); if (!philo->same->death && (config->must_eat == -1 || (config->must_eat > -1 && only->eat < config->must_eat))) @@ -132,6 +158,5 @@ void *philosopher(t_philo *philo) message_die(philo, "died\n"); } pthread_mutex_unlock(&philo->same->mutex[nbr_philo]); - pthread_mutex_unlock(&philo->same->mutex[nbr_philo + 1]); return (NULL); }