narnaud
3 years ago
10 changed files with 651 additions and 1 deletions
@ -1,3 +1,30 @@ |
|||
# Philosophers |
|||
|
|||
42 school project |
|||
|
|||
|
|||
|
|||
PHILOSOPHERS BONUS |
|||
=== |
|||
|
|||
## Subject : |
|||
<https://cdn.intra.42.fr/pdf/pdf/48443/fr.subject.pdf> |
|||
|
|||
## Docs : |
|||
[Semaphores](https://sites.uclouvain.be/SyllabusC/notes/Theorie/Threads/coordination.html) |
|||
|
|||
|
|||
## Structure : |
|||
|
|||
Main : |
|||
|
|||
- parsing() -> |
|||
- create table and *philos |
|||
- setup parameters |
|||
- create sticks semaphore |
|||
- init_philos() -> |
|||
- create array of childs pids |
|||
- for each philo, create a fork() : |
|||
- philo_life() -> |
|||
- |
|||
- loop |
|||
|
@ -0,0 +1,26 @@ |
|||
NAME = philosophers |
|||
|
|||
SRCS = philo_threads.c philo_launcher.c philo_utils.c philo_init.c |
|||
OBJS = ${SRCS:.c=.o} |
|||
|
|||
CC = gcc |
|||
CFLAGS = -Werror -Wextra -Wall -g -fsanitize=thread -D_REENTRANT |
|||
RM = rm -rf |
|||
|
|||
.c.o: |
|||
$(CC) $(CFLAGS) -c $< -o $(<:.c=.o) |
|||
|
|||
all: $(NAME) |
|||
|
|||
$(NAME): $(OBJS) |
|||
${CC} ${CFLAGS} -lpthread ${OBJS} -o ${NAME} |
|||
|
|||
clean: |
|||
${RM} ${OBJS} |
|||
|
|||
fclean: clean |
|||
${RM} ${NAME} |
|||
|
|||
re: fclean all |
|||
|
|||
.PHONY: all clean fclean re |
@ -0,0 +1,62 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo_init.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2022/04/11 10:33:01 by narnaud #+# #+# */ |
|||
/* Updated: 2022/04/11 10:35:12 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
t_param *init_param(char **argv) |
|||
{ |
|||
t_param *ret; |
|||
|
|||
ret = malloc(sizeof(t_param)); |
|||
ret->philo_amount = mini_atoi(argv[0]); |
|||
ret->die_time = mini_atoi(argv[1]); |
|||
ret->eat_duration = mini_atoi(argv[2]); |
|||
ret->sleep_duration = mini_atoi(argv[3]); |
|||
if (argv[4]) |
|||
ret->eat_amount = mini_atoi(argv[4]); |
|||
else |
|||
ret->eat_amount = 2147483647; |
|||
return (ret); |
|||
} |
|||
|
|||
t_room *init_room(char **argv) |
|||
{ |
|||
t_room *room; |
|||
struct timeval time; |
|||
static int i = 0; |
|||
|
|||
gettimeofday(&time, NULL); |
|||
room = malloc(sizeof(t_room)); |
|||
room->param = init_param(argv); |
|||
room->safe = malloc(sizeof(pthread_mutex_t)); |
|||
pthread_mutex_init(room->safe, NULL); |
|||
room->philos = \ |
|||
(t_philo **)malloc(room->param->philo_amount * sizeof(t_philo *)); |
|||
room->running = 1; |
|||
room->start_time = time.tv_sec * 1000 + time.tv_usec / 1000; |
|||
room->time = 0; |
|||
room->i = 0; |
|||
while (i < room->param->philo_amount) |
|||
{ |
|||
room->philos[i] = (t_philo *)malloc(sizeof(t_philo)); |
|||
room->philos[i]->fork = malloc(sizeof(pthread_mutex_t)); |
|||
room->philos[i]->safe = malloc(sizeof(pthread_mutex_t)); |
|||
room->philos[i]->thd = malloc(sizeof(pthread_t)); |
|||
room->philos[i]->eat_time = room->time; |
|||
room->philos[i]->eat_amount = 0; |
|||
room->philos[i]->i = i; |
|||
pthread_mutex_init(room->philos[i]->fork, NULL); |
|||
pthread_mutex_init(room->philos[i++]->safe, NULL); |
|||
} |
|||
return (room); |
|||
} |
|||
|
@ -0,0 +1,77 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo_launcher.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2021/11/24 15:44:04 by narnaud #+# #+# */ |
|||
/* Updated: 2022/04/11 14:55:43 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
int waiter(t_room *room); |
|||
|
|||
int main(int argc, char **argv) |
|||
{ |
|||
t_room *room; |
|||
|
|||
if (argc < 5 || argc > 6) |
|||
return (1); |
|||
room = init_room(argv + 1); |
|||
pthread_create(&room->clock_thd, NULL, room_clock, (void *)room); |
|||
while (room->i >= 0) |
|||
{ |
|||
pthread_mutex_lock(room->safe); |
|||
if (room->i >= room->param->philo_amount) |
|||
room->i -= 1 + (room->param->philo_amount % 2) * 2; |
|||
pthread_create(room->philos[room->i]->thd, NULL, \ |
|||
philos_life, (void *)room); |
|||
pthread_detach(*room->philos[room->i]->thd); |
|||
pthread_mutex_unlock(room->safe); |
|||
usleep(CLOCK_ONE); |
|||
pthread_mutex_lock(room->safe); |
|||
if ((room->i % 2) == 0) |
|||
room->i += 2; |
|||
else if ((room->i % 2) == 1) |
|||
room->i -= 2; |
|||
pthread_mutex_unlock(room->safe); |
|||
} |
|||
while (!waiter(room)) |
|||
usleep(CLOCK_TWO); |
|||
return (clean_memory(room)); |
|||
} |
|||
|
|||
int waiter(t_room *room) |
|||
{ |
|||
t_param *param; |
|||
int i; |
|||
int starvest; |
|||
|
|||
pthread_mutex_lock(room->safe); |
|||
i = 0; |
|||
param = room->param; |
|||
starvest = param->eat_amount; |
|||
while (i < param->philo_amount) |
|||
{ |
|||
pthread_mutex_lock(room->philos[i]->safe); |
|||
if (room->philos[i]->eat_time + param->die_time < room->time) |
|||
{ |
|||
safe_print("%ld %d died\n", room, i); |
|||
room->running = 0; |
|||
pthread_mutex_unlock(room->philos[i]->safe); |
|||
pthread_mutex_unlock(room->safe); |
|||
return (1); |
|||
} |
|||
if (room->philos[i]->eat_amount < starvest) |
|||
starvest = room->philos[i]->eat_amount; |
|||
pthread_mutex_unlock(room->philos[i]->safe); |
|||
i++; |
|||
} |
|||
if (starvest == param->eat_amount) |
|||
room->running = 0; |
|||
pthread_mutex_unlock(room->safe); |
|||
return (!room->running); |
|||
} |
@ -0,0 +1,84 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo_threads.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2021/11/26 07:43:48 by narnaud #+# #+# */ |
|||
/* Updated: 2022/04/11 14:52:22 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
void *philos_life(void *r) |
|||
{ |
|||
t_room *room; |
|||
t_param *param; |
|||
t_philo *philo; |
|||
int id; |
|||
int id_p; |
|||
|
|||
room = (t_room *)r; |
|||
param = room->param; |
|||
pthread_mutex_lock(room->safe); |
|||
id = room->i; |
|||
philo = room->philos[id]; |
|||
philo->eat_time = room->time; |
|||
id_p = (id + 1) % param->philo_amount; |
|||
pthread_mutex_unlock(room->safe); |
|||
while (room->running) |
|||
{ |
|||
pthread_mutex_lock(philo->fork); |
|||
safe_print("%ld %d has taken a fork\n", room, id); |
|||
pthread_mutex_lock(room->philos[id_p]->fork); |
|||
safe_print("%ld %d has taken a fork\n", room, id); |
|||
safe_print("%ld %d is eating\n", room, id); |
|||
pthread_mutex_lock(philo->safe); |
|||
philo->eat_time = room->time; |
|||
pthread_mutex_unlock(philo->safe); |
|||
if (check_end(room)) |
|||
{ |
|||
pthread_mutex_unlock(philo->fork); |
|||
pthread_mutex_unlock(room->philos[id_p]->fork); |
|||
return (NULL); |
|||
} |
|||
usleep(param->eat_duration * 1000); |
|||
pthread_mutex_unlock(philo->fork); |
|||
pthread_mutex_unlock(room->philos[id_p]->fork); |
|||
if (check_end(room)) |
|||
return (NULL); |
|||
safe_print("%ld %d is sleeping\n", room, id); |
|||
pthread_mutex_lock(philo->safe); |
|||
philo->eat_amount++; |
|||
pthread_mutex_unlock(philo->safe); |
|||
usleep(param->sleep_duration * 1000); |
|||
if (check_end(room)) |
|||
return (NULL); |
|||
safe_print("%ld %d is thinking\n", room, id); |
|||
} |
|||
return (NULL); |
|||
} |
|||
|
|||
void *room_clock(void *r) |
|||
{ |
|||
t_room *room; |
|||
struct timeval time; |
|||
|
|||
room = (t_room *)r; |
|||
while (1) |
|||
{ |
|||
gettimeofday(&time, NULL); |
|||
pthread_mutex_lock(room->safe); |
|||
room->time = time.tv_sec * 1000 + time.tv_usec / 1000 - room->start_time; |
|||
if (!room->running) |
|||
{ |
|||
pthread_mutex_unlock(room->safe); |
|||
return(NULL); |
|||
} |
|||
pthread_mutex_unlock(room->safe); |
|||
usleep(CLOCK_TWO); |
|||
} |
|||
return (NULL); |
|||
} |
@ -0,0 +1,71 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo_utils.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2022/04/11 10:29:50 by narnaud #+# #+# */ |
|||
/* Updated: 2022/04/11 14:50:59 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
|
|||
int mini_atoi(char *nbr) |
|||
{ |
|||
int ret; |
|||
|
|||
ret = 0; |
|||
while (*nbr >= '0' && *nbr <= '9') |
|||
{ |
|||
ret = (*nbr - '0') + (10 * ret); |
|||
nbr++; |
|||
} |
|||
return (ret); |
|||
} |
|||
|
|||
void safe_print(char *str, t_room *room, int id) |
|||
{ |
|||
pthread_mutex_lock(room->safe); |
|||
printf(str, room->time, id); |
|||
pthread_mutex_unlock(room->safe); |
|||
} |
|||
|
|||
int check_end(t_room *room) |
|||
{ |
|||
int ret; |
|||
|
|||
ret = 0; |
|||
pthread_mutex_lock(room->safe); |
|||
if (!room->running) |
|||
ret = 1; |
|||
pthread_mutex_unlock(room->safe); |
|||
return (ret); |
|||
} |
|||
int clean_memory(t_room *room) |
|||
{ |
|||
t_param *param; |
|||
int i; |
|||
|
|||
i = 0; |
|||
param = room->param; |
|||
while (i < param->philo_amount) |
|||
{ |
|||
pthread_mutex_destroy(room->philos[i]->safe); |
|||
pthread_mutex_destroy(room->philos[i]->fork); |
|||
free(room->philos[i]->safe); |
|||
free(room->philos[i]->fork); |
|||
free(room->philos[i]->thd); |
|||
free(room->philos[i]); |
|||
i++; |
|||
} |
|||
pthread_mutex_destroy(room->safe); |
|||
free(room->safe); |
|||
free(room->philos); |
|||
free(room->param); |
|||
free(room); |
|||
return (0); |
|||
} |
|||
|
@ -0,0 +1,70 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philosophers.h :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2021/11/24 15:44:06 by narnaud #+# #+# */ |
|||
/* Updated: 2022/05/16 14:09:56 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#ifndef PHILOSOPHERS_H |
|||
# define PHILOSOPHERS_H |
|||
# define CLOCK_ONE 500 |
|||
# define CLOCK_TWO 1000 |
|||
|
|||
# include <unistd.h> |
|||
# include <stdio.h> |
|||
# include <stdlib.h> |
|||
# include <string.h> |
|||
# include <pthread.h> |
|||
# include <sys/time.h> |
|||
|
|||
typedef struct s_param |
|||
{ |
|||
int philo_amount; |
|||
int die_time; |
|||
int eat_duration; |
|||
int sleep_duration; |
|||
int eat_amount; |
|||
} t_param; |
|||
|
|||
typedef struct s_philo |
|||
{ |
|||
pthread_mutex_t *fork; |
|||
pthread_mutex_t *safe; |
|||
pthread_t *thd; |
|||
unsigned long eat_time; |
|||
int eat_amount; |
|||
int i; |
|||
} t_philo; |
|||
|
|||
typedef struct s_room |
|||
{ |
|||
t_param *param; |
|||
t_philo **philos; |
|||
pthread_mutex_t *safe; |
|||
pthread_t clock_thd; |
|||
int running; |
|||
unsigned long start_time; |
|||
unsigned long time; |
|||
int i; |
|||
} t_room; |
|||
|
|||
//philo_threads.c
|
|||
void *philos_life(void *r); |
|||
void *room_clock(void *r); |
|||
|
|||
//philo_init.c
|
|||
t_param *init_param(char **argv); |
|||
t_room *init_room(char **argv); |
|||
|
|||
//philo_utils.c
|
|||
int mini_atoi(char *nbr); |
|||
void safe_print(char *str, t_room *room, int id); |
|||
int clean_memory(t_room *room); |
|||
int check_end(t_room *room); |
|||
|
|||
#endif |
@ -0,0 +1,102 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2022/05/16 14:03:42 by narnaud #+# #+# */ |
|||
/* Updated: 2022/05/16 14:03:47 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
void *check_halt(void * p) |
|||
{ |
|||
size_t time; |
|||
t_philo *philo; |
|||
|
|||
philo = p; |
|||
while (1) |
|||
{ |
|||
usleep(1000); |
|||
time = gettime(); |
|||
philo->table->time = time; |
|||
if (time - philo->last_meal_time > philo->table->time_to_die) |
|||
{ |
|||
printf("%lu %d died\n", time, philo->id); |
|||
exit(EXIT_SUCCESS); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void philo_life(t_philo *philo) |
|||
{ |
|||
t_table *table; |
|||
|
|||
table = philo->table; |
|||
while (1) |
|||
{ |
|||
sem_wait(table->sptr); |
|||
printf("%lu %d has taken a fork\n", table->time, philo->id); |
|||
sem_wait(table->sptr); |
|||
printf("%lu %d has taken a fork\n", table->time, philo->id); |
|||
philo->last_meal_time = table->time; |
|||
printf("%lu %d is eating\n", table->time, philo->id); |
|||
usleep(table->eating_time * 1000); |
|||
sem_post(table->sptr); |
|||
sem_post(table->sptr); |
|||
printf("%lu %d is sleeping\n", table->time, philo->id); |
|||
usleep(table->sleeping_time * 1000); |
|||
printf("%lu %d is thinking\n", table->time, philo->id); |
|||
} |
|||
} |
|||
|
|||
void init_philos(t_table *table) |
|||
{ |
|||
size_t i; |
|||
pthread_t checks; |
|||
|
|||
table->pid = malloc(sizeof(pid_t) * table->nb_of_philos); |
|||
memset(table->pid, 0, sizeof(pid_t) * table->nb_of_philos); |
|||
i = 0; |
|||
while (i < table->nb_of_philos) |
|||
{ |
|||
table->pid[i] = fork(); |
|||
table->philos[i].table = table; |
|||
table->philos[i].id = i; |
|||
if (!table->pid[i]) |
|||
{ |
|||
pthread_create(&checks, NULL, check_halt, table->philos + i); |
|||
philo_life(table->philos + i); |
|||
} |
|||
usleep(500); |
|||
i++; |
|||
} |
|||
} |
|||
|
|||
int main(int argc, char **argv) |
|||
{ |
|||
static t_table *table; |
|||
static size_t i = 0; |
|||
int status; |
|||
|
|||
sem_unlink("/chopsticks"); |
|||
sem_unlink("/death"); |
|||
if (argc < 5 || argc > 6) |
|||
return (1); |
|||
table = parsing(argv + 1); |
|||
table->sptr = sem_open("/chopsticks", O_CREAT, 0664, table->nb_of_philos); |
|||
table->death = sem_open("/death", O_CREAT, 0664, 1); |
|||
init_philos(table); |
|||
waitpid(-1, &status, 0); |
|||
while (i < table->nb_of_philos) |
|||
{ |
|||
kill(table->pid[i], SIGINT); |
|||
i++; |
|||
} |
|||
sem_unlink("/chopsticks"); |
|||
sem_unlink("/deaths"); |
|||
return(0); |
|||
} |
@ -0,0 +1,60 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philo_utils.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2022/05/16 14:04:06 by narnaud #+# #+# */ |
|||
/* Updated: 2022/05/16 14:04:11 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#include "philosophers.h" |
|||
|
|||
static int mini_atoi(char *nbr) |
|||
{ |
|||
int ret; |
|||
|
|||
ret = 0; |
|||
while (*nbr >= '0' && *nbr <= '9') |
|||
{ |
|||
ret = (*nbr - '0') + (10 * ret); |
|||
nbr++; |
|||
} |
|||
return (ret); |
|||
} |
|||
|
|||
t_table *parsing(char **argv) |
|||
{ |
|||
t_table *table; |
|||
|
|||
table = malloc(sizeof(t_table)); |
|||
memset(table, 0, sizeof(t_table)); |
|||
table->nb_of_philos = mini_atoi(argv[0]); |
|||
table->philos = malloc(sizeof(t_philo) * table->nb_of_philos); |
|||
memset(table->philos, 0, sizeof(t_philo) * table->nb_of_philos); |
|||
table->time_to_die = mini_atoi(argv[1]); |
|||
table->eating_time = mini_atoi(argv[2]); |
|||
table->sleeping_time = mini_atoi(argv[3]); |
|||
table->time = gettime(); |
|||
if (argv[4]) |
|||
table->nb_of_meal = mini_atoi(argv[4]); |
|||
else |
|||
table->nb_of_meal = 2147483647; |
|||
return (table); |
|||
} |
|||
|
|||
size_t gettime(void) |
|||
{ |
|||
static struct timeval time = {0,0}; |
|||
struct timeval actualtime; |
|||
size_t ret; |
|||
|
|||
if(time.tv_sec == 0 && time.tv_usec == 0) |
|||
gettimeofday(&time, NULL); |
|||
gettimeofday(&actualtime, NULL); |
|||
ret = (size_t)((actualtime.tv_sec * 1000 + actualtime.tv_usec / 1000)\ |
|||
- (time.tv_sec * 1000 + time.tv_usec / 1000)); |
|||
return (ret); |
|||
} |
@ -0,0 +1,71 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* philosophers.h :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* Created: 2022/05/16 14:03:01 by narnaud #+# #+# */ |
|||
/* Updated: 2022/05/16 14:03:20 by narnaud ### ########.fr */ |
|||
/* */ |
|||
/* ************************************************************************** */ |
|||
|
|||
#ifndef PHILOSOPHERS_H |
|||
# define PHILOSOPHERS_H |
|||
|
|||
/*
|
|||
|
|||
• Chaque philosophe doit être représenté par un thread. |
|||
• Toutes les fourchettes sont au centre de la table. |
|||
• Elles n’ont pas d’état spécifique en mémoire, mais le nombre de fourchettes |
|||
disponibles est représenté par un sémaphore. • Chaque philosophe est représenté |
|||
par un processus différent. Cependant, le processus principal ne doit pas être |
|||
un philosophe. |
|||
|
|||
*/ |
|||
|
|||
# include <unistd.h> |
|||
# include <stdio.h> |
|||
# include <stdlib.h> |
|||
# include <pthread.h> |
|||
# include <string.h> |
|||
# include <errno.h> |
|||
# include <fcntl.h> |
|||
# include <signal.h> |
|||
# include <sys/wait.h> |
|||
# include <sys/time.h> |
|||
# include <sys/stat.h> |
|||
# include <semaphore.h> |
|||
|
|||
typedef struct s_table t_table; |
|||
|
|||
typedef struct s_philo |
|||
{ |
|||
int id; |
|||
size_t meals_done; |
|||
size_t last_meal_time; |
|||
t_table *table; |
|||
} t_philo; |
|||
|
|||
typedef struct s_table |
|||
{ |
|||
size_t nb_of_philos; |
|||
size_t time_to_die; |
|||
size_t eating_time; |
|||
size_t sleeping_time; |
|||
size_t nb_of_meal; |
|||
int i; |
|||
sem_t *sptr; |
|||
sem_t *death; |
|||
t_philo *philos; |
|||
size_t time; |
|||
size_t start_time; |
|||
int *pid; |
|||
} t_table; |
|||
|
|||
/***************************/ |
|||
|
|||
t_table *parsing(char **argv); |
|||
size_t gettime(void); |
|||
|
|||
#endif |
Loading…
Reference in new issue