philosophers/philo/src/philo_routine.c
2025-01-24 15:07:02 +01:00

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);
}