diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..e69de29 diff --git a/philo/inc/philo.h b/philo/inc/philo.h index 8668f6c..8ba38ff 100644 --- a/philo/inc/philo.h +++ b/philo/inc/philo.h @@ -16,6 +16,7 @@ "time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]\n" # define ERROR_MUTEX "Can not create mutex" # define ERROR_MALLOC "Malloc Failure" +# define ERROR_THREADS "Can not create threads" typedef struct s_rules { @@ -24,10 +25,12 @@ typedef struct s_rules int time_to_eat; int time_to_sleep; int n_must_eat; - pthread_mutex_t *print; - pthread_mutex_t *death; + int death; + int start_time; + pthread_mutex_t *print_lock; + pthread_mutex_t *death_lock; pthread_mutex_t *forks; - t_philo *philos; + struct s_philo *philos; } t_rules; @@ -40,6 +43,7 @@ typedef struct s_philo int death; int last_meal; t_rules *rules; + int n_eat; } t_philo; // memset, printf, malloc, free, write, @@ -49,6 +53,19 @@ typedef struct s_philo // pthread_mutex_unlock int ph_atoi(const char *nptr, int *res); +int get_time(void); +void free_philos(t_rules *rules); +int destroy_mutexes(t_rules *rules); +int create_philos(t_rules *rules); +int parse_arguments(int argc,char *argv[], t_rules *rules); +int create_mutexes(t_rules *rules); +int create_threads(t_rules *rules); +void print_status(t_philo *philo, char *status); +void *philo_routine(void *philo); +int join_threads(t_rules *rules); +void print_rules(t_rules *rules); + + #endif \ No newline at end of file diff --git a/philo/philo b/philo/philo index 7c22300..8fda598 100755 Binary files a/philo/philo and b/philo/philo differ diff --git a/philo/src/check_alive.c b/philo/src/check_alive.c new file mode 100644 index 0000000..96555c6 --- /dev/null +++ b/philo/src/check_alive.c @@ -0,0 +1,17 @@ +#include "philo.h" + +int check_alive(t_philo *philo) +{ + if (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); +} \ No newline at end of file diff --git a/philo/src/create_mutexes.c b/philo/src/create_mutexes.c index 3980631..edf94af 100644 --- a/philo/src/create_mutexes.c +++ b/philo/src/create_mutexes.c @@ -5,16 +5,20 @@ int create_mutexes(t_rules *rules) int i; i = 0; - if (!pthread_mutex_init(&rules->death, NULL)) - return(FAILURE); - if (!pthread_mutex_init(&rules->print, NULL)) - return(FAILURE); + printf("creating mutexes\n"); + if (pthread_mutex_init(rules->death_lock, NULL)) + return(printf("death mutex created"), FAILURE); + if (pthread_mutex_init(rules->print_lock, NULL)) + return(printf("print mutex created"), FAILURE); + printf("creating forks\n"); rules->forks = malloc(rules->n_philos * sizeof(pthread_mutex_t)); if (!rules->forks) return(FAILURE); while (i < rules->n_philos) { - if (!pthread_mutex_init(&rules->forks[i], NULL)) + if (pthread_mutex_init(&rules->forks[i], NULL)) return(FAILURE); + i++; } + return (SUCCESS); } \ No newline at end of file diff --git a/philo/src/create_philos.c b/philo/src/create_philos.c index 1d36985..c0cf919 100644 --- a/philo/src/create_philos.c +++ b/philo/src/create_philos.c @@ -18,6 +18,8 @@ int create_philos(t_rules *rules) philo->death = 0; philo->pid = 0; philo->rules = rules; + philo->last_meal = get_time(); i++; } + return (SUCCESS); } \ No newline at end of file diff --git a/philo/src/create_threads.c b/philo/src/create_threads.c new file mode 100644 index 0000000..1042a01 --- /dev/null +++ b/philo/src/create_threads.c @@ -0,0 +1,20 @@ +#include "philo.h" + +int create_threads(t_rules *rules) +{ + int i; + t_philo *philo; + + i = 0; + while (i < rules->n_philos) + { + philo = &rules->philos[i]; + philo->pid = malloc(sizeof(pthread_t)); + if (!philo->pid) + return (FAILURE); + if (pthread_create(philo->pid, NULL, &philo_routine, philo)) + return (FAILURE); + i++; + } + return (SUCCESS); +} \ No newline at end of file diff --git a/philo/src/destroy_mutexes.c b/philo/src/destroy_mutexes.c index f17c359..89a7a89 100644 --- a/philo/src/destroy_mutexes.c +++ b/philo/src/destroy_mutexes.c @@ -5,13 +5,15 @@ int destroy_mutexes(t_rules *rules) int i; i = 0; - if (!pthread_mutex_destroy(&rules->death)) + if (pthread_mutex_destroy(rules->death_lock)) return(FAILURE); - if (!pthread_mutex_destroy(&rules->print)) + if (pthread_mutex_destroy(rules->print_lock)) return(FAILURE); while (i < rules->n_philos) { - if (!pthread_mutex_destroy(&rules->forks[i])) + if (pthread_mutex_destroy(&rules->forks[i])) return(FAILURE); + i++; } + return (SUCCESS); } \ No newline at end of file diff --git a/philo/src/free_philos.c b/philo/src/free_philos.c index dc6afd4..1950c1d 100644 --- a/philo/src/free_philos.c +++ b/philo/src/free_philos.c @@ -1,7 +1,9 @@ #include "philo.h" -int free_philos(t_rules *rules) +void free_philos(t_rules *rules) { free(rules->philos); free(rules->forks); + free(rules->print_lock); + free(rules->death_lock); } \ No newline at end of file diff --git a/philo/src/join_threads.c b/philo/src/join_threads.c new file mode 100644 index 0000000..9a2baa8 --- /dev/null +++ b/philo/src/join_threads.c @@ -0,0 +1,17 @@ +#include "philo.h" + +int join_threads(t_rules *rules) +{ + int i; + t_philo *philo; + + i = 0; + while (i < rules->n_philos) + { + philo = &rules->philos[i]; + if (pthread_join(*philo->pid, NULL)) + return (FAILURE); + i++; + } + return (SUCCESS); +} \ No newline at end of file diff --git a/philo/src/main.c b/philo/src/main.c index 5082711..7aba7cc 100644 --- a/philo/src/main.c +++ b/philo/src/main.c @@ -4,12 +4,25 @@ int main(int argc, char *argv[]) { t_rules rules; - if (FAILURE == parse_arguments(argc, argv, &rules)) + if (FAILURE == parse_arguments(argc, argv, &rules)) return (printf(ERROR_USAGE), EXIT_FAILURE); + printf("arguments parsed\n"); if (FAILURE == create_philos(&rules)) - return (printf(ERROR_MALLOC)); + return (printf(ERROR_MALLOC), EXIT_FAILURE); + printf("philos created\n"); if (FAILURE == create_mutexes(&rules)) - return (printf(ERROR_MUTEX)); + return (printf(ERROR_MUTEX), EXIT_FAILURE); + printf("mutexes created\n"); + rules.start_time = get_time(); + if (FAILURE == create_threads(&rules)) + return (printf(ERROR_THREADS), EXIT_FAILURE); + printf("threads created\n"); + if (FAILURE == join_threads(&rules)) + return (printf(ERROR_THREADS), EXIT_FAILURE); + if (FAILURE == destroy_mutexes(&rules)) + return (printf(ERROR_MUTEX), EXIT_FAILURE); + printf("mutexes destroyed\n"); + free_philos(&rules); return(EXIT_SUCCESS); } diff --git a/philo/src/parse_arguments.c b/philo/src/parse_arguments.c index 92b1604..19131d7 100644 --- a/philo/src/parse_arguments.c +++ b/philo/src/parse_arguments.c @@ -2,6 +2,8 @@ int parse_arguments(int argc,char *argv[], t_rules *rules) { + rules->n_must_eat = -1; + printf("argc: %d\n", argc); if (argc != 5 && argc != 6) return (FAILURE); if (!ph_atoi(argv[1], &rules->n_philos)) @@ -14,5 +16,13 @@ int parse_arguments(int argc,char *argv[], t_rules *rules) return (FAILURE); if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat)) return (FAILURE); + rules->print_lock = malloc(sizeof(pthread_mutex_t)); + rules->death_lock = malloc(sizeof(pthread_mutex_t)); + if (!rules->print_lock || !rules->death_lock) + return (FAILURE); + rules->forks = malloc(rules->n_philos * sizeof(pthread_mutex_t)); + if (!rules->forks) + return (FAILURE); + print_rules(rules); return (SUCCESS); } \ No newline at end of file diff --git a/philo/src/philo_routine.c b/philo/src/philo_routine.c new file mode 100644 index 0000000..79daba7 --- /dev/null +++ b/philo/src/philo_routine.c @@ -0,0 +1,36 @@ +#include "philo.h" + +void *philo_routine(void *arg) +{ + t_philo *philo; + + philo = (t_philo *)arg; + while (!philo->death && !philo->rules->death + && (philo->n_eat < philo->rules->n_must_eat || philo->rules->n_must_eat == -1)) + { + 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_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->r_fork); + print_status(philo, "is sleeping"); + usleep(philo->rules->time_to_sleep * 1000); + print_status(philo, "is thinking"); + } + return (NULL); +} \ No newline at end of file diff --git a/philo/src/print_rules.c b/philo/src/print_rules.c new file mode 100644 index 0000000..5f00b7e --- /dev/null +++ b/philo/src/print_rules.c @@ -0,0 +1,10 @@ +#include "philo.h" + +void print_rules(t_rules *rules) +{ + printf("n_philos: %d\n", rules->n_philos); + printf("time_to_die: %d\n", rules->time_to_die); + printf("time_to_eat: %d\n", rules->time_to_eat); + printf("time_to_sleep: %d\n", rules->time_to_sleep); + printf("n_must_eat: %d\n", rules->n_must_eat); +} \ No newline at end of file diff --git a/philo/src/print_status.c b/philo/src/print_status.c index 5fbd108..28140c0 100644 --- a/philo/src/print_status.c +++ b/philo/src/print_status.c @@ -1,8 +1,8 @@ #include "philo.h" -int print_status(t_philo *philo, char *status) +void print_status(t_philo *philo, char *status) { - pthread_mutex_lock(philo->rules->print); - printf("%d %d %s\n", get_time(), philo->id, status); - pthread_mutex_unlock(philo->rules->print); + pthread_mutex_lock(philo->rules->print_lock); + printf("%d %d %s\n", get_time() - philo->rules->start_time, philo->id, status); + pthread_mutex_unlock(philo->rules->print_lock); } \ No newline at end of file