-
Notifications
You must be signed in to change notification settings - Fork 0
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
1 parent
f2ccec6
commit 602d940
Showing
8 changed files
with
411 additions
and
0 deletions.
There are no files selected for viewing
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,26 @@ | ||
NAME = philo | ||
CC = gcc | ||
FLAGS = -Wall -Werror -Wextra -pthread | ||
RM = rm -rf | ||
|
||
SRC = philo.c dinner.c utils.c check.c | ||
|
||
OBJECTS = $(SRC:.c=.o) | ||
|
||
.c.o: | ||
$(CC) $(FLAGS) -c $< -o $(<:.c=.o) | ||
|
||
all: $(NAME) | ||
|
||
$(NAME): $(OBJECTS) philo.h | ||
$(CC) $(FLAGS) $(OBJECTS) -o $(NAME) | ||
|
||
clean: | ||
$(RM) $(OBJECTS) | ||
|
||
fclean: clean | ||
$(RM) $(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,46 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* check.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: cyalniz <[email protected]> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2022/09/15 18:28:54 by cyalniz #+# #+# */ | ||
/* Updated: 2022/09/19 10:25:34 by cyalniz ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "philo.h" | ||
|
||
int check_args(t_data *data) | ||
{ | ||
if (data->num_philo < 1 || data->t_die < 1 | ||
|| data->t_eat < 1 || data->t_sleep < 1) | ||
{ | ||
printf("Error: Arguments problem, arguments cannot less than 1\n"); | ||
return (-1); | ||
} | ||
return (1); | ||
} | ||
|
||
int check_meals(t_philo *philo) | ||
{ | ||
int ph_id; | ||
|
||
ph_id = 0; | ||
if (philo->data_of_philo->must_eat > 0) | ||
{ | ||
while (ph_id < philo->data_of_philo->num_philo) | ||
{ | ||
if (philo[ph_id].p_eat_count == philo->data_of_philo->must_eat) | ||
philo->data_of_philo->total_meal++; | ||
ph_id++; | ||
} | ||
if (philo->data_of_philo->total_meal >= philo->data_of_philo->num_philo) | ||
{ | ||
philo->data_of_philo->is_died = 1; | ||
return (1); | ||
} | ||
} | ||
return (0); | ||
} |
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,109 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* dinner.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: cyalniz <[email protected]> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2022/09/15 18:28:37 by cyalniz #+# #+# */ | ||
/* Updated: 2022/09/19 10:20:08 by cyalniz ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "philo.h" | ||
|
||
void finish_dinner(t_philo *philo, t_data *data) | ||
{ | ||
int fork_id; | ||
|
||
fork_id = 0; | ||
while (fork_id < data->num_philo) | ||
{ | ||
pthread_mutex_destroy(&data->fork_lock[fork_id]); | ||
fork_id++; | ||
} | ||
pthread_mutex_destroy(&data->print_lock); | ||
free(data->fork_lock); | ||
free(philo); | ||
return ; | ||
} | ||
|
||
void eat_func(t_philo *philo) | ||
{ | ||
pthread_mutex_lock(&philo->data_of_philo->fork_lock[philo->left_fork]); | ||
pthread_mutex_lock(&philo->data_of_philo->fork_lock[philo->right_fork]); | ||
print(philo, "has taken left fork", 'f'); | ||
print(philo, "has taken right fork", 'f'); | ||
print(philo, "is eating", 'e'); | ||
philo->last_meal = get_time(); | ||
ft_wait(philo->data_of_philo->t_eat, philo); | ||
pthread_mutex_unlock(&philo->data_of_philo->fork_lock[philo->left_fork]); | ||
pthread_mutex_unlock(&philo->data_of_philo->fork_lock[philo->right_fork]); | ||
return ; | ||
} | ||
|
||
void *observer(void *ptr) | ||
{ | ||
t_philo *phi; | ||
int phi_id; | ||
|
||
phi = (t_philo *)ptr; | ||
while (!check_meals(phi)) | ||
{ | ||
phi_id = 0; | ||
while (phi_id < phi->data_of_philo->num_philo) | ||
{ | ||
if (get_time() - phi[phi_id].last_meal > phi->data_of_philo->t_die) | ||
{ | ||
print(&phi[phi_id], "died !!!", 'd'); | ||
phi->data_of_philo->is_died = 1; | ||
return (NULL); | ||
} | ||
phi_id++; | ||
} | ||
ft_wait(10, phi); | ||
} | ||
return (NULL); | ||
} | ||
|
||
void *loop(void *ptr) | ||
{ | ||
t_philo *philo; | ||
|
||
philo = (t_philo *)ptr; | ||
if (philo->philo_id % 2 != 0) | ||
usleep(1600); | ||
while (philo->data_of_philo->is_died != 1) | ||
{ | ||
eat_func(philo); | ||
print(philo, "is sleeping", 's'); | ||
ft_wait(philo->data_of_philo->t_sleep, philo); | ||
print(philo, "is thinking", 't'); | ||
usleep(1000); | ||
philo->p_eat_count++; | ||
} | ||
return (NULL); | ||
} | ||
|
||
int start_dinner(t_philo *phi) | ||
{ | ||
int p_id; | ||
pthread_t monitor; | ||
|
||
p_id = -1; | ||
phi->data_of_philo->start_time = get_time(); | ||
while (++p_id < phi->data_of_philo->num_philo) | ||
{ | ||
if (pthread_create(&phi[p_id].thread, NULL, &loop, &phi[p_id]) == -1) | ||
return (-1); | ||
} | ||
if (pthread_create(&monitor, NULL, &observer, phi) == -1) | ||
return (-1); | ||
p_id = -1; | ||
while (++p_id < phi->data_of_philo->num_philo) | ||
{ | ||
pthread_join(phi[p_id].thread, NULL); | ||
} | ||
pthread_join(monitor, NULL); | ||
return (1); | ||
} |
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,83 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* philo.c :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: cyalniz <[email protected]> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2022/09/15 18:28:27 by cyalniz #+# #+# */ | ||
/* Updated: 2022/09/19 10:09:40 by cyalniz ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#include "philo.h" | ||
|
||
t_philo *init_philo(t_data *data) | ||
{ | ||
t_philo *philo; | ||
int p_indx; | ||
|
||
p_indx = 0; | ||
philo = malloc(sizeof(t_philo) * data->num_philo); | ||
while (p_indx < data->num_philo) | ||
{ | ||
philo[p_indx].philo_id = p_indx + 1; | ||
philo[p_indx].left_fork = p_indx; | ||
philo[p_indx].right_fork = p_indx + 1; | ||
philo[p_indx].last_meal = get_time(); | ||
philo[p_indx].p_eat_count = 0; | ||
philo[p_indx].data_of_philo = data; | ||
pthread_mutex_init(&data->fork_lock[p_indx], NULL); | ||
p_indx++; | ||
} | ||
philo[0].left_fork = 0; | ||
return (philo); | ||
} | ||
|
||
int init_data(t_data *data, int ac, char **av) | ||
{ | ||
if (ac < 5 || ac > 6) | ||
{ | ||
printf("Error: Argument count is wrong!\n"); | ||
return (-1); | ||
} | ||
data->num_philo = ft_atoi(av[1]); | ||
if (data->num_philo == 1) | ||
{ | ||
printf("Philo 1 died...\n"); | ||
return (-1); | ||
} | ||
data->t_die = ft_atoi(av[2]); | ||
data->t_eat = ft_atoi(av[3]); | ||
data->t_sleep = ft_atoi(av[4]); | ||
data->must_eat = 0; | ||
if (ac == 6) | ||
data->must_eat = ft_atoi(av[5]); | ||
data->is_died = 0; | ||
data->total_meal = 0; | ||
data->fork_lock = malloc(sizeof(pthread_mutex_t) * data->num_philo); | ||
pthread_mutex_init(&data->print_lock, NULL); | ||
return (1); | ||
} | ||
|
||
int main(int ac, char **av) | ||
{ | ||
t_data data; | ||
t_philo *philo; | ||
int data_check; | ||
int arg_check; | ||
int thread_check; | ||
|
||
data_check = init_data(&data, ac, av); | ||
if (data_check == -1) | ||
return (0); | ||
arg_check = check_args(&data); | ||
if (arg_check == -1) | ||
return (0); | ||
philo = init_philo(&data); | ||
thread_check = start_dinner(philo); | ||
if (thread_check == -1) | ||
return (0); | ||
finish_dinner(philo, &data); | ||
return (0); | ||
} |
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,64 @@ | ||
/* ************************************************************************** */ | ||
/* */ | ||
/* ::: :::::::: */ | ||
/* philo.h :+: :+: :+: */ | ||
/* +:+ +:+ +:+ */ | ||
/* By: cyalniz <[email protected]> +#+ +:+ +#+ */ | ||
/* +#+#+#+#+#+ +#+ */ | ||
/* Created: 2022/09/15 18:30:04 by cyalniz #+# #+# */ | ||
/* Updated: 2022/09/19 10:10:08 by cyalniz ### ########.fr */ | ||
/* */ | ||
/* ************************************************************************** */ | ||
|
||
#ifndef PHILO_H | ||
# define PHILO_H | ||
|
||
# include <stdio.h> | ||
# include <pthread.h> | ||
# include <stdlib.h> | ||
# include <unistd.h> | ||
# include <sys/time.h> | ||
|
||
typedef struct s_data | ||
{ | ||
int num_philo; | ||
int t_die; | ||
int t_eat; | ||
int t_sleep; | ||
int must_eat; | ||
int total_meal; | ||
long start_time; | ||
int is_died; | ||
pthread_mutex_t print_lock; | ||
pthread_mutex_t *fork_lock; | ||
} t_data; | ||
|
||
typedef struct s_philo | ||
{ | ||
pthread_t thread; | ||
t_data *data_of_philo; | ||
int philo_id; | ||
int p_eat_count; | ||
long last_meal; | ||
int left_fork; | ||
int right_fork; | ||
} t_philo; | ||
|
||
//init | ||
int init_data(t_data *data, int ac, char **av); | ||
t_philo *init_philo(t_data *data); | ||
//utils | ||
int check_args(t_data *data); | ||
void print(t_philo *philo, char *state, char c); | ||
long get_time(void); | ||
int check_meals(t_philo *philo); | ||
int ft_atoi(char *ptr); | ||
//dinner | ||
void finish_dinner(t_philo *philo, t_data *data); | ||
void eat_func(t_philo *philo); | ||
void *loop(void *ptr); | ||
void *observer(void *ptr); | ||
int start_dinner(t_philo *philo); | ||
void ft_wait(long long time, t_philo *sim); | ||
|
||
#endif |
Oops, something went wrong.