/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* death_monitor.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ruiferna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/10/09 20:16:37 by ruiferna #+# #+# */ /* Updated: 2025/10/10 20:51:41 by ruiferna ### ########.fr */ /* */ /* ************************************************************************** */ #include "simple_philosophers.h" #define WORKERS 900 static pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER; int get_random_sleep_duration() { unsigned int seed; pthread_mutex_lock(&random_mutex); seed = time(NULL) ^ pthread_self(); /* produce a duration between 1000 and 4000 ms (1-4 seconds) */ int duration = 1000 + rand_r(&seed) % 6001; pthread_mutex_unlock(&random_mutex); return duration; } typedef struct { pthread_mutex_t mutex; struct timeval last_activity_time; int alive; // 1 if alive, 0 if dead } WorkerState; typedef struct s_shared { int id; int is_dead; pthread_t workers[WORKERS]; long long last_updated[WORKERS]; pthread_mutex_t workers_mutexes[WORKERS]; pthread_mutex_t mutex_id; } t_shared; void *worker_routine(void *arg) { t_shared *shared; int worker_id; int sleep_time; shared = (t_shared *) arg; /* assign a unique id in range [0, WORKERS-1] */ pthread_mutex_lock(&shared->mutex_id); shared->id += 1; worker_id = shared->id; pthread_mutex_unlock(&shared->mutex_id); while (1) { pthread_mutex_lock(&shared->workers_mutexes[worker_id]); shared->last_updated[worker_id] = get_current_time(); pthread_mutex_unlock(&shared->workers_mutexes[worker_id]); sleep_time = get_random_sleep_duration(); printf("Worker %i will stop for %i seconds.\n", worker_id, (int)(sleep_time / 1000)); precise_sleep(sleep_time); } return (NULL); } void *monitor_routine(void *arg) { t_shared *shared; long long time_diff; int i; shared = (t_shared *) arg; while (1) { i = 0; while (i < WORKERS) { pthread_mutex_lock(&shared->workers_mutexes[i]); time_diff = get_current_time() - shared->last_updated[i]; pthread_mutex_unlock(&shared->workers_mutexes[i]); if (time_diff > 3000) { printf("Worker %i died.\n", i); return (NULL); } i++; } /* sleep once per full scan to keep checks frequent and non-blocking */ precise_sleep(50); } return (NULL); } int main() { t_shared shared; pthread_t monitor; int i; i = 0; shared.id = 0; while (i < WORKERS) { pthread_mutex_init(&shared.workers_mutexes[i], NULL); i++; } pthread_mutex_init(&shared.mutex_id, NULL); i = 0; while (i < WORKERS) { if (pthread_create(&shared.workers[i], NULL, worker_routine, &shared) != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } i++; } pthread_create(&monitor, NULL, monitor_routine, &shared); pthread_join(monitor, NULL); // i = 0; // while (i < WORKERS) // { // pthread_join(shared.workers[i], NULL); // i++; // } return (0); }