splitphilos working on 1 5fork bug and death

This commit is contained in:
whaffman 2025-01-10 16:00:52 +01:00
parent 1707d4ab5c
commit 3de1ac17b3
17 changed files with 146 additions and 66 deletions

33
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,33 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug philo",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/philo/philo",
"args": [
"5", "800", "200", "200", "7"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/philo",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build philo",
"miDebuggerPath": "/usr/bin/gdb",
"logging": {
"moduleLoad": false,
"trace": false
},
"internalConsoleOptions": "openOnSessionStart"
}
]
}

20
.vscode/tasks.json vendored
View File

@ -0,0 +1,20 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build philo",
"type": "shell",
"command": "make",
"args": [
"-C",
"philo"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"detail": "Build the philo project using the Makefile"
}
]
}

View File

@ -14,12 +14,10 @@ NAME = philo
SRC_PATH = src SRC_PATH = src
INC_PATH = inc INC_PATH = inc
OBJ_PATH = obj OBJ_PATH = obj
VPATH = src:src/utils VPATH = src:src/utils
SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c")) SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c"))
OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o)) OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o))
DEPENDS = ${OBJECTS:.o=.d} DEPENDS = ${OBJECTS:.o=.d}
@ -27,7 +25,7 @@ CC = cc
RM = rm -rf RM = rm -rf
INCLUDES = -I./$(INC_PATH) INCLUDES = -I./$(INC_PATH)
CFLAGS = -Wall -Wextra -Werror -MMD CFLAGS = -Wall -Wextra -Werror -MMD -g
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)

View File

@ -12,6 +12,8 @@
# define SUCCESS 1 # define SUCCESS 1
# define FAILURE 0 # define FAILURE 0
# define START_DELAY 500
# define ERROR_USAGE "Usage: ./philo number_of_philosophers time_to_die " \ # define ERROR_USAGE "Usage: ./philo number_of_philosophers time_to_die " \
"time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]\n" "time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]\n"
# define ERROR_MUTEX "Can not create mutex" # define ERROR_MUTEX "Can not create mutex"
@ -25,10 +27,10 @@ typedef struct s_rules
int time_to_eat; int time_to_eat;
int time_to_sleep; int time_to_sleep;
int n_must_eat; int n_must_eat;
int death; int finished;
int start_time; int start_time;
pthread_mutex_t *print_lock; pthread_mutex_t *print_lock;
pthread_mutex_t *death_lock; pthread_mutex_t *finished_lock;
pthread_mutex_t *forks; pthread_mutex_t *forks;
struct s_philo *philos; struct s_philo *philos;
@ -64,10 +66,9 @@ void print_status(t_philo *philo, char *status);
void *philo_routine(void *philo); void *philo_routine(void *philo);
int join_threads(t_rules *rules); int join_threads(t_rules *rules);
void print_rules(t_rules *rules); void print_rules(t_rules *rules);
int check_alive(t_philo *philo); int check_death(t_philo *philo);
void philo_die(t_philo *philo);
int philo_died_while_sleeping(t_philo *philo, int time);
int philo_eat(t_philo *philo);
#endif #endif

Binary file not shown.

View File

@ -1,17 +1,7 @@
#include "philo.h" #include "philo.h"
int check_alive(t_philo *philo) int check_death(t_philo *philo)
{ {
if (get_time() - philo->last_meal > philo->rules->time_to_die) return (get_time() - philo->last_meal >= philo->rules->time_to_die);
{ }
print_status(philo, "died");
philo->death = 1;
pthread_mutex_lock(philo->rules->death_lock);
philo->rules->death = 1;
pthread_mutex_unlock(philo->rules->death_lock);
pthread_mutex_unlock(philo->l_fork);
pthread_mutex_unlock(philo->r_fork);
return (FAILURE);
}
return (SUCCESS);
}

View File

@ -6,7 +6,7 @@ int create_mutexes(t_rules *rules)
i = 0; i = 0;
printf("creating mutexes\n"); printf("creating mutexes\n");
if (pthread_mutex_init(rules->death_lock, NULL)) if (pthread_mutex_init(rules->finished_lock, NULL))
return(printf("death mutex created"), FAILURE); return(printf("death mutex created"), FAILURE);
if (pthread_mutex_init(rules->print_lock, NULL)) if (pthread_mutex_init(rules->print_lock, NULL))
return(printf("print mutex created"), FAILURE); return(printf("print mutex created"), FAILURE);

View File

@ -18,7 +18,7 @@ int create_philos(t_rules *rules)
philo->death = 0; philo->death = 0;
philo->pid = 0; philo->pid = 0;
philo->rules = rules; philo->rules = rules;
philo->last_meal = get_time(); philo->last_meal = get_time() + START_DELAY;
i++; i++;
} }
return (SUCCESS); return (SUCCESS);

View File

