/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* threads.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/08 20:08:33 by erey-bet #+# #+# */ /* Updated: 2023/04/10 17:22:22 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" int finish(t_philo *philo, long long last_eat_time) { int dead; int all_eat; int nbr_philo; nbr_philo = philo->same->config->nbr_philo; if (philo->same->config->must_eat > -1) { pthread_mutex_lock(&philo->same->mutex[nbr_philo + 1]); all_eat = philo->same->all_eat; pthread_mutex_unlock(&philo->same->mutex[nbr_philo + 1]); } pthread_mutex_lock(&philo->same->mutex[nbr_philo]); dead = philo->same->death; pthread_mutex_unlock(&philo->same->mutex[nbr_philo]); return (get_utime() - last_eat_time >= philo->same->config->time_die || dead || (philo->same->config->must_eat != -1 && all_eat >= philo->same->config->must_eat * nbr_philo) ); } void init_philo(t_philo *philo, t_only *only, t_config *config, int *nbr_philo) { *nbr_philo = philo->same->config->nbr_philo; only->next_id = (only->id + 1) % *nbr_philo; only->last_eat_time = get_utime(); if (only->id == only->next_id) return ; if (only->id % 2 == 1 || (*nbr_philo % 2 == 1 && only->id == *nbr_philo - 1)) { message(philo, "is thinking\n"); if (get_utime() - only->last_eat_time + config->time_eat >= config->time_die) ft_sleep(config->time_die - (get_utime() - only->last_eat_time)); else ft_sleep(config->time_eat / (only->id % 2 + 1)); } } int in_loop_eat_sleep(t_philo *philo, t_only *only, t_config *config, int nbr_philo) { only->last_eat_time = get_utime(); if (!verif_die_eating(philo, only, config)) return (0); ft_sleep(config->time_eat); if (verif_finish(philo, only)) return (0); if (config->must_eat > -1 && only->eat < config->must_eat) { only->eat++; pthread_mutex_lock(&philo->same->mutex[nbr_philo + 1]); philo->same->all_eat += 1; pthread_mutex_unlock(&philo->same->mutex[nbr_philo + 1]); } message(philo, "is sleeping\n"); drop_fork(philo, only->id, only->next_id); if (get_utime() - only->last_eat_time + config->time_sleep >= config->time_die) { ft_sleep(config->time_die - (get_utime() - only->last_eat_time)); return (0); } else ft_sleep(config->time_sleep); return (1); } void loop_philosopher(t_philo *philo, t_only *only, t_config *config, int nbr_philo) { while (!finish(philo, only->last_eat_time)) { wait_fork(philo, only, only->id); if (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)) ; wait_fork(philo, only, only->next_id); if (get_fork(philo, only->next_id)) { if (!before_eat(philo, only, config, nbr_philo)) break ; } else drop_fork(philo, only->id, -1); } if (!finish(philo, only->last_eat_time)) message(philo, "is thinking\n"); } } void *philosopher(t_philo *philo) { t_only *only; t_config *config; int nbr_philo; only = philo->only; 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]); if (!philo->same->death && (config->must_eat == -1 || (config->must_eat > -1 && only->eat < config->must_eat))) { philo->same->death = 1; message_die(philo, "died\n"); } pthread_mutex_unlock(&philo->same->mutex[nbr_philo]); return (NULL); }