Files
42_INT_08_philosophers/philo/exec.c
2022-02-02 00:31:51 +01:00

130 lines
4.8 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/02/01 18:08:58 by hulamy #+# #+# */
/* Updated: 2022/02/02 00:28:14 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "philo.h"
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_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)
{
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);
if (print_message(philo, B_YELLOW, "is eating"))
return (ret_err_unlock(fork1, fork2));
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(fork2);
pthread_mutex_unlock(fork1);
return (0);
}
/*
** just after the assignation of the two forks :
if (philo->p_nbr % 2 == 0)
{
fork1 = &(philo->next->m_fork);
fork2 = &(philo->m_fork);
}
** just before the while :
if (philo->p_nbr % 2 == 0)
usleep(10 * 1000);
** just at the end of the while
usleep(1 * 1000);
*/
void *philo_exec(void *arg)
{
t_philo *philo;
t_mtx *fork1;
t_mtx *fork2;
philo = (t_philo *)arg;
init_time(philo);
fork1 = &(philo->m_fork);
fork2 = &(philo->next->m_fork);
if (philo->p_nbr % 2 == 0)
usleep(10 * 1000);
while (1)
{
if (eat(philo, fork1, fork2) != 0)
break ;
if (print_message(philo, B_BLUE, "is sleeping"))
break ;
action_delay(philo, philo->params->t_slp);
if (print_message(philo, B_GREEN, "is thinking"))
break ;
}
return (NULL);
}
/*
3 610 200 100 . 3 610 200 100 . 3 610 200 200
. .
-(1) (2)- -(3) . -(1) -(2) -(3) . -(1) (2)- -(3)
. .
(ms) . .
. .
0: +-(1)-+ (2)- +-(3)- . +-(1)-+ -(2) +-(3)- . +-(1)-+ (2)- +-(3)-
| . | . |
100: | (2)- +-(3)- . | -(2) +-(3)- . | (2)- +-(3)-
| . | . |
200: ((|)) (2)- +-(3)-+ . ((|)) +-(2)- +-(3)-+ . ((|)) (2)- +-(3)-+
| | . | | . | |
300: -(1) (2)- | . -(1) +-(2)- | . | (2)- |
| . | . | |
400: +-(1)-+ -(2)-+ ((|)) . +-(1)- +-(2)-+ ((|)) . +-(1) +-(2)-+ ((|))
| | . | | . | |
500: | -(2)-+ -(3) . +-(1)- | -(3) . +-(1)- | |
| . | . | |
600: ((|)) +-(2)-+ -(3) . +-(1)-+ ((|)) +-(3)- . +-(1)-+ ((|)) +-(3)
| | . | | . | |
700: +-(1)- | -(3) . | -(2) +-(3)- . | | +-(3)-
| . | . | |
800: +-(1)-+ ((|)) +-(3)- . ((|)) +-(2)- +-(3)-+ . ((|)) +-(2)- +-(3)-+
| | xxxxxxx . | | . | |
900: | (2)- . -(1) +-(2)- | . | +-(2)- |
*/