/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* philo.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/16 14:03:42 by narnaud #+# #+# */ /* Updated: 2022/05/20 10:34:10 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" void *check_halt(void *p) { int time; t_philo *philo; philo = p; while (1) { usleep(1000); time = gettime(); if (time - philo->last_meal_time > philo->table->param[DIE_TIME]) { printf("%i %d died\n", time, philo->id); exit(EXIT_SUCCESS); } if (philo->meals_done == philo->table->param[MEALS_AMOUNT]) exit(EXIT_SUCCESS); } } void philo_life(t_philo *philo) { t_table *table; table = philo->table; while (1) { sem_wait(table->sptr); printf("%i %d has taken a fork\n", gettime(), philo->id); sem_wait(table->sptr); printf("%i %d has taken a fork\n", gettime(), philo->id); philo->last_meal_time = gettime(); printf("%i %d is eating\n", gettime(), philo->id); usleep(table->param[EAT_DURATION] * 1000); philo->meals_done++; sem_post(table->sptr); sem_post(table->sptr); printf("%i %d is sleeping\n", gettime(), philo->id); usleep(table->param[SLEEP_DURATION] * 1000); printf("%i %d is thinking\n", gettime(), philo->id); } } void init_philos(t_table *table) { int i; pthread_t checks; int amount; amount = table->param[PHILO_AMOUNT]; table->pid = malloc(sizeof(pid_t) * amount); i = 0; while (i < amount) { table->pid[i] = fork(); table->philos[i].table = table; table->philos[i].id = i; table->philos[i].meals_done = 0; if (!table->pid[i]) { pthread_create(&checks, NULL, check_halt, table->philos + i); philo_life(table->philos + i); } usleep(500); i++; } } int main(int argc, char **argv) { static t_table *table; static int i = 0; static int status; sem_unlink("/chopsticks"); sem_unlink("/death"); if (argc < 5 || argc > 6) return (1); table = parsing(argv + 1); table->sptr = sem_open("/chopsticks", O_CREAT, 0664, table->param[PHILO_AMOUNT]); table->death = sem_open("/death", O_CREAT, 0664, 1); init_philos(table); waitpid(-1, &status, 0); while (i < table->param[PHILO_AMOUNT]) { kill(table->pid[i], SIGINT); i++; } sem_unlink("/chopsticks"); sem_unlink("/deaths"); return (0); }