first working simulation and breakup of code
This commit is contained in:
parent
40036d5d71
commit
c0b9c33cfa
0
.vscode/tasks.json
vendored
Normal file
0
.vscode/tasks.json
vendored
Normal file
@ -16,6 +16,7 @@
|
|||||||
"time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]\n"
|
"time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]\n"
|
||||||
# define ERROR_MUTEX "Can not create mutex"
|
# define ERROR_MUTEX "Can not create mutex"
|
||||||
# define ERROR_MALLOC "Malloc Failure"
|
# define ERROR_MALLOC "Malloc Failure"
|
||||||
|
# define ERROR_THREADS "Can not create threads"
|
||||||
|
|
||||||
typedef struct s_rules
|
typedef struct s_rules
|
||||||
{
|
{
|
||||||
@ -24,10 +25,12 @@ typedef struct s_rules
|
|||||||
int time_to_eat;
|
int time_to_eat;
|
||||||
int time_to_sleep;
|
int time_to_sleep;
|
||||||
int n_must_eat;
|
int n_must_eat;
|
||||||
pthread_mutex_t *print;
|
int death;
|
||||||
pthread_mutex_t *death;
|
int start_time;
|
||||||
|
pthread_mutex_t *print_lock;
|
||||||
|
pthread_mutex_t *death_lock;
|
||||||
pthread_mutex_t *forks;
|
pthread_mutex_t *forks;
|
||||||
t_philo *philos;
|
struct s_philo *philos;
|
||||||
|
|
||||||
} t_rules;
|
} t_rules;
|
||||||
|
|
||||||
@ -40,6 +43,7 @@ typedef struct s_philo
|
|||||||
int death;
|
int death;
|
||||||
int last_meal;
|
int last_meal;
|
||||||
t_rules *rules;
|
t_rules *rules;
|
||||||
|
int n_eat;
|
||||||
} t_philo;
|
} t_philo;
|
||||||
|
|
||||||
// memset, printf, malloc, free, write,
|
// memset, printf, malloc, free, write,
|
||||||
@ -49,6 +53,19 @@ typedef struct s_philo
|
|||||||
// pthread_mutex_unlock
|
// pthread_mutex_unlock
|
||||||
|
|
||||||
int ph_atoi(const char *nptr, int *res);
|
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
|
#endif
|
||||||
BIN
philo/philo
BIN
philo/philo
Binary file not shown.
17
philo/src/check_alive.c
Normal file
17
philo/src/check_alive.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -5,16 +5,20 @@ int create_mutexes(t_rules *rules)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (!pthread_mutex_init(&rules->death, NULL))
|
printf("creating mutexes\n");
|
||||||
return(FAILURE);
|
if (pthread_mutex_init(rules->death_lock, NULL))
|
||||||
if (!pthread_mutex_init(&rules->print, NULL))
|
return(printf("death mutex created"), FAILURE);
|
||||||
return(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));
|
rules->forks = malloc(rules->n_philos * sizeof(pthread_mutex_t));
|
||||||
if (!rules->forks)
|
if (!rules->forks)
|
||||||
return(FAILURE);
|
return(FAILURE);
|
||||||
while (i < rules->n_philos)
|
while (i < rules->n_philos)
|
||||||
{
|
{
|
||||||
if (!pthread_mutex_init(&rules->forks[i], NULL))
|
if (pthread_mutex_init(&rules->forks[i], NULL))
|
||||||
return(FAILURE);
|
return(FAILURE);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
@ -18,6 +18,8 @@ int create_philos(t_rules *rules)
|
|||||||
philo->death = 0;
|
philo->death = 0;
|
||||||
philo->pid = 0;
|
philo->pid = 0;
|
||||||
philo->rules = rules;
|
philo->rules = rules;
|
||||||
|
philo->last_meal = get_time();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
20
philo/src/create_threads.c
Normal file
20
philo/src/create_threads.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -5,13 +5,15 @@ int destroy_mutexes(t_rules *rules)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (!pthread_mutex_destroy(&rules->death))
|
if (pthread_mutex_destroy(rules->death_lock))
|
||||||
return(FAILURE);
|
return(FAILURE);
|
||||||
if (!pthread_mutex_destroy(&rules->print))
|
if (pthread_mutex_destroy(rules->print_lock))
|
||||||
return(FAILURE);
|
return(FAILURE);
|
||||||
while (i < rules->n_philos)
|
while (i < rules->n_philos)
|
||||||
{
|
{
|
||||||
if (!pthread_mutex_destroy(&rules->forks[i]))
|
if (pthread_mutex_destroy(&rules->forks[i]))
|
||||||
return(FAILURE);
|
return(FAILURE);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
#include "philo.h"
|
#include "philo.h"
|
||||||
|
|
||||||
int free_philos(t_rules *rules)
|
void free_philos(t_rules *rules)
|
||||||
{
|
{
|
||||||
free(rules->philos);
|
free(rules->philos);
|
||||||
free(rules->forks);
|
free(rules->forks);
|
||||||
|
free(rules->print_lock);
|
||||||
|
free(rules->death_lock);
|
||||||
}
|
}
|
||||||
17
philo/src/join_threads.c
Normal file
17
philo/src/join_threads.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -4,12 +4,25 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
t_rules rules;
|
t_rules rules;
|
||||||
|
|
||||||
if (FAILURE == parse_arguments(argc, argv, &rules))
|
if (FAILURE == parse_arguments(argc, argv, &rules))
|
||||||
return (printf(ERROR_USAGE), EXIT_FAILURE);
|
return (printf(ERROR_USAGE), EXIT_FAILURE);
|
||||||
|
printf("arguments parsed\n");
|
||||||
if (FAILURE == create_philos(&rules))
|
if (FAILURE == create_philos(&rules))
|
||||||
return (printf(ERROR_MALLOC));
|
return (printf(ERROR_MALLOC), EXIT_FAILURE);
|
||||||
|
printf("philos created\n");
|
||||||
if (FAILURE == create_mutexes(&rules))
|
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);
|
return(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
int parse_arguments(int argc,char *argv[], t_rules *rules)
|
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)
|
if (argc != 5 && argc != 6)
|
||||||
return (FAILURE);
|
return (FAILURE);
|
||||||
if (!ph_atoi(argv[1], &rules->n_philos))
|
if (!ph_atoi(argv[1], &rules->n_philos))
|
||||||
@ -14,5 +16,13 @@ int parse_arguments(int argc,char *argv[], t_rules *rules)
|
|||||||
return (FAILURE);
|
return (FAILURE);
|
||||||
if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat))
|
if (argc == 6 && !ph_atoi(argv[5], &rules->n_must_eat))
|
||||||
return (FAILURE);
|
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);
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
36
philo/src/philo_routine.c
Normal file
36
philo/src/philo_routine.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
10
philo/src/print_rules.c
Normal file
10
philo/src/print_rules.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
#include "philo.h"
|
#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);
|
pthread_mutex_lock(philo->rules->print_lock);
|
||||||
printf("%d %d %s\n", get_time(), philo->id, status);
|
printf("%d %d %s\n", get_time() - philo->rules->start_time, philo->id, status);
|
||||||
pthread_mutex_unlock(philo->rules->print);
|
pthread_mutex_unlock(philo->rules->print_lock);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user