/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* threads.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/08 20:08:33 by erey-bet #+# #+# */ /* Updated: 2023/03/13 18:33:50 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" long get_usec(long long time) { return (time % 1000000); } void *philosopher(t_philo *philo) { long long *time; long long last_eat_time; int id; int next_id; time = philo->same->time; id = *philo->only->id; next_id = (*philo->only->id + 1) % philo->same->config->nbr_philo; while (*time <= 0) ; usleep((*philo->only->id % 2)); last_eat_time = *time; while (1) { printf("%ld %d is thinking\n" , get_usec(*time), id); if (!*philo->same->death && !pthread_mutex_lock(&philo->same->mutex[id])) { // printf("%ld %d is taking %d fork\n" , get_usec(*time), id, id); if (!*philo->same->death && !pthread_mutex_lock(&philo->same->mutex[next_id])) { //printf("%ld %d is taking %d fork\n" , get_usec(*time), id, next_id); printf("%ld %d is eating\n" , get_usec(*time), id); last_eat_time = *time; if (*time - last_eat_time + philo->same->config->time_eat >= philo->same->config->time_die || *philo->same->death) { printf("%lld | %d dieing 1\n",*time - last_eat_time, id); break; } else usleep(philo->same->config->time_eat); printf("after eat last_eat_time: %lld\n" , *time - last_eat_time); pthread_mutex_unlock(&philo->same->mutex[next_id]); pthread_mutex_unlock(&philo->same->mutex[id]); printf("%ld %d is sleeping\n" , get_usec(*time), id); if (*time - last_eat_time + philo->same->config->time_sleep >= philo->same->config->time_die || *philo->same->death) { printf("%lld | %d dieing 2\n",*time - last_eat_time, id); break; } else usleep(philo->same->config->time_sleep); printf("after sleep last_eat_time: %lld\n" , *time - last_eat_time); } else pthread_mutex_unlock(&philo->same->mutex[id]); } if (*time - last_eat_time >= philo->same->config->time_die || *philo->same->death) { printf("%lld | %d dieing 3\n",*time - last_eat_time, id); break; } } if (!*philo->same->death) { *philo->same->death = 1; printf("%ld %d died\n" , get_usec(*time), id); } //else //printf("%ld %d stop\n" , get_usec(*time), id); return (NULL); } void init_mutex(pthread_mutex_t *mutex, int nbr) { int i; i = -1; while (++i < nbr) pthread_mutex_init(&mutex[i], NULL); } void destroy_mutex(pthread_mutex_t *mutex, int nbr) { int i; i = -1; while (++i < nbr) pthread_mutex_destroy(&mutex[i]); } long long get_time() { struct timeval time; long long new_time; gettimeofday(&time, NULL); new_time = time.tv_sec * 1000000; new_time += time.tv_usec; return (new_time); } void *timer(t_philo *timer) { *timer->same->time = get_time(); while (!*timer->same->death) *timer->same->time = get_time(); return (NULL); } t_same *create_struct_same(t_config *config) { t_same *same; pthread_mutex_t *mutex; long long *time; int *death; same = ft_calloc(sizeof(t_same), 1); time = ft_calloc(sizeof(long long), 1); mutex = ft_calloc(sizeof(pthread_mutex_t), config->nbr_philo + 1); init_mutex(mutex, config->nbr_philo + 1); same->config = config; same->mutex = mutex; same->time = time; death = ft_calloc(sizeof(int), 1); *death = 0; same->death = death; return (same); } t_only *create_struct_only(int id) { t_only *only; int *id_alloc; only = ft_calloc(sizeof(t_only), 1); id_alloc = ft_calloc(sizeof(int), 1); *id_alloc = id; only->id = id_alloc; return (only); } t_philo *init_philo(t_same *same, t_only *only) { t_philo *philo; philo = ft_calloc(sizeof(t_philo), 1); philo->same = same; philo->only = only; return (philo); } int manage_threads(t_config *config) { pthread_t *threads; t_same *same; int i; threads = ft_calloc(config->nbr_philo + 1, sizeof(pthread_t)); if (threads == NULL) return (1); same = create_struct_same(config); pthread_create(&threads[0], NULL, (void *)&timer, init_philo(same, create_struct_only(-1))); i = -1; while (++i < config->nbr_philo) { if (pthread_create(&threads[i + 1], NULL, (void *)&philosopher, init_philo(same, create_struct_only(i))) != 0) { write(2, "Error thread creation\n", 21); return (1); } } while (--i > -1) { if (pthread_join(threads[i], NULL) != 0) { write(2, "Error thread finish\n", 20); return (1); } } destroy_mutex(same->mutex, 3); return (0); }