Skip to content

Commit

Permalink
philo
Browse files Browse the repository at this point in the history
  • Loading branch information
m3zh committed Nov 5, 2021
1 parent 5f8adec commit 3b73942
Show file tree
Hide file tree
Showing 8 changed files with 584 additions and 0 deletions.
47 changes: 47 additions & 0 deletions philo_mac/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2021/09/15 12:21:19 by mdesalle #+# #+# #
# Updated: 2021/11/05 09:56:05 by mlazzare ### ########.fr #
# #
# **************************************************************************** #

NAME = philo

CC = gcc -g3
CFLAGS = -Wall -Wextra -Werror
#CFLAGS += -fsanitize=thread

LIB = -lpthread

SRC = \
./src/philosphers.c \
./src/thread_routine.c \
./src/time.c \
./src/utils.c \
./src/ft_atoi.c \
./src/main.c \

OBJ = $(SRC:.c=.o)

.c.o:
@$(CC) $(CFLAGS) $< -o $@

$(NAME): $(LIBFT) $(SRC)
$(CC) $(SRC) $(CFLAGS) $(LIB) -o $(NAME)

all: $(NAME)

clean:
@rm -rf $(OBJ)

fclean: clean
@rm -rf $(NAME)

re: fclean all

.PHONY: all clean fclean re
71 changes: 71 additions & 0 deletions philo_mac/inc/philo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philo.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/07 14:32:05 by mlazzare #+# #+# */
/* Updated: 2021/11/05 10:20:30 by mlazzare ### ########.fr */
/* */
/* ************************************************************************** */

#ifndef PHILO_H
# define PHILO_H

# include <stdio.h>
# include <string.h>
# include <pthread.h>
# include <stdlib.h>
# include <unistd.h>
# include <limits.h>
# include <sys/time.h>

# define FORK "has taken a fork"
# define EAT "is eating"
# define SLEEP "is sleeping"
# define THINK "is thinking"
# define DIE "\e[0;31mDIED (ভ_ ভ)\e[m"
# define LEFT 0
# define RIGHT 1

typedef struct s_params
{
int num;
int forks;
int time2die;
int time2eat;
int time2sleep;
int max_iter;
int check_meal;
int over;
long int start;
pthread_mutex_t *death;
pthread_mutex_t *fork;
} t_params;

typedef struct s_philo
{
int id;
int dead;
int iter_num;
long int thread_start;
long int last_meal;
pthread_t life_tid;
pthread_mutex_t *left_fork;
pthread_mutex_t *right_fork;
t_params *params;
} t_philo;

int philosophers(t_params *p);
int init_philo(t_params *p, t_philo *philo);
int print_routine(long int now, t_philo *p, char *action);
int check_death(t_philo *p);
int ft_atoi(const char *str);
void *thread_routine(void *job);
int ft_usleep(long int time);
void final_print(int alive);
int error_msg(char *s, t_params *par, t_philo *p, int malloc);
long int time_now(t_philo *p);

#endif
70 changes: 70 additions & 0 deletions philo_mac/src/ft_atoi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/11/10 08:05:31 by mlazzare #+# #+# */
/* Updated: 2021/11/02 09:49:07 by mlazzare ### ########.fr */
/* */
/* ************************************************************************** */

#include "../inc/philo.h"

static int ft_isnumber(const char *s)
{
int i;

i = 0;
if (s[i] && (s[i] == '-' || s[i] == '+'))
i++;
while (s[i])
{
if (!(s[i] >= '0' && s[i] <= '9'))
return (0);
i++;
}
return (1);
}

static int check_sign(char c)
{
if (c == '-')
return (-1);
return (1);
}

static int check_overflow(int sign)
{
if (sign == 1)
return (-1);
return (0);
}

int ft_atoi(const char *str)
{
int i;
int sign;
unsigned long long int n;

i = 0;
n = 0;
if (!ft_isnumber(str))
return (-1);
sign = 1;
while ((str[i] >= 9 && str[i] <= 13) || str[i] == ' ')
i++;
if (str[i] == '-' || str[i] == '+')
sign = check_sign(str[i++]);
while (str[i] >= '0' && str[i] <= '9')
{
if (n >= LONG_MAX)
{
n = check_overflow(sign);
break ;
}
n = n * 10 + (str[i++] - '0');
}
return (sign * (int)n);
}
91 changes: 91 additions & 0 deletions philo_mac/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/07 14:31:20 by mlazzare #+# #+# */
/* Updated: 2021/11/05 13:00:45 by mlazzare ### ########.fr */
/* */
/* ************************************************************************** */

#include "../inc/philo.h"

