splitphilos working on 1 5fork bug and death
This commit is contained in:
parent
1707d4ab5c
commit
3de1ac17b3
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal 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
20
.vscode/tasks.json
vendored
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
BIN
philo/philo
BIN
philo/philo
Binary file not shown.
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
@ -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");
|
||||||
|
|||||||
@ -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)
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user