92 lines
2.7 KiB
C
92 lines
2.7 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* death.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2024/11/22 14:20:46 by lfirmin #+# #+# */
|
|
/* Updated: 2025/03/17 04:52:57 by lfirmin ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#include "../include/philo.h"
|
|
|
|
void set_dead_and_print(t_data *data, int philo_idx, long long current_time)
|
|
{
|
|
pthread_mutex_lock(&data->dead_mutex);
|
|
data->dead_flag = 1;
|
|
pthread_mutex_unlock(&data->dead_mutex);
|
|
pthread_mutex_unlock(&data->philos[philo_idx].meal_lock);
|
|
pthread_mutex_lock(&data->print);
|
|
printf("%lld %lld died\n", current_time - data->start_time,
|
|
data->philos[philo_idx].id);
|
|
pthread_mutex_unlock(&data->print);
|
|
}
|
|
|
|
static void set_all_ate_and_print(t_data *data)
|
|
{
|
|
pthread_mutex_lock(&data->dead_mutex);
|
|
data->dead_flag = 1;
|
|
pthread_mutex_unlock(&data->dead_mutex);
|
|
pthread_mutex_lock(&data->print);
|
|
printf("Each philosopher has eaten %lld times\n", data->must_eat);
|
|
pthread_mutex_unlock(&data->print);
|
|
}
|
|
|
|
static int check_philo_death(t_data *data, int idx, int *all_ate_enough)
|
|
{
|
|
long long current_time;
|
|
long long time_since_last_meal;
|
|
|
|
if (check_if_dead_data(data))
|
|
return (1);
|
|
pthread_mutex_lock(&data->philos[idx].meal_lock);
|
|
current_time = get_time();
|
|
time_since_last_meal = current_time - data->philos[idx].last_meal;
|
|
if (time_since_last_meal > data->t_die)
|
|
{
|
|
set_dead_and_print(data, idx, current_time);
|
|
return (1);
|
|
}
|
|
if (data->must_eat != -1 && data->philos[idx].m_eaten < data->must_eat)
|
|
*all_ate_enough = 0;
|
|
pthread_mutex_unlock(&data->philos[idx].meal_lock);
|
|
return (0);
|
|
}
|
|
|
|
static int check_all_philos(t_data *data)
|
|
{
|
|
int i;
|
|
int all_ate_enough;
|
|
|
|
i = 0;
|
|
all_ate_enough = 1;
|
|
while (i < data->nb_philo)
|
|
{
|
|
if (check_philo_death(data, i, &all_ate_enough))
|
|
return (1);
|
|
i++;
|
|
}
|
|
if (data->must_eat != -1 && all_ate_enough && !check_if_dead_data(data))
|
|
{
|
|
set_all_ate_and_print(data);
|
|
return (1);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
void *death_check(void *arg)
|
|
{
|
|
t_data *data;
|
|
|
|
data = (t_data *)arg;
|
|
while (1)
|
|
{
|
|
if (check_if_dead_data(data))
|
|
return (NULL);
|
|
usleep(500);
|
|
if (check_all_philos(data))
|
|
return (NULL);
|
|
}
|
|
}
|