int init_philo(t_params *p, t_philo *philo)
{
int i;

i = -1;
while (++i < p->num)
{
philo[i].id = i;
philo[i].dead = 0;
philo[i].iter_num = 0;
philo[i].thread_start = 0;
philo[i].last_meal = 0;
philo[i].params = p;
philo[i].left_fork = &p->fork[i];
philo[i].right_fork = 0;
}
return (0);
}

static int init_params_mutex(t_params *p)
{
int i;

i = -1;
p->death = malloc(sizeof(pthread_mutex_t));
if (!p->death)
return (error_msg("Error\nMutex death: malloc failed\n", p, 0, 1));
p->fork = malloc(sizeof(pthread_mutex_t) * p->num);
if (!p->fork)
return (error_msg("Error\nMutex fork: malloc failed\n", p, 0, 1));
if (pthread_mutex_init(p->death, NULL) == -1)
return (error_msg("Error\nMutex init failed\n", p, 0, 1));
while (++i < p->num)
if (pthread_mutex_init(&p->fork[i], NULL) == -1)
return (error_msg("Error\nMutex init failed\n", p, 0, 1));
return (0);
}

static int init_params(t_params *p, char **ag)
{
int mutex;

p->num = ft_atoi(ag[1]);
if (p->num == 0)
return (printf("No philo here ...\n"));
p->forks = p->num;
p->time2die = ft_atoi(ag[2]);
if (p->time2die == 0)
return (printf("No time to even be born ...\n"));
p->time2eat = ft_atoi(ag[3]);
p->time2sleep = ft_atoi(ag[4]);
if (p->time2eat == 0 || p->time2sleep == 0)
return (printf("This philo is sleep or food deprived ...\n"));
p->max_iter = 0;
p->check_meal = 0;
p->start = 0;
if (ag[5])
{
p->check_meal = 1;
p->max_iter = ft_atoi(ag[5]);
}
p->over = 0;
mutex = init_params_mutex(p);
return (mutex || p->num < 0 || p->time2die < 0 || p->time2eat < 0
|| p->time2sleep < 0 || p->max_iter < 0);
}

int main(int ac, char **ag)
{
t_params p;

if ((ac != 5 && ac != 6) || init_params(&p, ag))
return (error_msg("Error: invalid arguments\n", &p, 0, 1));
if (philosophers(&p))
return (EXIT_FAILURE);
return (EXIT_SUCCESS);
}
87 changes: 87 additions & 0 deletions philo_mac/src/philosphers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* philosphers.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mlazzare <mlazzare@student.s19.be> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/07 14:31:20 by mlazzare #+# #+# */
/* Updated: 2021/11/05 12:40:56 by mlazzare ### ########.fr */
/* */
/* ************************************************************************** */

#include "../inc/philo.h"

static int check_meals(t_philo p, int last)
{
if (p.params->check_meal && last == p.params->num - 1
&& p.iter_num == p.params->max_iter)
return (ft_usleep(300));
return (0);
}

static void check_thread(t_params *p, t_philo *philo)
{
int i;

ft_usleep(30 * p->num);
while (!p->over)
{
i = -1;
while (++i < p->num)
if (check_death(&philo[i]) || check_meals(philo[i], i))
p->over = 1;
}
if (p->check_meal && philo[p->num - 1].iter_num == p->max_iter)
{
ft_usleep(5 * p->num);
printf(" \n");
printf(" All philosophers have eaten %d times\n", p->max_iter);
return (final_print(1));
}
return (final_print(0));
}

static int init_thread(t_params *p, t_philo *philo)
{
int i;

i = -1;
p->start = time_now(philo);
while (++i < p->num)
{
philo[i].right_fork = philo[(i + 1) % p->num].left_fork;
if (pthread_create(&philo[i].life_tid, NULL,
&thread_routine, &philo[i]) == -1)
return (error_msg("Error\nFailed to create thread\n", p, philo, 2));
}
return (0);
}

static void end_thread(t_params *p, t_philo *philo)
{
int i;

i = -1;
while (++i < p->num)
pthread_detach(philo[i].life_tid);
pthread_mutex_destroy(p->death);
pthread_mutex_destroy(p->fork);
free(p->death);
free(p->fork);
free(philo);
}

int philosophers(t_params *params)
{
t_philo *philo;

philo = malloc(sizeof(t_philo) * params->num);
if (!philo || init_philo(params, philo))
return (EXIT_FAILURE);
if (init_thread(params, philo))
return (EXIT_FAILURE);
check_thread(params, philo);
end_thread(params, philo);
return (0);
}
Loading

0 comments on commit 3b73942

Please sign in to comment.