firsttry
This commit is contained in:
commit
4580f4d963
11
Readme.md
Normal file
11
Readme.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Philosophers
|
||||
|
||||
---
|
||||
## Tester
|
||||
- Write tester
|
||||
- Wrong input
|
||||
- try to make the program hang
|
||||
- check 1 philosopher
|
||||
|
||||
---
|
||||
[This project is part of the studies at 42](https://42.fr/en/homepage/)
|
@ -0,0 +1 @@
|
||||
Subproject commit 9ada401ba0d9cd15e3c132c66693c13d56371965
|
46
philo/Makefile
Normal file
46
philo/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
# **************************************************************************** #
|
||||
# #
|
||||
# .--. _ #
|
||||
# Makefile |o_o || | #
|
||||
# |:_/ || |_ _ ___ __ #
|
||||
# By: djonker <djonker@student.codam.nl> // \ \ __| | | \ \/ / #
|
||||
# (| | )|_| |_| |> < #
|
||||
# Created: 2021/08/19 15:20:20 by djonker /'\_ _/`\__|\__,_/_/\_\ #
|
||||
# Updated: 2023/05/14 09:08:22 by djonker \___)=(___/ #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
NAME =philo
|
||||
CC =gcc
|
||||
CFLAGS =-Wall -Werror -Wextra -g -fsanitize=thread
|
||||
RM =rm -f
|
||||
SRC =src/philo.c\
|
||||
src/init.c\
|
||||
src/util.c
|
||||
OBJ =$(SRC:src/%.c=obj/%.o)
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
clean:
|
||||
@$(RM) -r obj
|
||||
@printf "\e[1;35mCleaned Object Files\n\e[0;00m"
|
||||
|
||||
fclean: clean
|
||||
@$(RM) philo philo_bonus
|
||||
@printf "\e[1;31mCleaned Executables\n\e[0;00m"
|
||||
|
||||
re: fclean all
|
||||
|
||||
$(NAME):
|
||||
|
||||
$(OBJ): $(SRC)
|
||||
@mkdir -p $(dir $@)
|
||||
@printf "\e[1;34mBuilding $@\n\e[0;00m"
|
||||
@$(CC) $(CFLAGS) -c $(@:obj/%.o=src/%.c) -o $@
|
||||
|
||||
philo: $(OBJ)
|
||||
@printf "\e[1;36mCompiling $@\n\e[0;00m"
|
||||
@$(CC) $(CFLAGS) $^ -o $@
|
||||
@printf "\e[1;32mDone\e[0;00m\n"
|
||||
|
||||
.PHONY: all clean fclean re
|
70
philo/philo.h
Normal file
70
philo/philo.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* philo.h |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/11 07:19:18 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 06:08:32 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PHILO_H
|
||||
# define PHILO_H
|
||||
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <pthread.h>
|
||||
# include <sys/time.h>
|
||||
|
||||
typedef struct s_philo
|
||||
{
|
||||
int id;
|
||||
int cycles;
|
||||
pthread_mutex_t *forks;
|
||||
pthread_mutex_t *datarace;
|
||||
int *philos;
|
||||
int lfork;
|
||||
int rfork;
|
||||
long long lastfood;
|
||||
long long *dietime;
|
||||
long long *eattime;
|
||||
long long *sleeptime;
|
||||
long long *strtt;
|
||||
int *target;
|
||||
int *done;
|
||||
int *dead;
|
||||
pthread_t thrd;
|
||||
} t_philo;
|
||||
|
||||
typedef struct s_strct
|
||||
{
|
||||
pthread_mutex_t forks[512];
|
||||
pthread_mutex_t datarace[3];
|
||||
t_philo philo[512];
|
||||
int philos;
|
||||
long long dietime;
|
||||
long long eattime;
|
||||
long long sleeptime;
|
||||
long long strtt;
|
||||
int target;
|
||||
int done;
|
||||
int dead;
|
||||
char *error;
|
||||
} t_strct;
|
||||
|
||||
t_strct *ft_parseandvalidateinput(int argc, char **argv);
|
||||
int ft_initstructandmutex(t_strct *strct);
|
||||
int ft_startcycle(t_strct *strct);
|
||||
void *ft_cycle(void *pointer);
|
||||
int ft_liveordie(t_strct *strct, int i);
|
||||
int ft_cleanup(t_strct *strct);
|
||||
long long ft_time(void);
|
||||
int philo_atoi(char *str);
|
||||
int ft_printreturn(char *reason, int code);
|
||||
int ft_charactercheck(int argc, char **argv);
|
||||
int ft_alivecheck(t_philo *ps);
|
||||
|
||||
#endif
|
91
philo/src/init.c
Normal file
91
philo/src/init.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* init.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/15 02:00:19 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 08:24:58 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_charactercheck(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = 1;
|
||||
j = 0;
|
||||
while (i < argc)
|
||||
{
|
||||
while (argv[i][j] != '\0')
|
||||
{
|
||||
if (argv[i][j] < '0' || argv[i][j] > '9')
|
||||
return (1);
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
j = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_strct *ft_parseandvalidateinput(int argc, char **argv)
|
||||
{
|
||||
t_strct *strct;
|
||||
|
||||
strct = malloc(sizeof(t_strct));
|
||||
strct->error = NULL;
|
||||
if (ft_charactercheck(argc, argv))
|
||||
strct->error = "input can only be numbers";
|
||||
strct->philos = philo_atoi(argv[1]);
|
||||
if (strct->philos < 1 || strct->philos > 500)
|
||||
strct->error = "Min 1 and Max 500 philosophers";
|
||||
strct->dietime = philo_atoi(argv[2]);
|
||||
if (strct->dietime < 50)
|
||||
strct->error = "die time must be a minimum of 50ms";
|
||||
strct->eattime = philo_atoi(argv[3]);
|
||||
if (strct->eattime < 50)
|
||||
strct->error = "eat time must be a minimum of 50ms";
|
||||
strct->sleeptime = philo_atoi(argv[4]);
|
||||
if (strct->sleeptime < 50)
|
||||
strct->error = "sleeptime must be a minimum of 50ms";
|
||||
if (argc == 6)
|
||||
strct->target = philo_atoi(argv[5]);
|
||||
else
|
||||
strct->target = 1000000000;
|
||||
if (strct->target < 0)
|
||||
strct->error = "We can't do negative cycles";
|
||||
return (strct);
|
||||
}
|
||||
|
||||
int ft_initstructandmutex(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i <= strct->philos)
|
||||
{
|
||||
strct->philo[i].id = i + 1;
|
||||
strct->philo[i].cycles = 0;
|
||||
strct->philo[i].thrd = (pthread_t)(&i);
|
||||
strct->philo[i].dietime = &strct->dietime;
|
||||
strct->philo[i].eattime = &strct->eattime;
|
||||
strct->philo[i].sleeptime = &strct->sleeptime;
|
||||
strct->philo[i].strtt = &strct->strtt;
|
||||
strct->philo[i].forks = strct->forks;
|
||||
strct->philo[i].datarace = strct->datarace;
|
||||
strct->philo[i].lfork = i;
|
||||
strct->philo[i].rfork = (i + 1) % strct->philos;
|
||||
strct->philo[i].philos = &strct->philos;
|
||||
strct->philo[i].target = &strct->target;
|
||||
strct->philo[i].done = &strct->done;
|
||||
strct->philo[i].dead = &strct->dead;
|
||||
pthread_mutex_init(&strct->forks[i], NULL);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
133
philo/src/philo.c
Normal file
133
philo/src/philo.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* philo.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/11 06:42:31 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 08:18:24 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_eatsleepthink(t_philo *ps)
|
||||
{
|
||||
pthread_mutex_lock(&ps->forks[ps->lfork]);
|
||||
if (ft_alivecheck(ps))
|
||||
printf("%lld %d has taken a fork\n", ft_time() - *ps->strtt, ps->id);
|
||||
if (*ps->philos == 1)
|
||||
return (1);
|
||||
pthread_mutex_lock(&ps->forks[ps->rfork]);
|
||||
if (ft_alivecheck(ps))
|
||||
printf("%lld %d has taken a fork\n", ft_time() - *ps->strtt, ps->id);
|
||||
pthread_mutex_lock(&ps->datarace[0]);
|
||||
ps->lastfood = ft_time();
|
||||
pthread_mutex_unlock(&ps->datarace[0]);
|
||||
if (ft_alivecheck(ps))
|
||||
printf("%lld %d is eating\n", ft_time() - *ps->strtt, ps->id);
|
||||
usleep(*ps->eattime * 1000);
|
||||
pthread_mutex_unlock(&ps->forks[ps->lfork]);
|
||||
pthread_mutex_unlock(&ps->forks[ps->rfork]);
|
||||
if (ft_alivecheck(ps))
|
||||
printf("%lld %d is sleeping\n", ft_time() - *ps->strtt, ps->id);
|
||||
usleep(*ps->sleeptime * 1000);
|
||||
if (ft_alivecheck(ps))
|
||||
printf("%lld %d is thinking\n", ft_time() - *ps->strtt, ps->id);
|
||||
pthread_mutex_lock(&ps->datarace[2]);
|
||||
ps->cycles++;
|
||||
pthread_mutex_unlock(&ps->datarace[2]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *ft_cycle(void *pointer)
|
||||
{
|
||||
t_philo *philo;
|
||||
|
||||
philo = pointer;
|
||||
if ((philo->id - 1) % 2)
|
||||
usleep(*philo->eattime * 1000);
|
||||
pthread_mutex_lock(&philo->datarace[2]);
|
||||
while (philo->cycles < *philo->target && *philo->dead == 0)
|
||||
{
|
||||
pthread_mutex_unlock(&philo->datarace[2]);
|
||||
if (ft_eatsleepthink(philo))
|
||||
return (NULL);
|
||||
pthread_mutex_lock(&philo->datarace[2]);
|
||||
}
|
||||
pthread_mutex_unlock(&philo->datarace[2]);
|
||||
pthread_mutex_lock(&philo->datarace[1]);
|
||||
*philo->done = *philo->done + 1;
|
||||
pthread_mutex_unlock(&philo->datarace[1]);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int ft_liveordie(t_strct *stct, int i)
|
||||
{
|
||||
pthread_mutex_lock(&stct->datarace[1]);
|
||||
while (stct->done < stct->philos)
|
||||
{
|
||||
pthread_mutex_unlock(&stct->datarace[1]);
|
||||
if (i == stct->philos)
|
||||
i = 0;
|
||||
pthread_mutex_lock(&stct->datarace[0]);
|
||||
if (ft_time() - stct->philo[i].lastfood > stct->dietime)
|
||||
{
|
||||
printf("%lld %d died\n", ft_time() - stct->strtt, stct->philo[i].id);
|
||||
pthread_mutex_lock(&stct->datarace[2]);
|
||||
stct->dead = 1;
|
||||
pthread_mutex_unlock(&stct->datarace[2]);
|
||||
pthread_mutex_unlock(&stct->datarace[0]);
|
||||
return (1);
|
||||
}
|
||||
pthread_mutex_unlock(&stct->datarace[0]);
|
||||
usleep(100);
|
||||
i++;
|
||||
pthread_mutex_lock(&stct->datarace[1]);
|
||||
}
|
||||
pthread_mutex_unlock(&stct->datarace[1]);
|
||||
printf("All %d philosophers have", stct->philos);
|
||||
printf(" finished all %d cycles\n", stct->target);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ft_startcycle(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
strct->strtt = ft_time();
|
||||
while (i < strct->philos)
|
||||
{
|
||||
strct->philo[i].lastfood = ft_time();
|
||||
pthread_create(&strct->philo[i].thrd, NULL, ft_cycle, &strct->philo[i]);
|
||||
i++;
|
||||
}
|
||||
ft_liveordie(strct, 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
t_strct *strct;
|
||||
|
||||
if (argc < 5 || argc > 6)
|
||||
return (ft_printreturn("Wrong number of arguments", 1));
|
||||
strct = ft_parseandvalidateinput(argc, argv);
|
||||
if (strct->error)
|
||||
{
|
||||
ft_printreturn(strct->error, 0);
|
||||
free(strct);
|
||||
return (1);
|
||||
}
|
||||
strct->done = 0;
|
||||
strct->dead = 0;
|
||||
pthread_mutex_init(&strct->datarace[0], NULL);
|
||||
pthread_mutex_init(&strct->datarace[1], NULL);
|
||||
pthread_mutex_init(&strct->datarace[2], NULL);
|
||||
ft_initstructandmutex(strct);
|
||||
ft_startcycle(strct);
|
||||
ft_cleanup(strct);
|
||||
return (0);
|
||||
}
|
92
philo/src/util.c
Normal file
92
philo/src/util.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* util.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/15 02:01:41 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 06:09:40 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_printreturn(char *reason, int code)
|
||||
{
|
||||
printf("%s\n", reason);
|
||||
return (code);
|
||||
}
|
||||
|
||||
long long ft_time(void)
|
||||
{
|
||||
struct timeval t;
|
||||
long long r;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
r = (t.tv_sec * 1000) + (t.tv_usec / 1000);
|
||||
return (r);
|
||||
}
|
||||
|
||||
int philo_atoi(char *str)
|
||||
{
|
||||
unsigned int r;
|
||||
int c;
|
||||
int n;
|
||||
|
||||
r = 0;
|
||||
c = 0;
|
||||
n = 1;
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
while ((str[c] == 32) || (str[c] > 8 && str[c] < 14))
|
||||
c++;
|
||||
if (str[c] == '-' || str[c] == '+')
|
||||
if (str[c++] == '-')
|
||||
n = -1;
|
||||
while (str[c] >= '0' && str[c] <= '9')
|
||||
{
|
||||
r = 10 * r + (str[c] - '0');
|
||||
if (r > 2147483647 && n == 1)
|
||||
return (-1);
|
||||
else if (r > 2147483648 && n == -1)
|
||||
return (0);
|
||||
c++;
|
||||
}
|
||||
return (n * r);
|
||||
}
|
||||
|
||||
int ft_cleanup(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < strct->philos)
|
||||
{
|
||||
pthread_join(strct->philo[i].thrd, NULL);
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (i < strct->philos)
|
||||
{
|
||||
pthread_mutex_destroy(&strct->forks[i]);
|
||||
i++;
|
||||
}
|
||||
pthread_mutex_destroy(&strct->datarace[0]);
|
||||
pthread_mutex_destroy(&strct->datarace[1]);
|
||||
pthread_mutex_destroy(&strct->datarace[2]);
|
||||
free(strct);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ft_alivecheck(t_philo *ps)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 1;
|
||||
pthread_mutex_lock(&ps->datarace[2]);
|
||||
if (*ps->dead)
|
||||
i = 0;
|
||||
pthread_mutex_unlock(&ps->datarace[2]);
|
||||
return (i);
|
||||
}
|
44
philo_bonus/Makefile
Normal file
44
philo_bonus/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
# **************************************************************************** #
|
||||
# #
|
||||
# .--. _ #
|
||||
# Makefile |o_o || | #
|
||||
# |:_/ || |_ _ ___ __ #
|
||||
# By: djonker <djonker@student.codam.nl> // \ \ __| | | \ \/ / #
|
||||
# (| | )|_| |_| |> < #
|
||||
# Created: 2021/08/19 15:20:20 by djonker /'\_ _/`\__|\__,_/_/\_\ #
|
||||
# Updated: 2023/05/14 09:48:37 by djonker \___)=(___/ #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
NAME =philo_bonus
|
||||
CC =gcc
|
||||
CFLAGS =-Wall -Werror -Wextra# -g -fsanitize=address
|
||||
RM =rm -f
|
||||
SRC =src/philo.c\
|
||||
src/init.c\
|
||||
src/util.c
|
||||
OBJ =$(SRC:src/%.c=obj/%.o)
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
clean:
|
||||
@$(RM) -r obj
|
||||
@printf "\e[1;35mCleaned Object Files\n\e[0;00m"
|
||||
|
||||
fclean: clean
|
||||
@$(RM) philo_bonus
|
||||
@printf "\e[1;31mCleaned Executables\n\e[0;00m"
|
||||
|
||||
re: fclean all
|
||||
|
||||
$(OBJ): $(SRC)
|
||||
@mkdir -p $(dir $@)
|
||||
@printf "\e[1;34mBuilding $@\n\e[0;00m"
|
||||
@$(CC) $(CFLAGS) -c $(@:obj/%.o=src/%.c) -o $@
|
||||
|
||||
philo_bonus:$(OBJ)
|
||||
@printf "\e[1;36mCompiling $@\n\e[0;00m"
|
||||
@$(CC) $(CFLAGS) $^ -o $@
|
||||
@printf "\e[1;32mDone\e[0;00m\n"
|
||||
|
||||
.PHONY: all clean fclean re
|
78
philo_bonus/philo.h
Normal file
78
philo_bonus/philo.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* philo.h |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/11 07:19:18 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 08:55:03 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PHILO_H
|
||||
# define PHILO_H
|
||||
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <fcntl.h>
|
||||
# include <signal.h>
|
||||
# include <semaphore.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/wait.h>
|
||||
|
||||
typedef struct s_philo
|
||||
{
|
||||
int id;
|
||||
int cycles;
|
||||
sem_t *forks;
|
||||
int *philos;
|
||||
int *pid;
|
||||
int lfork;
|
||||
int rfork;
|
||||
long long lastfood;
|
||||
long long *dietime;
|
||||
long long *eattime;
|
||||
long long *sleeptime;
|
||||
long long *strtt;
|
||||
int *target;
|
||||
sem_t *done;
|
||||
sem_t *dead;
|
||||
sem_t *hold;
|
||||
sem_t *print;
|
||||
} t_philo;
|
||||
|
||||
typedef struct s_strct
|
||||
{
|
||||
sem_t *forks;
|
||||
t_philo philo[512];
|
||||
int pid[512];
|
||||
int philos;
|
||||
long long dietime;
|
||||
long long eattime;
|
||||
long long sleeptime;
|
||||
long long strtt;
|
||||
int target;
|
||||
sem_t *done;
|
||||
sem_t *dead;
|
||||
sem_t *hold;
|
||||
sem_t *print;
|
||||
char *error;
|
||||
} t_strct;
|
||||
|
||||
t_strct *ft_parseandvalidateinput(int argc, char **argv);
|
||||
int ft_initstructandmutex(t_strct *strct, int i);
|
||||
int ft_startcycle(t_strct *strct);
|
||||
void ft_cycle(void *pointer);
|
||||
int ft_releasetheminds(t_strct *strct);
|
||||
int ft_cyclecounter(t_strct *strct);
|
||||
int ft_waitingfordeath(t_strct *strct);
|
||||
int ft_cleanup(t_strct *strct);
|
||||
long long ft_time(void);
|
||||
int philo_atoi(char *str);
|
||||
int ft_printreturn(char *reason, int code);
|
||||
int ft_charactercheck(int argc, char **argv);
|
||||
void ft_safeprint(t_philo *ps, char *str);
|
||||
|
||||
#endif
|
111
philo_bonus/src/init.c
Normal file
111
philo_bonus/src/init.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* init.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/15 02:00:19 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 08:55:41 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_charactercheck(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = 1;
|
||||
j = 0;
|
||||
while (i < argc)
|
||||
{
|
||||
while (argv[i][j] != '\0')
|
||||
{
|
||||
if (argv[i][j] < '0' || argv[i][j] > '9')
|
||||
return (1);
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
j = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_strct *ft_parseandvalidateinput(int argc, char **argv)
|
||||
{
|
||||
t_strct *strct;
|
||||
|
||||
strct = malloc(sizeof(t_strct));
|
||||
strct->error = NULL;
|
||||
if (ft_charactercheck(argc, argv))
|
||||
strct->error = "input can only be numbers";
|
||||
strct->philos = philo_atoi(argv[1]);
|
||||
if (strct->philos < 1 || strct->philos > 500)
|
||||
strct->error = "Min 1 and Max 500 philosophers";
|
||||
strct->dietime = philo_atoi(argv[2]);
|
||||
if (strct->dietime < 50)
|
||||
strct->error = "die time must be a minimum of 50ms";
|
||||
strct->eattime = philo_atoi(argv[3]);
|
||||
if (strct->eattime < 50)
|
||||
strct->error = "eat time must be a minimum of 50ms";
|
||||
strct->sleeptime = philo_atoi(argv[4]);
|
||||
if (strct->sleeptime < 50)
|
||||
strct->error = "sleeptime must be a minimum of 50ms";
|
||||
if (argc == 6)
|
||||
strct->target = philo_atoi(argv[5]);
|
||||
else
|
||||
strct->target = 1000000000;
|
||||
if (strct->target < 0)
|
||||
strct->error = "We can't do negative cycles";
|
||||
return (strct);
|
||||
}
|
||||
|
||||
int ft_initstructandmutex(t_strct *strct, int i)
|
||||
{
|
||||
strct->dead = sem_open("dead", O_CREAT, 0666, 0);
|
||||
strct->done = sem_open("done", O_CREAT, 0666, 0);
|
||||
strct->hold = sem_open("hold", O_CREAT, 0666, 0);
|
||||
strct->print = sem_open("print", O_CREAT, 0666, 1);
|
||||
strct->forks = sem_open("forks", O_CREAT, 0666, strct->philos);
|
||||
while (i <= strct->philos)
|
||||
{
|
||||
strct->philo[i].id = i + 1;
|
||||
strct->philo[i].cycles = 0;
|
||||
strct->philo[i].dietime = &strct->dietime;
|
||||
strct->philo[i].eattime = &strct->eattime;
|
||||
strct->philo[i].sleeptime = &strct->sleeptime;
|
||||
strct->philo[i].strtt = &strct->strtt;
|
||||
strct->philo[i].philos = &strct->philos;
|
||||
strct->philo[i].target = &strct->target;
|
||||
strct->philo[i].forks = strct->forks;
|
||||
strct->philo[i].done = strct->done;
|
||||
strct->philo[i].dead = strct->dead;
|
||||
strct->philo[i].hold = strct->hold;
|
||||
strct->philo[i].print = strct->print;
|
||||
strct->philo[i].pid = strct->pid;
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ft_releasetheminds(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < strct->philos)
|
||||
{
|
||||
sem_post(strct->hold);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ft_safeprint(t_philo *ps, char *str)
|
||||
{
|
||||
sem_wait(ps->print);
|
||||
printf("%lld %d %s\n", ft_time() - *ps->strtt, ps->id, str);
|
||||
sem_post(ps->print);
|
||||
}
|
148
philo_bonus/src/philo.c
Normal file
148
philo_bonus/src/philo.c
Normal file
@ -0,0 +1,148 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* philo.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/11 06:42:31 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 09:24:42 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_eatsleepthink(t_philo *ps)
|
||||
{
|
||||
sem_wait(ps->forks);
|
||||
if (ft_time() - ps->lastfood > *ps->dietime)
|
||||
return (1);
|
||||
ft_safeprint(ps, "has taken a fork");
|
||||
if (*ps->philos == 1)
|
||||
return (1);
|
||||
sem_wait(ps->forks);
|
||||
ft_safeprint(ps, "has taken a fork");
|
||||
ps->lastfood = ft_time();
|
||||
ft_safeprint(ps, "is eating");
|
||||
usleep(*ps->eattime * 1000);
|
||||
sem_post(ps->forks);
|
||||
sem_post(ps->forks);
|
||||
if (ft_time() - ps->lastfood > *ps->dietime)
|
||||
return (1);
|
||||
ft_safeprint(ps, "is sleeping");
|
||||
usleep(*ps->sleeptime * 1000);
|
||||
if (ft_time() - ps->lastfood > *ps->dietime)
|
||||
return (1);
|
||||
ft_safeprint(ps, "is thinking");
|
||||
ps->cycles++;
|
||||
if (ps->cycles == *ps->target)
|
||||
return (2);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ft_cycle(void *pointer)
|
||||
{
|
||||
t_philo *philo;
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
philo = pointer;
|
||||
philo->hold = sem_open("hold", 0);
|
||||
sem_wait(philo->hold);
|
||||
philo->dead = sem_open("dead", 0);
|
||||
philo->done = sem_open("done", 0);
|
||||
if ((philo->id - 1) % 2)
|
||||
usleep(*philo->eattime * 1000);
|
||||
while (!ret)
|
||||
ret = ft_eatsleepthink(philo);
|
||||
if (ret == 1)
|
||||
{
|
||||
printf("%lld %d died\n", ft_time() - *philo->strtt, philo->id);
|
||||
sem_post(philo->dead);
|
||||
}
|
||||
if (ret == 2)
|
||||
sem_post(philo->done);
|
||||
}
|
||||
|
||||
int ft_startcycle(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
strct->strtt = ft_time();
|
||||
while (i < strct->philos)
|
||||
{
|
||||
strct->philo[i].lastfood = ft_time();
|
||||
strct->pid[i] = fork();
|
||||
if (strct->pid[i] == 0)
|
||||
{
|
||||
ft_cycle(&strct->philo[i]);
|
||||
sem_close(strct->dead);
|
||||
sem_close(strct->done);
|
||||
sem_close(strct->hold);
|
||||
sem_close(strct->forks);
|
||||
sem_close(strct->print);
|
||||
free(strct);
|
||||
exit(0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ft_cyclecounter(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
sem_t *done;
|
||||
int philos;
|
||||
int target;
|
||||
|
||||
philos = strct->philos;
|
||||
target = strct->target;
|
||||
sem_close(strct->dead);
|
||||
sem_close(strct->done);
|
||||
sem_close(strct->hold);
|
||||
sem_close(strct->forks);
|
||||
sem_close(strct->print);
|
||||
free(strct);
|
||||
done = sem_open("done", 0);
|
||||
i = 0;
|
||||
while (i < philos)
|
||||
{
|
||||
sem_wait(done);
|
||||
i++;
|
||||
}
|
||||
printf("All %d philosophers have", philos);
|
||||
printf(" finished all %d cycles\n", target);
|
||||
sem_close(done);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
t_strct *strct;
|
||||
int i;
|
||||
|
||||
if (argc < 5 || argc > 6)
|
||||
return (ft_printreturn("Wrong number of arguments", 1));
|
||||
strct = ft_parseandvalidateinput(argc, argv);
|
||||
if (strct->error)
|
||||
{
|
||||
ft_printreturn(strct->error, 0);
|
||||
free(strct);
|
||||
return (1);
|
||||
}
|
||||
i = ft_initstructandmutex(strct, 0);
|
||||
ft_startcycle(strct);
|
||||
strct->pid[501] = fork();
|
||||
if (strct->pid[501] == 0)
|
||||
ft_waitingfordeath(strct);
|
||||
strct->pid[502] = fork();
|
||||
if (strct->pid[502] == 0)
|
||||
ft_cyclecounter(strct);
|
||||
ft_releasetheminds(strct);
|
||||
while (i != strct->pid[501] && i != strct->pid[502])
|
||||
i = waitpid(-1, NULL, 0);
|
||||
ft_cleanup(strct);
|
||||
return (0);
|
||||
}
|
99
philo_bonus/src/util.c
Normal file
99
philo_bonus/src/util.c
Normal file
@ -0,0 +1,99 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* .--. _ */
|
||||
/* util.c |o_o || | */
|
||||
/* |:_/ || |_ _ ___ __ */
|
||||
/* By: houtworm <codam@houtworm.net> // \ \ __| | | \ \/ / */
|
||||
/* (| | )|_| |_| |> < */
|
||||
/* Created: 2023/03/15 02:01:41 by houtworm /'\_ _/`\__|\__,_/_/\_\ */
|
||||
/* Updated: 2023/05/14 09:13:53 by djonker \___)=(___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../philo.h"
|
||||
|
||||
int ft_printreturn(char *reason, int code)
|
||||
{
|
||||
printf("%s\n", reason);
|
||||
return (code);
|
||||
}
|
||||
|
||||
long long ft_time(void)
|
||||
{
|
||||
struct timeval t;
|
||||
long long r;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
r = (t.tv_sec * 1000) + (t.tv_usec / 1000);
|
||||
return (r);
|
||||
}
|
||||
|
||||
int ft_waitingfordeath(t_strct *strct)
|
||||
{
|
||||
sem_t *dead;
|
||||
|
||||
sem_close(strct->dead);
|
||||
sem_close(strct->done);
|
||||
sem_close(strct->hold);
|
||||
sem_close(strct->forks);
|
||||
sem_close(strct->print);
|
||||
free(strct);
|
||||
dead = sem_open("dead", 0);
|
||||
sem_wait(dead);
|
||||
sem_close(dead);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int philo_atoi(char *str)
|
||||
{
|
||||
unsigned int r;
|
||||
int c;
|
||||
int n;
|
||||
|
||||
r = 0;
|
||||
c = 0;
|
||||
n = 1;
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
while ((str[c] == 32) || (str[c] > 8 && str[c] < 14))
|
||||
c++;
|
||||
if (str[c] == '-' || str[c] == '+')
|
||||
if (str[c++] == '-')
|
||||
n = -1;
|
||||
while (str[c] >= '0' && str[c] <= '9')
|
||||
{
|
||||
r = 10 * r + (str[c] - '0');
|
||||
if (r > 2147483647 && n == 1)
|
||||
return (-1);
|
||||
else if (r > 2147483648 && n == -1)
|
||||
return (0);
|
||||
c++;
|
||||
}
|
||||
return (n * r);
|
||||
}
|
||||
|
||||
int ft_cleanup(t_strct *strct)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
kill(strct->pid[501], 15);
|
||||
kill(strct->pid[502], 15);
|
||||
while (i < strct->philos)
|
||||
{
|
||||
kill(strct->pid[i], 15);
|
||||
i++;
|
||||
}
|
||||
sem_close(strct->dead);
|
||||
sem_close(strct->done);
|
||||
sem_close(strct->hold);
|
||||
sem_close(strct->forks);
|
||||
sem_close(strct->print);
|
||||
sem_unlink("dead");
|
||||
sem_unlink("done");
|
||||
sem_unlink("hold");
|
||||
sem_unlink("forks");
|
||||
sem_unlink("print");
|
||||
free(strct);
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user