Copy the philo as a base for the bonus
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 10 May 2024 06:52:38 +0000 (08:52 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 10 May 2024 06:52:38 +0000 (08:52 +0200)
It may be easier to repurpose the code for the bonus.

12 files changed:
philo_bonus/Makefile [new file with mode: 0644]
philo_bonus/helpers.c [new file with mode: 0644]
philo_bonus/inner_pars_arg.c [new file with mode: 0644]
philo_bonus/main.c [new file with mode: 0644]
philo_bonus/mem_management.c [new file with mode: 0644]
philo_bonus/mutex.c [new file with mode: 0644]
philo_bonus/pars_arg.c [new file with mode: 0644]
philo_bonus/parsing.c [new file with mode: 0644]
philo_bonus/parsing.h [new file with mode: 0644]
philo_bonus/parsing_misc.c [new file with mode: 0644]
philo_bonus/philo.c [new file with mode: 0644]
philo_bonus/philo.h [new file with mode: 0644]

diff --git a/philo_bonus/Makefile b/philo_bonus/Makefile
new file mode 100644 (file)
index 0000000..d2b2550
--- /dev/null
@@ -0,0 +1,41 @@
+CC := gcc
+
+CFLAGS := -Wall -Wextra -Werror -Wpedantic
+-std=c99
+NAME := philo
+
+INCDIR := .
+SRCDIR := .
+SRCS :=        main.c                          \
+               philo.c                         \
+               helpers.c                       \
+               parsing.c                       \
+               parsing_misc.c          \
+               pars_arg.c                      \
+               inner_pars_arg.c        \
+               mem_management.c        \
+               mutex.c                         \
+
+SRCS := $(addprefix $(SRCDIR)/, $(SRCS))
+OBJS := $(SRCS:%.c=%.o)
+CFLAGS += $(addprefix -I, $(INCDIR))
+
+all : $(NAME)
+
+debug : CFLAGS += -g
+debug : $(NAME)
+
+$(NAME) : $(OBJS)
+       $(CC) $(CFLAGS) $(OBJS) -o $@
+
+%.o : %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+clean :
+       $(RM) $(OBJS)
+
+fclean :
+       $(RM) $(OBJS) $(NAME)
+
+re : fclean
+       $(MAKE)
diff --git a/philo_bonus/helpers.c b/philo_bonus/helpers.c
new file mode 100644 (file)
index 0000000..35f974a
--- /dev/null
@@ -0,0 +1,53 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   helpers.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/05/09 09:13:40 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 11:59:36 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <sys/time.h>
+#include <stdio.h>
+
+int    end(t_settings *set)
+{
+       int     res;
+
+       mutex_lock(&set->end_lock);
+       res = set->end;
+       mutex_unlock(&set->end_lock);
+       return (res);
+}
+
+useconds_t     usecs_since_start(struct timeval start)
+{
+       struct timeval  time;
+
+       gettimeofday(&time, NULL);
+       return ((time.tv_sec - start.tv_sec) * 1000000
+               + time.tv_usec - start.tv_usec);
+}
+
+void   print_timestamp(t_philo *philo, const char *str)
+{
+       mutex_lock(&philo->settings->terminal_lock);
+       printf("%u %lu %s\n", usecs_since_start(philo->settings->start)
+               / 1000, philo->id, str);
+       mutex_unlock(&philo->settings->terminal_lock);
+       return ;
+}
+
+int    report(t_philo *philo, const char *str)
+{
+       if (!end(philo->settings))
+       {
+               print_timestamp(philo, str);
+               return (0);
+       }
+       return (1);
+}
diff --git a/philo_bonus/inner_pars_arg.c b/philo_bonus/inner_pars_arg.c
new file mode 100644 (file)
index 0000000..ac1b753
--- /dev/null
@@ -0,0 +1,31 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   inner_pars_arg.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/28 11:35:59 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/03/28 11:36:24 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "parsing.h"
+#include <stdlib.h>
+
+//     Maybe this should be changed so that it only changes
+//     res when the parse is successful?
+int    inner_parse_arg(t_big_uint *res, const char *arg)
+{
+       char    *tmp;
+
+       *res = ft_atobui(arg);
+       tmp = ft_buitoa(*res);
+       if (!same_number(tmp, arg))
+       {
+               free(tmp);
+               return (1);
+       }
+       free(tmp);
+       return (0);
+}
diff --git a/philo_bonus/main.c b/philo_bonus/main.c
new file mode 100644 (file)
index 0000000..11c1ceb
--- /dev/null
@@ -0,0 +1,131 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   main.c                                             :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/22 11:19:48 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 12:31:31 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <stddef.h>
+#include <pthread.h>
+#include <limits.h>
+#include <stdio.h>
+
+static int     seat_philosophers(t_diner *diner, pthread_t *threads)
+{
+       size_t  i;
+
+       gettimeofday(&diner->setting.start, NULL);
+       i = 0;
+       while (i < diner->setting.philo_count)
+       {
+               if (pthread_create(threads + i, NULL,
+                               be_a_philosopher, diner->philos + i))
+               {
+                       mutex_lock(&diner->setting.end_lock);
+                       diner->setting.end = 1;
+                       mutex_unlock(&diner->setting.end_lock);
+                       while (i > 0)
+                       {
+                               pthread_join(threads[--i], NULL);
+                       }
+                       return (1);
+               }
+               ++i;
+       }
+       return (0);
+}
+
+static int     is_dead(t_philo *philo)
+{
+       mutex_lock(&philo->philo_lock);
+       if (usecs_since_start(philo->settings->start) - philo->last_eaten
+               > philo->settings->time_to_die)
+       {
+               mutex_unlock(&philo->philo_lock);
+               return (1);
+       }
+       mutex_unlock(&philo->philo_lock);
+       return (0);
+}
+
+static int     all_full(t_diner *diner)
+{
+       size_t                  i;
+       unsigned int    min_eaten;
+
+       if (!diner->setting.should_check_hunger)
+               return (0);
+       i = 0;
+       min_eaten = UINT_MAX;
+       while (i < diner->setting.philo_count)
+       {
+               mutex_lock(&diner->philos[i].philo_lock);
+               if (min_eaten > diner->philos[i].num_eaten)
+                       min_eaten = diner->philos[i].num_eaten;
+               mutex_unlock(&diner->philos[i].philo_lock);
+               ++i;
+       }
+       return (min_eaten >= diner->setting.min_eat_num);
+}
+
+static enum e_end      watch_philosophers(t_diner *diner)
+{
+       size_t  i;
+
+       while (1)
+       {
+               i = 0;
+               while (i < diner->setting.philo_count)
+               {
+                       if (is_dead(diner->philos + i))
+                       {
+                               mutex_lock(&diner->setting.end_lock);
+                               diner->setting.end = 1;
+                               mutex_unlock(&diner->setting.end_lock);
+                               print_timestamp(diner->philos + i, "died");
+                               return (death);
+                       }
+                       ++i;
+               }
+               if (all_full(diner))
+               {
+                       mutex_lock(&diner->setting.end_lock);
+                       diner->setting.end = 1;
+                       mutex_unlock(&diner->setting.end_lock);
+                       return (well_fed);
+               }
+       }
+}
+
+int    main(int argc, char **argv)
+{
+       t_diner         diner;
+       pthread_t       *threads;
+       enum e_end      res;
+
+       if (parse_input(&diner.setting, argc, argv))
+       {
+               return (1);
+       }
+       if (init(&diner, &threads))
+       {
+               cleanup(&diner, threads);
+               return (2);
+       }
+       if (seat_philosophers(&diner, threads))
+       {
+               cleanup(&diner, threads);
+               return (3);
+       }
+       res = watch_philosophers(&diner);
+       cleanup(&diner, threads);
+       if (res == well_fed)
+               printf("All philosophers are well fed.\n");
+       return (0);
+}
diff --git a/philo_bonus/mem_management.c b/philo_bonus/mem_management.c
new file mode 100644 (file)
index 0000000..c459048
--- /dev/null
@@ -0,0 +1,73 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   mem_management.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/28 09:39:55 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 12:41:33 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <pthread.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+//     Shortcircuiting does no harm here as when any mutex_init fails
+//     the program will end anyway.
+int    init(t_diner *diner, pthread_t **threads)
+{
+       const size_t    count = diner->setting.philo_count;
+       size_t                  i;
+
+       init_mutex(&diner->setting.terminal_lock, NULL);
+       init_mutex(&diner->setting.end_lock, NULL);
+       diner->philos = malloc(sizeof(*diner->philos) * count);
+       diner->forks = malloc(sizeof(*diner->forks) * count);
+       *threads = malloc(sizeof(**threads) * count);
+       if (!diner->philos || !diner->forks || !*threads)
+               return (1);
+       i = 0;
+       while (i < count)
+       {
+               init_mutex(diner->forks + i, NULL);
+               init_mutex(&diner->philos[i].philo_lock, NULL);
+               diner->philos[i].forks[i % 2] = diner->forks + i;
+               diner->philos[i].forks[(i + 1) % 2] = diner->forks
+                       + (i + 1) % count;
+               diner->philos[i].settings = &diner->setting;
+               diner->philos[i].last_eaten = 0;
+               diner->philos[i].id = i + 1;
+               diner->philos[i].num_eaten = 0;
+               ++i;
+       }
+       return (!all_mutexes_initialized(diner));
+}
+
+void   cleanup(t_diner *diner, pthread_t *threads)
+{
+       const size_t    count = diner->setting.philo_count;
+       size_t                  i;
+
+       i = 0;
+       if (diner->philos)
+       {
+               while (i < count)
+               {
+                       pthread_join(threads[i], NULL);
+                       destroy_mutex(&diner->philos[i++].philo_lock);
+               }
+       }
+       i = 0;
+       if (diner->forks)
+               while (i < count)
+                       destroy_mutex(diner->forks + (i++));
+       destroy_mutex(&diner->setting.terminal_lock);
+       destroy_mutex(&diner->setting.end_lock);
+       free(diner->philos);
+       free(diner->forks);
+       free(threads);
+       return ;
+}
diff --git a/philo_bonus/mutex.c b/philo_bonus/mutex.c
new file mode 100644 (file)
index 0000000..6073e71
--- /dev/null
@@ -0,0 +1,59 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   mutex.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/28 10:35:16 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/03/28 15:12:37 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <pthread.h>
+
+int    init_mutex(t_mutex *mutex, pthread_mutexattr_t *attr)
+{
+       mutex->is_init = !(pthread_mutex_init(&mutex->mutex, attr));
+       return (mutex->is_init);
+}
+
+void   destroy_mutex(t_mutex *mutex)
+{
+       if (mutex->is_init)
+               pthread_mutex_destroy(&mutex->mutex);
+       mutex->is_init = 0;
+}
+
+int    mutex_lock(t_mutex *mutex)
+{
+       if (!mutex->is_init)
+               return (1);
+       return (pthread_mutex_lock(&mutex->mutex));
+}
+
+int    mutex_unlock(t_mutex *mutex)
+{
+       if (!mutex->is_init)
+               return (1);
+       return (pthread_mutex_unlock(&mutex->mutex));
+}
+
+int    all_mutexes_initialized(t_diner *diner)
+{
+       int             res;
+       size_t  i;
+
+       res = 1;
+       res = res && diner->setting.terminal_lock.is_init;
+       res = res && diner->setting.end_lock.is_init;
+       i = 0;
+       while (i < diner->setting.philo_count)
+       {
+               res = res && diner->forks[i].is_init;
+               res = res && diner->philos[i].philo_lock.is_init;
+               ++i;
+       }
+       return (res);
+}
diff --git a/philo_bonus/pars_arg.c b/philo_bonus/pars_arg.c
new file mode 100644 (file)
index 0000000..c9b7986
--- /dev/null
@@ -0,0 +1,84 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   pars_arg.c                                         :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/28 11:29:47 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 10:38:14 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "parsing.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+int    parse_arg_usec(useconds_t *res, const char *arg)
+{
+       t_big_uint      tmp;
+
+       if (inner_parse_arg(&tmp, arg))
+               return (1);
+       tmp *= 1000;
+       if (tmp > (useconds_t)-1)
+               return (1);
+       *res = (useconds_t)tmp;
+       return (0);
+}
+
+#if SIZE_MAX > UINT_MAX
+
+int    parse_arg_size(size_t *res, const char *arg)
+{
+       t_big_uint      tmp;
+
+       if (inner_parse_arg(&tmp, arg))
+               return (1);
+       if (tmp > (size_t)-1)
+               return (1);
+       *res = (size_t)tmp;
+       return (0);
+}
+
+#else
+
+int    parse_arg_size(size_t *res, const char *arg)
+{
+       t_big_uint      tmp;
+
+       if (inner_parse_arg(&tmp, arg))
+               return (1);
+       *res = (size_t)tmp;
+       return (0);
+}
+
+#endif //SIZE_MAX > UINT_MAX
+
+#if UINT_MAX > SIZE_MAX
+
+int    parse_arg_uint(unsigned int *res, const char *arg)
+{
+       t_big_uint      tmp;
+
+       if (inner_parse_arg(&tmp, arg))
+               return (1);
+       if (tmp > (unsigned int)-1)
+               return (1);
+       *res = (unsigned int)tmp;
+       return (0);
+}
+
+#else
+
+int    parse_arg_uint(unsigned int *res, const char *arg)
+{
+       t_big_uint      tmp;
+
+       if (inner_parse_arg(&tmp, arg))
+               return (1);
+       *res = (unsigned int)tmp;
+       return (0);
+}
+
+#endif //UINT_MAX > SIZE_MAX
diff --git a/philo_bonus/parsing.c b/philo_bonus/parsing.c
new file mode 100644 (file)
index 0000000..ec9a39f
--- /dev/null
@@ -0,0 +1,43 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parsing.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/26 09:31:35 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 12:35:58 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "parsing.h"
+#include "philo.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+int    is_sane(t_settings *settings)
+{
+       return (settings->philo_count > 0);
+}
+
+int    parse_input(t_settings *settings, int argc, char **argv)
+{
+       if (argc != 5 && argc != 6)
+               return (1);
+       settings->end = 0;
+       settings->should_check_hunger = 0;
+       if (parse_arg_size(&settings->philo_count, argv[1])
+               || parse_arg_usec(&settings->time_to_die, argv[2])
+               || parse_arg_usec(&settings->time_to_eat, argv[3])
+               || parse_arg_usec(&settings->time_to_sleep, argv[4]))
+       {
+               return (1);
+       }
+       if (argc == 6)
+       {
+               if (parse_arg_uint(&settings->min_eat_num, argv[5]))
+                       return (1);
+               settings->should_check_hunger = 1;
+       }
+       return (!is_sane(settings));
+}
diff --git a/philo_bonus/parsing.h b/philo_bonus/parsing.h
new file mode 100644 (file)
index 0000000..727331e
--- /dev/null
@@ -0,0 +1,45 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parsing.h                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/28 11:24:41 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/03/28 11:40:04 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef PARSING_H
+# define PARSING_H
+
+# include <limits.h>
+# include <stddef.h>
+# include <unistd.h>
+
+//     This done to make parsing easier/non-repetitive
+//     but it cannot be a part of parsing.c as more files depend on it
+//     
+//     This assumes useconds_t is not the biggest type
+//     The assumption is made because it is not easy to check
+# if SIZE_MAX > UINT_MAX
+
+typedef size_t                 t_big_uint;
+
+# else
+
+typedef unsigned int   t_big_uint;
+
+# endif //SIZE_MAX > UINT_MAX
+
+t_big_uint     ft_atobui(const char *str);
+char           *ft_buitoa(t_big_uint num);
+int                    same_number(const char *num1, const char *num2);
+
+int                    inner_parse_arg(t_big_uint *res, const char *arg);
+
+int                    parse_arg_usec(useconds_t *res, const char *arg);
+int                    parse_arg_size(size_t *res, const char *arg);
+int                    parse_arg_uint(unsigned int *res, const char *arg);
+
+#endif //PARSING_H
diff --git a/philo_bonus/parsing_misc.c b/philo_bonus/parsing_misc.c
new file mode 100644 (file)
index 0000000..747648a
--- /dev/null
@@ -0,0 +1,75 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parsing_misc.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/26 10:42:02 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/03/28 11:53:49 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "parsing.h"
+#include <stdlib.h>
+
+t_big_uint     ft_atobui(const char *str)
+{
+       t_big_uint      res;
+
+       res = 0;
+       if (!str)
+               return (res);
+       while (*str == ' ' || *str == '+')
+               ++str;
+       while ('0' <= *str && *str <= '9')
+       {
+               res *= 10;
+               res += *str - '0';
+               ++str;
+       }
+       return (res);
+}
+
+char   *ft_buitoa(t_big_uint num)
+{
+       char            *res;
+       size_t          size;
+       t_big_uint      tmp;
+
+       tmp = num;
+       size = 0;
+       while (tmp > 0)
+       {
+               ++size;
+               tmp /= 10;
+       }
+       if (size == 0)
+               size = 1;
+       res = malloc(size + 1);
+       if (!res)
+               return (NULL);
+       res[size--] = '\0';
+       if (num == 0)
+               res[0] = '0';
+       while (num > 0)
+       {
+               res[size--] = '0' + num % 10;
+               num /= 10;
+       }
+       return (res);
+}
+
+int    same_number(const char *num1, const char *num2)
+{
+       while (*num1 == ' ' || *num1 == '+' || *num1 == '0')
+               ++num1;
+       while (*num2 == ' ' || *num2 == '+' || *num2 == '0')
+               ++num2;
+       while (*num1 && *num2 && *num1 == *num2)
+       {
+               ++num1;
+               ++num2;
+       }
+       return (!((int)*num1 - (int)*num2));
+}
diff --git a/philo_bonus/philo.c b/philo_bonus/philo.c
new file mode 100644 (file)
index 0000000..6dfa0fb
--- /dev/null
@@ -0,0 +1,61 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   philo.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/05/09 08:45:21 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 10:25:46 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <unistd.h>
+
+static void    philo_think(t_philo *philo)
+{
+       report(philo, "is thinking");
+       return ;
+}
+
+static void    philo_eat(t_philo *philo)
+{
+       mutex_lock(philo->forks[0]);
+       if (report(philo, "has taken a fork"))
+       {
+               mutex_unlock(philo->forks[0]);
+               return ;
+       }
+       mutex_lock(philo->forks[1]);
+       report(philo, "has taken a fork");
+       mutex_lock(&philo->philo_lock);
+       philo->last_eaten = usecs_since_start(philo->settings->start);
+       ++philo->num_eaten;
+       mutex_unlock(&philo->philo_lock);
+       if (!report(philo, "is eating"))
+               usleep(philo->settings->time_to_eat);
+       mutex_unlock(philo->forks[0]);
+       mutex_unlock(philo->forks[1]);
+       return ;
+}
+
+static void    philo_sleep(t_philo *philo)
+{
+       if (!report(philo, "is sleeping"))
+               usleep(philo->settings->time_to_sleep);
+       return ;
+}
+
+void   *be_a_philosopher(void *void_philo)
+{
+       t_philo *const  philo = void_philo;
+
+       while (!end(philo->settings))
+       {
+               philo_think(philo);
+               philo_eat(philo);
+               philo_sleep(philo);
+       }
+       return (NULL);
+}
diff --git a/philo_bonus/philo.h b/philo_bonus/philo.h
new file mode 100644 (file)
index 0000000..ad3ffc9
--- /dev/null
@@ -0,0 +1,85 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   philo.h                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/22 11:10:17 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/09 12:21:57 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef PHILO_H
+# define PHILO_H
+
+# include <stddef.h>
+# include <pthread.h>
+# include <sys/time.h>
+# include <unistd.h>
+
+typedef struct s_mutex
+{
+       int                             is_init;
+       pthread_mutex_t mutex;
+}                                      t_mutex;
+
+//     The .start member holds the result of gettimeofday
+//     Every other member that holds time info counts
+//     microseconds from that point (in other structures also)
+typedef struct s_settings
+{
+       int                             end;
+       int                             should_check_hunger;
+       unsigned int    min_eat_num;
+       useconds_t              time_to_die;
+       useconds_t              time_to_eat;
+       useconds_t              time_to_sleep;
+       size_t                  philo_count;
+       struct timeval  start;
+       t_mutex                 terminal_lock;
+       t_mutex                 end_lock;
+}                                      t_settings;
+
+typedef struct s_philosopher
+{
+       unsigned int    num_eaten;
+       size_t                  id;
+       useconds_t              last_eaten;
+       t_settings              *settings;
+       t_mutex                 *forks[2];
+       t_mutex                 philo_lock;
+}                                      t_philo;
+
+typedef struct s_diner
+{
+       t_settings      setting;
+       t_philo         *philos;
+       t_mutex         *forks;
+}                              t_diner;
+
+enum e_end
+{
+       death,
+       well_fed,
+};
+
+int                    parse_input(t_settings *settings, int argc, char **argv);
+
+int                    init(t_diner *diner, pthread_t **threads);
+void           cleanup(t_diner *diner, pthread_t *threads);
+
+int                    init_mutex(t_mutex *mutex, pthread_mutexattr_t *attr);
+void           destroy_mutex(t_mutex *mutex);
+int                    mutex_lock(t_mutex *mutex);
+int                    mutex_unlock(t_mutex *mutex);
+int                    all_mutexes_initialized(t_diner *diner);
+
+int                    end(t_settings *set);
+useconds_t     usecs_since_start(struct timeval start);
+int                    report(t_philo *philo, const char *str);
+void           print_timestamp(t_philo *philo, const char *str);
+
+void           *be_a_philosopher(void *philo);
+
+#endif //PHILO_H