/* ************************************************************************** */ /* */ /* ::: o_ :::::: ::: */ /* philo_routine.c :+: / :+::+: :+: */ /* +:+ > +:++:+ +:+ */ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2025/01/20 14:26:49 by whaffman #+#+# #+#+# #+# #+# | */ /* Updated: 2025/01/20 14:27:41 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ #include "philo.h" void set_finished(t_rules *rules) { pthread_mutex_lock(rules->finished_lock); rules->finished = 1; pthread_mutex_unlock(rules->finished_lock); } int get_finished(t_rules *rules) { int finished; pthread_mutex_lock(rules->finished_lock); finished = rules->finished; pthread_mutex_unlock(rules->finished_lock); return (finished); } void philo_die(t_philo *philo) { print_status(philo, "died"); philo->death = 1; set_finished(philo->rules); pthread_mutex_unlock(philo->l_fork); pthread_mutex_unlock(philo->r_fork); } int philo_died_while_sleeping(t_philo *philo, int time) { const int start = get_time(); while (get_time() - start < time) { if (philo->last_meal - get_time() >= philo->rules->time_to_die) return (SUCCESS); usleep(500); } return (FAILURE); } int philo_eat(t_philo *philo) { if (philo->id % 2 == 1) { pthread_mutex_lock(philo->r_fork); print_status(philo, "has taken a fork"); } pthread_mutex_lock(philo->l_fork); print_status(philo, "has taken a fork"); if (philo->id % 2 != 1) { pthread_mutex_lock(philo->r_fork); print_status(philo, "has taken a fork"); } if (check_death(philo)) return (philo_die(philo), FAILURE); print_status(philo, "is eating"); philo->last_meal = get_time(); philo->n_eat++; return (SUCCESS); } void synchronize_philos(t_philo *philo) { pthread_mutex_lock(philo->rules->finished_lock); pthread_mutex_unlock(philo->rules->finished_lock); philo->last_meal = get_time(); if (philo->id % 2 == 1) { print_status(philo, "is thinking"); usleep(philo->rules->time_to_eat * 10); } } void *philo_routine(void *arg) { t_philo *philo; philo = (t_philo *)arg; synchronize_philos(philo); while (!philo->death && !get_finished(philo->rules)) { if (check_death(philo)) return (philo_die(philo), NULL); if (!philo_eat(philo)) return (NULL); if (philo_died_while_sleeping(philo, philo->rules->time_to_eat)) return (philo_die(philo), NULL); pthread_mutex_unlock(philo->l_fork); pthread_mutex_unlock(philo->r_fork); if (!philo->rules->finished) print_status(philo, "is sleeping"); if (philo_died_while_sleeping(philo, philo->rules->time_to_sleep)) return (philo_die(philo), NULL); if(!philo->rules->finished) print_status(philo, "is thinking"); } return (NULL); }