/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* threads.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/08 20:08:33 by erey-bet #+# #+# */ /* Updated: 2023/03/28 00:42:38 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "philo.h" long get_usec(long long time) { return (time % 1000000); } long long get_utime() { struct timeval time; gettimeofday(&time, NULL); return (time.tv_sec * 1000000 + time.tv_usec); } long long get_mstime() { struct timeval time; gettimeofday(&time, NULL); return (time.tv_usec / 1000); } long long get_time() { struct timeval time; gettimeofday(&time, NULL); return (time.tv_sec * 1000 + time.tv_usec / 1000); } void message(long long time, int id, char *msg) { char send[1024]; int i; i = ft_itoa_bozo(send, (get_utime() - time) / 1000 ); send[i++] = ' '; i += ft_itoa_bozo(send + i, id + 1); send[i++] = ' '; while (*msg) send[i++] = *msg++; write(1, send, i); } void *philosopher(t_philo *philo) { long long time; long long last_eat_time; int id; int next_id; id = *philo->only->id; next_id = (*philo->only->id + 1) % philo->same->config->nbr_philo; time = get_utime(); last_eat_time = time; if (id % 2 == 1 || (philo->same->config->nbr_philo % 2 == 1 && id == philo->same->config->nbr_philo - 1)) { message(time, id, "is thinking\n"); usleep(philo->same->config->time_eat); } while (get_utime() - last_eat_time < philo->same->config->time_die && !*philo->same->death) { if (!*philo->same->death && !pthread_mutex_lock(&philo->same->mutex[id])) { // message(time, id, "is taking %d fork\n"); if (!*philo->same->death && !pthread_mutex_lock(&philo->same->mutex[next_id])) { //message(time, id, "is taking %d fork\n"); message(time, id, "is eating\n"); if (get_utime() - last_eat_time + philo->same->config->time_eat >= philo->same->config->time_die || *philo->same->death) { message(time, id, "dieing 1\n"); break ; } else usleep(philo->same->config->time_eat); last_eat_time = get_utime(); pthread_mutex_unlock(&philo->same->mutex[next_id]); pthread_mutex_unlock(&philo->same->mutex[id]); message(time, id, "is sleeping\n"); if (get_utime() - last_eat_time + philo->same->config->time_sleep >= philo->same->config->time_die || *philo->same->death) { message(time, id, "dieing 2\n"); break ; } else usleep(philo->same->config->time_sleep); } else pthread_mutex_unlock(&philo->same->mutex[id]); } message(time, id, "is thinking\n"); } if (!*philo->same->death) { *philo->same->death = 1; message(time, id, "died\n"); } //else //message(time, id, " stop\n"); 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]); } 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; only = ft_calloc(sizeof(t_only), 1); only->id = id; only->eat = 0; 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) { /*(void)config; long long time = get_utime(); message(time, 0, "frghjuikfgvbjhnkiugtfgv\n"); ft_putnbr_fd(get_utime() - time, 1); write(1, "\n", 1);*/ 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); 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); }