@ -5,7 +5,7 @@ int destroy_mutexes(t_rules *rules)
int i; int i;
i = 0; i = 0;
if (pthread_mutex_destroy(rules->death_lock)) if (pthread_mutex_destroy(rules->finished_lock))
return(FAILURE); return(FAILURE);
if (pthread_mutex_destroy(rules->print_lock)) if (pthread_mutex_destroy(rules->print_lock))
return(FAILURE); return(FAILURE);

View File

@ -5,5 +5,5 @@ void free_philos(t_rules *rules)
free(rules->philos); free(rules->philos);
free(rules->forks); free(rules->forks);
free(rules->print_lock); free(rules->print_lock);
free(rules->death_lock); free(rules->finished_lock);
} }

View File

@ -13,13 +13,13 @@ int main(int argc, char *argv[])
if (FAILURE == create_mutexes(&rules)) if (FAILURE == create_mutexes(&rules))
return (printf(ERROR_MUTEX), EXIT_FAILURE); return (printf(ERROR_MUTEX), EXIT_FAILURE);
printf("mutexes created\n"); printf("mutexes created\n");
rules.start_time = get_time(); rules.start_time = get_time() + START_DELAY;
if (FAILURE == create_threads(&rules)) if (FAILURE == create_threads(&rules))
return (printf(ERROR_THREADS), EXIT_FAILURE); return (printf(ERROR_THREADS), EXIT_FAILURE);
printf("threads created\n"); printf("threads created\n");
if (FAILURE == join_threads(&rules)) if (FAILURE == join_threads(&rules))
return (printf(ERROR_THREADS), EXIT_FAILURE); return (printf(ERROR_THREADS), EXIT_FAILURE);
printf("threads joined\n");
if (FAILURE == destroy_mutexes(&rules)) if (FAILURE == destroy_mutexes(&rules))
return (printf(ERROR_MUTEX), EXIT_FAILURE); return (printf(ERROR_MUTEX), EXIT_FAILURE);
printf("mutexes destroyed\n"); printf("mutexes destroyed\n");

View File

@ -1,12 +0,0 @@
#include "philo.h"
void *monitor_death(void *arg)
{
int i;
t_rules *rules;
rules = (t_rules *) i = 0;
while (i < rules->n_philos)
if (rules->philos[i].last_meal - get_time() < rules->time_to_die)
}

View File

@ -17,8 +17,8 @@ int parse_arguments(int argc,char *argv[], t_rules *rules)
if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat)) if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat))
return (FAILURE); return (FAILURE);
rules->print_lock = malloc(sizeof(pthread_mutex_t)); rules->print_lock = malloc(sizeof(pthread_mutex_t));
rules->death_lock = malloc(sizeof(pthread_mutex_t)); rules->finished_lock = malloc(sizeof(pthread_mutex_t));
if (!rules->print_lock || !rules->death_lock) if (!rules->print_lock || !rules->finished_lock)
return (FAILURE); return (FAILURE);
rules->forks = malloc(rules->n_philos * sizeof(pthread_mutex_t)); rules->forks = malloc(rules->n_philos * sizeof(pthread_mutex_t));
if (!rules->forks) if (!rules->forks)

View File

@ -1,36 +1,86 @@
#include "philo.h" #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 == 0)
{
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 *philo_routine(void *arg) void *philo_routine(void *arg)
{ {
t_philo *philo; t_philo *philo;
philo = (t_philo *)arg; philo = (t_philo *)arg;
while (!philo->death && !philo->rules->death
while (get_time() < philo->rules->start_time)
usleep(50);
while (!philo->death && !philo->rules->finished
&& (philo->n_eat < philo->rules->n_must_eat || philo->rules->n_must_eat == -1)) && (philo->n_eat < philo->rules->n_must_eat || philo->rules->n_must_eat == -1))
{ {
if (philo->id % 2 == 1)
{ if (check_death(philo))
pthread_mutex_lock(philo->r_fork); return (philo_die(philo), NULL);
print_status(philo, "has taken a fork"); if (!philo_eat(philo))
} return (NULL);
pthread_mutex_lock(philo->l_fork); if (philo_died_while_sleeping(philo, philo->rules->time_to_eat))
print_status(philo, "has taken a fork"); return (philo_die(philo), NULL);
if (philo->id % 2 == 0)
{
pthread_mutex_lock(philo->r_fork);
print_status(philo, "has taken a fork");
}
if (!check_alive(philo))
break ;
print_status(philo, "is eating");
philo->last_meal = get_time();
philo->n_eat++;
usleep(philo->rules->time_to_eat * 1000);
pthread_mutex_unlock(philo->l_fork); pthread_mutex_unlock(philo->l_fork);
pthread_mutex_unlock(philo->r_fork); pthread_mutex_unlock(philo->r_fork);
print_status(philo, "is sleeping"); print_status(philo, "is sleeping 💤");
usleep(philo->rules->time_to_sleep * 1000); if (philo_died_while_sleeping(philo, philo->rules->time_to_sleep))
print_status(philo, "is thinking"); return (philo_die(philo), NULL);
print_status(philo, "is thinking 💭");
} }
return (NULL); return (NULL);
} }