summaryrefslogtreecommitdiff
path: root/src/routine.c
blob: 6d867cf1d8b392d03055a043d99f1d308f5123b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "codexion.h"
# include <unistd.h>   // for usleep()
# include <stdio.h>    // for printf()

static void	send_signal(t_fork *fork)
{
	(void)pthread_mutex_lock(&fork->mutex_cond);
	pthread_cond_signal(&fork->cond_signal);
	(void)pthread_mutex_unlock(&fork->mutex_cond);
}

static void	lock_forks(t_philo *philo, t_fork *f1,
			t_fork *f2)
{
	if (get_id(philo) % 2 == 0)
	{
		(void)pthread_mutex_lock(&f1->mutex);
		(void)pthread_mutex_lock(&f2->mutex);
	}
	else
	{
		if (philo->number_of_eats_done < 1)
			usleep(50);
		(void)pthread_mutex_lock(&f2->mutex);
		(void)pthread_mutex_lock(&f1->mutex);
	}
	wait_for_longest_cooldown(philo, f1, f2);
}

int	philo_routine(t_philo *philo, t_fork *f1,
			t_fork *f2)
{
	t_sim	*sim;

	(void)pthread_mutex_lock(&philo->mutex_sim);
	sim = philo->sim;
	(void)pthread_mutex_unlock(&philo->mutex_sim);
	if (check_if_philo_starved(sim))
		return (1);
	if (queue_routine(philo, f1, f2) == 1)
		return (1);
	if (check_if_philo_starved(sim))
		return (1);
	lock_forks(philo, f1, f2);
	print_log(philo, "has taken a fork", 0);
	print_log(philo, "has taken a fork", 0);
	update_last_released(sim, f1, f2);
	eat(philo);
	(void)pthread_mutex_unlock(&f2->mutex);
	dequeue(f2);
	send_signal(f2);
	(void)pthread_mutex_unlock(&f1->mutex);
	dequeue(f1);
	send_signal(f1);
	reflect_and_think(philo);
	return (0);
}