#include "philo.h" void go_sleep(t_philo *philo, int action_time) { struct timeval stime; int time_to_death; // now_s // now_u // last_meal_s // last_meal_u // // last_meal now // v v // ------|-----------|------------------------------------------ // | | // |_d_e_a_t_h__t_i_m_e__________________| // | // |_e_a_t__t_i_m_e_________________|->action_time // | // |_d_i_f_f___| // | // |_d_e_a_t_h_-_d_i_f_f_____|->time_to_death // // // last_meal now // v v // ------|-----------|------------------------------------------ // | // |_d_e_a_t_h__t_i_m_e_______________________________| // | // |_e_a_t__t_i_m_e_________________|->action_time // | // |_d_i_f_f___| // | // |_d_e_a_t_h_-_d_i_f_f__________________|->time_to_death // // // last_meal now // v v // ------|-----------|------------------------------------------ // | // |_death___| // | // |_e_a_t__t_i_m_e_________________|->action_time // | // |_d_i_f_f___| // | // |_|->time_to_death // // gettimeofday(&stime, NULL); time_to_death = diff_time(philo->t_last_meal, stime); time_to_death = philo->params->t_die - time_to_death; if (time_to_death > action_time) usleep(action_time * 1000); else if (time_to_death > 0) usleep(philo->params->t_die * 1000); } int ret_unlock(t_philo *philo, int nbr_fork, int ret) { pthread_mutex_unlock(&philo->m_fork); if (nbr_fork == 2) pthread_mutex_unlock(&philo->next->m_fork); return (ret); } int take_forks(t_philo *philo) { pthread_mutex_lock(&(philo->m_fork)); if (is_dead(philo)) return (ret_unlock(philo, 1, 1)); print_message(philo, "has taken a fork"); pthread_mutex_lock(&(philo->next->m_fork)); if (is_dead(philo)) return (ret_unlock(philo, 2, 1)); print_message(philo, "has taken a fork"); update_time(philo); print_message(philo, "is eating"); philo->eat++; if (philo->params->n_eat && philo->eat >= philo->params->n_eat) return (ret_unlock(philo, 2, 1)); go_sleep(philo, philo->params->t_eat); pthread_mutex_unlock(&(philo->next->m_fork)); pthread_mutex_unlock(&(philo->m_fork)); return (0); } void *philo_exec(void *arg) { t_philo *philo; philo = (t_philo*)arg; init_time(philo); if (philo->p_nbr % 2 == 0) usleep(10 * 1000); while (1) { if (take_forks(philo) != 0) break ; if (is_dead(philo)) break ; print_message(philo, "is sleeping"); go_sleep(philo, philo->params->t_slp); if (is_dead(philo)) break ; print_message(philo, "is thinking"); } return (NULL); }