-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
1,152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# **************************************************************************** # | ||
# # | ||
# ::: :::::::: # | ||
# Makefile :+: :+: :+: # | ||
# +:+ +:+ +:+ # | ||
# By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ # | ||
# +#+#+#+#+#+ +#+ # | ||
# Created: 2021/09/15 12:21:19 by mdesalle #+# #+# # | ||
# Updated: 2021/11/11 12:21:23 by mlazzare ### ########.fr # | ||
# # | ||
# **************************************************************************** # | ||
|
||
NAME = philo | ||
|
||
CC = gcc | ||
CFLAGS = -Wall -Wextra -Werror | ||
#CFLAGS += -fsanitize=address | ||
|
||
LIB = -lpthread | ||
|
||
SRC = \ | ||
./src/philosphers.c \ | ||
./src/thread_routine.c \ | ||
./src/time.c \ | ||
./src/utils.c \ | ||
./src/ft_atoi.c \ | ||
./src/main.c \ | ||
|
||
OBJ = $(SRC:.c=.o) | ||
|
||
.c.o: | ||
@$(CC) $(CFLAGS) $< -o $@ | ||
|
||
$(NAME): $(LIBFT) $(SRC) | ||
$(CC) $(SRC) $(CFLAGS) $(LIB) -o $(NAME) | ||
|
||
all: $(NAME) | ||
|
||
clean: | ||
@rm -rf $(OBJ) | ||
|
||
fclean: clean | ||
@rm -rf $(NAME) | ||
|
||
re: fclean all | ||
|
||
.PHONY: all clean fclean re |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* philo.h :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2021/10/07 14:32:05 by mlazzare #+# #+# */ | ||
/* Updated: 2021/11/11 16:22:31 by mlazzare ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#ifndef PHILO_H | ||
# define PHILO_H | ||
|
||
# include <stdio.h> | ||
# include <string.h> | ||
# include <pthread.h> | ||
# include <stdlib.h> | ||
# include <unistd.h> | ||
# include <limits.h> | ||
# include <sys/time.h> | ||
|
||
# define FORK "has taken a fork" | ||
# define EAT "is eating" | ||
# define SLEEP "is sleeping" | ||
# define THINK "is thinking" | ||
# define DIE "\e[0;31mDIED (ভ_ ভ)\e[m" | ||
# define LEFT 0 | ||
# define RIGHT 1 | ||
|
||
typedef struct s_params | ||
{ | ||
int num; | ||
int ready; | ||
int time2die; | ||
int time2eat; | ||
int time2sleep; | ||
int max_iter; | ||
int check_meal; | ||
int over; | ||
long int start; | ||
pthread_mutex_t *death; | ||
pthread_mutex_t *fork; | ||
pthread_mutex_t *write; | ||
} t_params; | ||
|
||
typedef struct s_philo | ||
{ | ||
int id; | ||
int iter_num; | ||
long int thread_start; | ||
long int last_meal; | ||
long int sleep; | ||
pthread_t life_tid; | ||
pthread_mutex_t *left_fork; | ||
pthread_mutex_t *right_fork; | ||
t_params *params; | ||
} t_philo; | ||
|
||
int philosophers(t_params *p); | ||
int init_philo(t_params *p, t_philo *philo); | ||
int print_routine(t_philo *p, char *action); | ||
int check_death(t_philo *p); | ||
int ft_atoi(const char *str); | ||
void *thread_routine(void *job); | ||
int ft_usleep(long int time); | ||
void final_print(int alive); | ||
int error_msg(char *s, t_params *par, t_philo *p, int malloc); | ||
long int time_now(t_philo *p); | ||
|
||
#endif |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* ft_atoi.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2020/11/10 08:05:31 by mlazzare #+# #+# */ | ||
/* Updated: 2021/11/02 09:49:07 by mlazzare ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "../inc/philo.h" | ||
|
||
static int ft_isnumber(const char *s) | ||
{ | ||
int i; | ||
|
||
i = 0; | ||
if (s[i] && (s[i] == '-' || s[i] == '+')) | ||
i++; | ||
while (s[i]) | ||
{ | ||
if (!(s[i] >= '0' && s[i] <= '9')) | ||
return (0); | ||
i++; | ||
} | ||
return (1); | ||
} | ||
|
||
static int check_sign(char c) | ||
{ | ||
if (c == '-') | ||
return (-1); | ||
return (1); | ||
} | ||
|
||
static int check_overflow(int sign) | ||
{ | ||
if (sign == 1) | ||
return (-1); | ||
return (0); | ||
} | ||
|
||
int ft_atoi(const char *str) | ||
{ | ||
int i; | ||
int sign; | ||
unsigned long long int n; | ||
|
||
i = 0; | ||
n = 0; | ||
if (!ft_isnumber(str)) | ||
return (-1); | ||
sign = 1; | ||
while ((str[i] >= 9 && str[i] <= 13) || str[i] == ' ') | ||
i++; | ||
if (str[i] == '-' || str[i] == '+') | ||
sign = check_sign(str[i++]); | ||
while (str[i] >= '0' && str[i] <= '9') | ||
{ | ||
if (n >= LONG_MAX) | ||
{ | ||
n = check_overflow(sign); | ||
break ; | ||
} | ||
n = n * 10 + (str[i++] - '0'); | ||
} | ||
return (sign * (int)n); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* main.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2021/10/07 14:31:20 by mlazzare #+# #+# */ | ||
/* Updated: 2021/11/11 16:11:14 by mlazzare ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "../inc/philo.h" | ||
|
||
int init_philo(t_params *p, t_philo *philo) | ||
{ | ||
int i; | ||
|
||
i = -1; | ||
while (++i < p->num) | ||
{ | ||
philo[i].id = i; | ||
philo[i].iter_num = 0; | ||
philo[i].thread_start = 0; | ||
philo[i].last_meal = 0; | ||
philo[i].params = p; | ||
philo[i].left_fork = &p->fork[i]; | ||
philo[i].right_fork = 0; | ||
} | ||
return (0); | ||
} | ||
|
||
static int init_params_mutex(t_params *p) | ||
{ | ||
int i; | ||
|
||
i = -1; | ||
p->death = 0; | ||
p->write = 0; | ||
p->fork = 0; | ||
p->death = malloc(sizeof(pthread_mutex_t)); | ||
if (!p->death) | ||
return (error_msg("Error\nMutex death: malloc failed\n", p, 0, 1)); | ||
p->write = malloc(sizeof(pthread_mutex_t)); | ||
if (!p->write) | ||
return (error_msg("Error\nMutex death: malloc failed\n", p, 0, 1)); | ||
p->fork = malloc(sizeof(pthread_mutex_t) * p->num); | ||
if (!p->fork) | ||
return (error_msg("Error\nMutex fork: malloc failed\n", p, 0, 1)); | ||
if (pthread_mutex_init(p->death, NULL) == -1) | ||
return (error_msg("Error\nMutex death init failed\n", p, 0, 1)); | ||
if (pthread_mutex_init(p->write, NULL) == -1) | ||
return (error_msg("Error\nMutex write init failed\n", p, 0, 1)); | ||
while (++i < p->num) | ||
if (pthread_mutex_init(&p->fork[i], NULL) == -1) | ||
return (error_msg("Error\nMutex init failed\n", p, 0, 1)); | ||
return (0); | ||
} | ||
|
||
static int init_params(t_params *p, char **ag) | ||
{ | ||
int mutex; | ||
|
||
mutex = 0; | ||
p->num = ft_atoi(ag[1]); | ||
if (p->num == 0) | ||
return (printf("No philo here ...\n")); | ||
p->ready = 0; | ||
p->time2die = ft_atoi(ag[2]); | ||
if (p->time2die == 0) | ||
return (printf("No time to even be born ...\n")); | ||
p->time2eat = ft_atoi(ag[3]); | ||
p->time2sleep = ft_atoi(ag[4]); | ||
p->max_iter = 0; | ||
p->check_meal = 0; | ||
p->start = 0; | ||
if (ag[5]) | ||
{ | ||
p->check_meal = 1; | ||
p->max_iter = ft_atoi(ag[5]); | ||
} | ||
p->over = 0; | ||
if (p->num > 0) | ||
mutex = init_params_mutex(p); | ||
return (mutex || p->num < 0 || p->time2die < 0 || p->time2eat < 0 | ||
|| p->time2sleep < 0 || p->max_iter < 0); | ||
} | ||
|
||
int main(int ac, char **ag) | ||
{ | ||
t_params p; | ||
|
||
memset(&p, 0, sizeof(p)); | ||
if ((ac != 5 && ac != 6) || init_params(&p, ag)) | ||
return (error_msg("Error: invalid arguments\n", &p, 0, 1)); | ||
if (philosophers(&p)) | ||
return (EXIT_FAILURE); | ||
return (EXIT_SUCCESS); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* philosphers.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2021/10/07 14:31:20 by mlazzare #+# #+# */ | ||
/* Updated: 2021/11/11 16:14:22 by mlazzare ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "../inc/philo.h" | ||
|
||
static int check_meals(t_philo p, int last) | ||
{ | ||
if (p.params->check_meal && last == p.params->num - 1 | ||
&& p.iter_num == p.params->max_iter) | ||
return (ft_usleep(300)); | ||
return (0); | ||
} | ||
|
||
static void check_thread(t_params *p, t_philo *philo) | ||
{ | ||
int i; | ||
|
||
while (!p->over) | ||
{ | ||
i = -1; | ||
while (++i < p->num) | ||
if (check_death(&philo[i]) || check_meals(philo[i], i)) | ||
p->over = 1; | ||
} | ||
if (p->check_meal) | ||
{ | ||
ft_usleep(1 * p->num); | ||
printf(" \n"); | ||
printf(" All philosophers have eaten %d times\n", p->max_iter); | ||
return (final_print(1)); | ||
} | ||
final_print(0); | ||
} | ||
|
||
static int init_thread(t_params *p, t_philo *philo) | ||
{ | ||
int i; | ||
|
||
i = -1; | ||
|
||
while (++i < p->num) | ||
{ | ||
philo[i].right_fork = philo[(i + 1) % p->num].left_fork; | ||
if (pthread_create(&philo[i].life_tid, NULL, | ||
&thread_routine, &philo[i]) == -1) | ||
return (error_msg("Error\nFailed to create thread\n", p, philo, 2)); | ||
} | ||
i = -1; | ||
p->start = time_now(philo); | ||
while (++i < p->num) | ||
{ | ||
philo[i].thread_start = philo->params->start; | ||
philo[i].last_meal = philo->params->start; | ||
} | ||
p->ready = 1; | ||
return (0); | ||
} | ||
|
||
static void end_thread(t_params *p, t_philo *philo) | ||
{ | ||
int i; | ||
|
||
i = -1; | ||
while (++i < p->num) | ||
pthread_join(philo[i].life_tid, (void *)&philo[i]); | ||
pthread_mutex_destroy(p->death); | ||
pthread_mutex_destroy(p->fork); | ||
pthread_mutex_destroy(p->write); | ||
free(p->death); | ||
free(p->fork); | ||
free(p->write); | ||
free(philo); | ||
} | ||
|
||
int philosophers(t_params *params) | ||
{ | ||
t_philo *philo; | ||
|
||
philo = malloc(sizeof(t_philo) * params->num); | ||
if (!philo || init_philo(params, philo)) | ||
return (EXIT_FAILURE); | ||
if (init_thread(params, philo)) | ||
return (EXIT_FAILURE); | ||
check_thread(params, philo); | ||
end_thread(params, philo); | ||
return (0); | ||
} |
Oops, something went wrong.