+++ /dev/null
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* 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);
-}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/22 11:10:17 by ljiriste #+# #+# */
-/* Updated: 2024/05/09 12:21:57 by ljiriste ### ########.fr */
+/* Updated: 2024/05/10 09:34:17 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
# 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;
+// As mutex is not available in bonus, the idea is to have
+// a semaphore with value 1 to for the access to terminal.
+// The well_fed_sem(aphore) and death_sem(aphore) will be taken
+// by the child processes immediately after their start.
+// 2 threads of the main process will then be waiting for those
+// semaphores. The death_sem only needs be unlocked once to signal the end.
+// The well_fed_sem needs to be unlock by every philosopher (process)
+// for the thread to singal the end.
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;
+ sem_t *forks;
+ sem_t *well_fed_sem;
+ sem_t *death_sem;
+ sem_t *terminal_sem;
+ t_settings settings;
} t_philo;
-typedef struct s_diner
-{
- t_settings setting;
- t_philo *philos;
- t_mutex *forks;
-} t_diner;
-
enum e_end
{
death,
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);