INCDIR := .
SRCDIR := .
-SRCS := main.c \
- parsing.c \
- parsing_misc.c \
+SRCS := main.c \
+ parsing.c \
+ parsing_misc.c \
+ mem_management.c \
+ mutex.c \
SRCS := $(addprefix $(SRCDIR)/, $(SRCS))
OBJS := $(SRCS:%.c=%.o)
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/22 11:19:48 by ljiriste #+# #+# */
-/* Updated: 2024/03/28 09:38:05 by ljiriste ### ########.fr */
+/* Updated: 2024/03/28 10:00:52 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
{
return (1);
}
- if (init(&diner, threads))
+ if (init(&diner, &threads))
{
cleanup(&diner, threads);
return (2);
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* mem_management.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/03/28 09:39:55 by ljiriste #+# #+# */
+/* Updated: 2024/03/28 10:49:03 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;
+
+ 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);
+ init_mutex(&diner->setting.terminal_lock, NULL);
+ init_mutex(&diner->setting.end_lock, NULL);
+ 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;
+ ++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;
+
+ destroy_mutex(&diner->setting.terminal_lock);
+ destroy_mutex(&diner->setting.end_lock);
+ i = 0;
+ if (diner->forks)
+ while (i < count)
+ destroy_mutex(diner->forks + (i++));
+ i = 0;
+ if (diner->philos)
+ while (i < count)
+ destroy_mutex(&diner->philos[i++].philo_lock);
+ free(diner->philos);
+ free(diner->forks);
+ free(threads);
+ return ;
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* mutex.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/03/28 10:35:16 by ljiriste #+# #+# */
+/* Updated: 2024/03/28 10:49:35 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 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);
+}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/22 11:10:17 by ljiriste #+# #+# */
-/* Updated: 2024/03/28 09:32:08 by ljiriste ### ########.fr */
+/* Updated: 2024/03/28 10:50:26 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
typedef unsigned int t_big_uint;
# endif //SIZE_MAX > UINT_MAX
+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)
useconds_t time_to_sleep;
size_t philo_count;
struct timeval start;
- pthread_mutex_t terminal_lock;
- pthread_mutex_t end_lock;
+ t_mutex terminal_lock;
+ t_mutex end_lock;
} t_settings;
typedef struct s_philosopher
{
- int num_eaten;
- size_t id;
- useconds_t last_eaten;
- t_settings *settings;
- pthread_mutex_t *forks[2];
- pthread_mutex_t philo_lock;
+ 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;
- pthread_mutex_t *forks;
-} t_diner;
+ t_settings setting;
+ t_philo *philos;
+ t_mutex *forks;
+} t_diner;
int parse_input(t_settings *settings, int argc, char **argv);
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 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 all_mutexes_initialized(t_diner *diner);
+
+int seat_philosophers(t_diner *diner, pthread_t *threads);
+void wait_till_death_possible(useconds_t time_to_die,
+ struct timeval start);
+void report_end(int end);
+int watch_philosophers(t_diner *diner);
+
#endif //PHILO_H