diff --git a/philo/Makefile b/philo/Makefile index ed7e1db..e772ede 100644 --- a/philo/Makefile +++ b/philo/Makefile @@ -10,14 +10,14 @@ # # # **************************************************************************** # -NAME = fdf +NAME = philo SRC_PATH = src INC_PATH = inc OBJ_PATH = obj -VPATH = src +VPATH = src:src/utils SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c")) OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o)) diff --git a/philo/inc/philo.h b/philo/inc/philo.h index 3d722c7..8668f6c 100644 --- a/philo/inc/philo.h +++ b/philo/inc/philo.h @@ -4,31 +4,51 @@ # include # include # include +# include +# include +# include + + +# define SUCCESS 1 +# define FAILURE 0 + +# 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" +# define ERROR_MUTEX "Can not create mutex" +# define ERROR_MALLOC "Malloc Failure" typedef struct s_rules { - int time_to_die; - int time_to_eat; - int time_to_sleep; - int nb_must_eat; + int n_philos; + int time_to_die; + int time_to_eat; + int time_to_sleep; + int n_must_eat; pthread_mutex_t *print; pthread_mutex_t *death; + pthread_mutex_t *forks; + t_philo *philos; } t_rules; typedef struct s_philo { + int id; pthread_t *pid; pthread_mutex_t *l_fork; pthread_mutex_t *r_fork; + int death; int last_meal; - t_rules rules; + t_rules *rules; } t_philo; + // memset, printf, malloc, free, write, // usleep, gettimeofday, pthread_create, // pthread_detach, pthread_join, pthread_mutex_init, // pthread_mutex_destroy, pthread_mutex_lock, // pthread_mutex_unlock +int ph_atoi(const char *nptr, int *res); + #endif \ No newline at end of file diff --git a/philo/philo b/philo/philo new file mode 100755 index 0000000..7c22300 Binary files /dev/null and b/philo/philo differ diff --git a/philo/src/create_mutexes.c b/philo/src/create_mutexes.c new file mode 100644 index 0000000..903aee9 --- /dev/null +++ b/philo/src/create_mutexes.c @@ -0,0 +1,18 @@ +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); + 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)) + return(FAILURE); + } +} \ No newline at end of file diff --git a/philo/src/create_philos.c b/philo/src/create_philos.c new file mode 100644 index 0000000..5cace20 --- /dev/null +++ b/philo/src/create_philos.c @@ -0,0 +1,21 @@ +int create_philos(t_rules *rules) +{ + int i; + t_philo *philo; + + i = 0; + rules->philos = malloc(rules->n_philos * sizeof(t_philo)); + if (!rules->philos) + return(FAILURE); + while (i < rules->n_philos) + { + philo = &rules->philos[i]; + philo->id = i + 1; + philo->l_fork = &rules->forks[i]; + philo->r_fork = &rules->forks[i + 1 % rules->n_philos]; + philo->death = 0; + philo->pid = 0; + philo->rules = rules; + i++; + } +} \ No newline at end of file diff --git a/philo/src/destroy_mutexes.c b/philo/src/destroy_mutexes.c new file mode 100644 index 0000000..0189274 --- /dev/null +++ b/philo/src/destroy_mutexes.c @@ -0,0 +1,15 @@ +int destroy_mutexes(t_rules *rules) +{ + int i; + + i = 0; + if (!pthread_mutex_destroy(&rules->death)) + return(FAILURE); + if (!pthread_mutex_destroy(&rules->print)) + return(FAILURE); + while (i < rules->n_philos) + { + if (!pthread_mutex_destroy(&rules->forks[i])) + return(FAILURE); + } +} \ No newline at end of file diff --git a/philo/src/free_philos.c b/philo/src/free_philos.c new file mode 100644 index 0000000..e348d9e --- /dev/null +++ b/philo/src/free_philos.c @@ -0,0 +1,5 @@ +int free_philos(t_rules *rules) +{ + free(rules->philos); + free(rules->forks); +} \ No newline at end of file diff --git a/philo/src/get_time.c b/philo/src/get_time.c new file mode 100644 index 0000000..1360063 --- /dev/null +++ b/philo/src/get_time.c @@ -0,0 +1,7 @@ +int get_time(void) +{ + struct timeval time; + + gettimeofday(&time, NULL); + return (time.tv_sec * 1000 + time.tv_usec / 1000); +} \ No newline at end of file diff --git a/philo/src/main.c b/philo/src/main.c index f03b93a..5082711 100644 --- a/philo/src/main.c +++ b/philo/src/main.c @@ -2,6 +2,14 @@ int main(int argc, char *argv[]) { - + t_rules rules; + + if (FAILURE == parse_arguments(argc, argv, &rules)) + return (printf(ERROR_USAGE), EXIT_FAILURE); + if (FAILURE == create_philos(&rules)) + return (printf(ERROR_MALLOC)); + if (FAILURE == create_mutexes(&rules)) + return (printf(ERROR_MUTEX)); + return(EXIT_SUCCESS); } diff --git a/philo/src/parse_arguments.c b/philo/src/parse_arguments.c new file mode 100644 index 0000000..d2f74d9 --- /dev/null +++ b/philo/src/parse_arguments.c @@ -0,0 +1,16 @@ +int parse_arguments(int argc,char *argv[], t_rules *rules) +{ + if (argc != 5 && argc != 6) + return (FAILURE); + if (!ph_atoi(argv[1], &rules->n_philos)) + return (FAILURE); + if (!ph_atoi(argv[2], &rules->time_to_die)) + return (FAILURE); + if (!ph_atoi(argv[3], &rules->time_to_eat)) + return (FAILURE); + if (!ph_atoi(argv[4], &rules->time_to_sleep)) + return (FAILURE); + if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat)) + return (FAILURE); + return (SUCCESS); +} \ No newline at end of file diff --git a/philo/src/print_status.c b/philo/src/print_status.c new file mode 100644 index 0000000..49feafa --- /dev/null +++ b/philo/src/print_status.c @@ -0,0 +1,6 @@ +int 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); +} \ No newline at end of file diff --git a/philo/src/utils/ph_atoi.c b/philo/src/utils/ph_atoi.c new file mode 100644 index 0000000..e47396c --- /dev/null +++ b/philo/src/utils/ph_atoi.c @@ -0,0 +1,25 @@ +#include "philo.h" + +static int ph_isspace(int c) +{ + return (' ' == c || '\f' == c || \ + '\n' == c || '\r' == c || \ + '\t' == c || '\v' == c); +} + +static int ph_isdigit(int c) +{ + return ('0' <= c && '9' >= c); +} + +int ph_atoi(const char *nptr, int *res) +{ + while (ph_isspace(*nptr)) + nptr++; + *res = 0; + while (ph_isdigit(*nptr)) + *res = 10 * *res + (*nptr++ - '0'); + if (*nptr != '\0') + return (FAILURE); + return (SUCCESS); +}