113 lines
3.1 KiB
C
113 lines
3.1 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: o_ :::::: ::: */
|
|
/* philo_routine.c :+: / :+::+: :+: */
|
|
/* +:+ > +:++:+ +:+ */
|
|
/* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#++#++:++#++ */
|
|
/* +#+ +#+#+ +#++#+ +#+ \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);
|
|
}
|