-
Notifications
You must be signed in to change notification settings - Fork 0
/
ft_main.c
116 lines (105 loc) · 3.6 KB
/
ft_main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: ysoroko <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/08/16 11:04:33 by ysoroko #+# #+# */
/* Updated: 2021/10/21 11:00:06 by ysoroko ### ########.fr */
/* */
/* ************************************************************************** */
#include "philosophers.h"
/// Initializes the "display" mutex
/// Returns the mutex or a NULL pointer in case of an error
void *ft_initialize_display_mutex(void)
{
pthread_mutex_t *displaying;
if (!ft_malloc(sizeof(pthread_mutex_t), (void **)&displaying))
return (NULL);
if (pthread_mutex_init(displaying, NULL))
return (ft_free(displaying, "Failed to init a display mutex", NULL));
return (displaying);
}
/// Initializes the t_philo structure, and the mutexes
/// Returns 0 in case of success or -1 if an error
static int ft_init(t_philo **ph, t_main_args *args, int i, pthread_mutex_t *d)
{
ph[2] = ft_initialize_philo(args, i + 1, &(ph[0]));
if (!ph[2])
return (ft_puterr("Failed to initialize a t_philo"));
if (ft_initialize_forks_mutex(ph[2], args->n_philos, ph[1], ph[0]))
return (-1);
ph[2]->displaying = d;
return (0);
}
void *ft_ph(t_philo **ph, t_main_args *arg, pthread_t *r, t_philo **p)
{
int i;
i = -1;
while (++i < arg->n_philos)
{
if (ft_init(ph, arg, i, arg->displaying))
return (ft_free(r, NULL, NULL));
(ph[2]->died = arg->dead);
if (pthread_create(&(r[i]), NULL, &ft_thread_function, ph[2]))
return (ft_free(r, "Failed to create a thread", NULL));
ph[1] = ph[2];
p[i] = ph[2];
}
*(p[0])->died = 0;
return (p);
}
/// Initialize an array of threads of n_philos elements with malloc
/// Creates a thread for every philosopher and joins the threads
/// Returns a NULL pointer in case of an error
static pthread_t *ft_initialize_threads(t_main_args *arg, t_philo **p)
{
pthread_t *ret;
pthread_t *death;
t_philo *ph[3];
int i;
if (!ft_malloc(sizeof(*ret) * arg->n_philos, (void **)&ret))
return (ft_puterr_ptr("Failed to malloc the philosophers"));
i = arg->n_philos;
ph[0] = NULL;
if (!ft_ph(ph, arg, ret, p))
return (NULL);
death = ft_initialize_death_check_thread(p, arg->n_philos, arg->t_to_die);
if (!death)
return (NULL);
while (--i >= 0)
if (pthread_detach(ret[i]))
return (ft_free(ret, "Failed to detach a thread", NULL));
if (pthread_join(*death, NULL))
return (NULL);
return (ret);
}
/*
** 1 - number of philosophers
** 2 - time to die
** 3 - time to eat
** 4 - time to sleep
** (optionnal) 5 - number of times they need to eat
*/
int main(int argc, char **argv)
{
t_main_args *main_args;
pthread_t *threads;
t_philo **philos;
if (ft_main_args_error(argc, argv))
return (-1);
philos = malloc(sizeof(t_philo *) * ft_atol(argv[1]));
if (!philos)
return (ft_puterr("Failed to malloc the philosophers array"));
main_args = ft_initialize_main_args_struct(argc, argv);
if (!main_args)
return (ft_free_int_ret(philos, NULL, -1));
threads = ft_initialize_threads(main_args, philos);
if (!threads)
return (-1);
free(main_args);
free(threads);
free(philos);
return (0);
}