#include "philo.h" int get_time(t_params *params) { struct timeval tp; long time; if (gettimeofday(&tp, NULL) < 0) { return (-1); } time = tp.tv_sec * 1000 + tp.tv_usec / 1000; if (!params->start_time) { params->start_time = time; return (0); } time -= params->start_time; return (time); } /* static void action_delay(t_philo *philo, int action_time) { struct timeval stime; int death_time; gettimeofday(&stime, NULL); death_time = philo->params->t_die - diff_time(philo, &stime); if (death_time > action_time) usleep(action_time * 1000); else if (death_time > 0) usleep(philo->params->t_die * 1000); } */ /* static int ret_err_unlock(t_philo *philo, int nbr_fork) { if (nbr_fork == 2) pthread_mutex_unlock(&philo->next->m_fork); pthread_mutex_unlock(&philo->m_fork); return (1); } */ static int ret_err_unlock(t_mtx *fork1, t_mtx *fork2) { if (fork2) pthread_mutex_unlock(fork2); if (fork1) pthread_mutex_unlock(fork1); return (1); } static int eat(t_philo *philo, t_mtx *fork1, t_mtx *fork2) { int time; pthread_mutex_lock(fork1); if (print_message(philo, WHITE, "has taken a fork")) return (ret_err_unlock(fork1, NULL)); if (fork1 == fork2) return (ret_err_unlock(fork1, NULL)); pthread_mutex_lock(fork2); if (print_message(philo, WHITE, "has taken a fork")) return (ret_err_unlock(fork1, fork2)); // update_time(philo); time = get_time(philo->params); if (print_message(philo, B_YELLOW, "is eating")) return (ret_err_unlock(fork1, fork2)); // action_delay(philo, philo->params->t_eat); while (get_time(philo->params) - time < philo->params->t_eat) usleep(100); pthread_mutex_lock(&(philo->m_eat)); philo->eat_count++; pthread_mutex_unlock(&(philo->m_eat)); pthread_mutex_unlock(fork2); pthread_mutex_unlock(fork1); return (0); } /* static int eat(t_philo *philo) { pthread_mutex_lock(&(philo->m_fork)); if (print_message(philo, WHITE, "has taken a fork")) return (ret_err_unlock(philo, 1)); if (philo->next == philo) return (ret_err_unlock(philo, 1)); pthread_mutex_lock(&(philo->next->m_fork)); if (print_message(philo, WHITE, "has taken a fork")) return (ret_err_unlock(philo, 2)); update_time(philo); if (print_message(philo, B_YELLOW, "is eating")) return (ret_err_unlock(philo, 2)); action_delay(philo, philo->params->t_eat); pthread_mutex_lock(&(philo->m_eat)); philo->eat_count++; pthread_mutex_unlock(&(philo->m_eat)); pthread_mutex_unlock(&(philo->next->m_fork)); pthread_mutex_unlock(&(philo->m_fork)); return (0); } */ /* ==10069== Observed (incorrect) order is: acquisition of lock at 0x54541F8 ==10069== at 0x4C3603C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10069== by 0x401188: eat (exec.c:38) ==10069== by 0x4010E7: philo_exec (exec.c:68) ==10069== by 0x4C38C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10069== by 0x4E4B6DA: start_thread (pthread_create.c:463) ==10069== by 0x518471E: clone (clone.S:95) ==10069== ==10069== followed by a later acquisition of lock at 0x54542E8 ==10069== at 0x4C3603C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10069== by 0x401209: eat (exec.c:43) ==10069== by 0x4010E7: philo_exec (exec.c:68) ==10069== by 0x4C38C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10069== by 0x4E4B6DA: start_thread (pthread_create.c:463) ==10069== by 0x518471E: clone (clone.S:95) */ void *philo_exec(void *arg) { int time; t_philo *philo; t_mtx *fork1; t_mtx *fork2; philo = (t_philo *)arg; // init_time(philo); get_time(philo->params); // if (philo->p_nbr % 2 == 0) // usleep(10 * 1000); fork1 = &(philo->m_fork); fork2 = &(philo->m_fork); // if (philo->global->t_start.ts == 0) // if (philo->p_nbr < philo->params->n_phi / 2) if (philo->p_nbr % 2 == 0) fork1 = &(philo->next->m_fork); else fork2 = &(philo->next->m_fork); while (1) { if (eat(philo, fork1, fork2) != 0) // if (eat(philo) != 0) break ; time = get_time(philo->params); if (print_message(philo, B_BLUE, "is sleeping")) break ; // action_delay(philo, philo->params->t_slp); while (get_time(philo->params) - time < philo->params->t_slp) usleep(100); if (print_message(philo, B_GREEN, "is thinking")) break ; } return (NULL); }