Add lock to the philos' state trunk
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 22 Mar 2024 08:46:28 +0000 (09:46 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 22 Mar 2024 08:46:28 +0000 (09:46 +0100)
This should prevent data races between any philo thread
and the main thread checking their status.

philo/check_death.c
philo/init.c
philo/main.c
philo/philo.h
philo/philos.c

index 9cca50a24211acf78bb2073ab3ff4b3e8deca122..e22752078ca9265ebf4c9f998eb368c076862df0 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 15:53:52 by ljiriste          #+#    #+#             */
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 15:53:52 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/22 09:22:19 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/22 09:44:44 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -23,11 +23,13 @@ static int  philo_died(t_philo *philo, t_settings *set)
        suseconds_t     now;
 
        i = 0;
        suseconds_t     now;
 
        i = 0;
-       now = cur_time_sus();
        while (i < set->philo_count)
        {
        while (i < set->philo_count)
        {
+               pthread_mutex_lock(&philo->state_lock);
+               now = cur_time_sus();
                if ((now - philo->last_eaten) > set->time_to_die)
                {
                if ((now - philo->last_eaten) > set->time_to_die)
                {
+                       pthread_mutex_unlock(&philo->state_lock);
                        pthread_mutex_lock(&set->terminal);
                        printf("%li %lu %s\n", (cur_time_sus() - set->program_start)
                                / 1000, i + 1, G_DIE_STR);
                        pthread_mutex_lock(&set->terminal);
                        printf("%li %lu %s\n", (cur_time_sus() - set->program_start)
                                / 1000, i + 1, G_DIE_STR);
@@ -35,6 +37,7 @@ static int    philo_died(t_philo *philo, t_settings *set)
                        pthread_mutex_unlock(&set->terminal);
                        return (1);
                }
                        pthread_mutex_unlock(&set->terminal);
                        return (1);
                }
+               pthread_mutex_unlock(&philo->state_lock);
                ++i;
        }
        return (0);
                ++i;
        }
        return (0);
@@ -49,8 +52,13 @@ static int   all_full(t_philo *philos, t_settings *set)
                return (0);
        while (i < set->philo_count)
        {
                return (0);
        while (i < set->philo_count)
        {
+               pthread_mutex_lock(&philos[i].state_lock);
                if (philos[i].times_eaten < set->min_eats_num)
                if (philos[i].times_eaten < set->min_eats_num)
+               {
+                       pthread_mutex_unlock(&philos[i].state_lock);
                        return (0);
                        return (0);
+               }
+               pthread_mutex_unlock(&philos[i].state_lock);
                ++i;
        }
        return (1);
                ++i;
        }
        return (1);
@@ -65,8 +73,10 @@ static suseconds_t   time_to_starve(t_philo *philos, t_settings *set)
        i = 1;
        while (i < set->philo_count)
        {
        i = 1;
        while (i < set->philo_count)
        {
+               pthread_mutex_lock(&philos[i].state_lock);
                if (furthest_eaten > philos[i].last_eaten)
                        furthest_eaten = philos[i].last_eaten;
                if (furthest_eaten > philos[i].last_eaten)
                        furthest_eaten = philos[i].last_eaten;
+               pthread_mutex_unlock(&philos[i].state_lock);
                ++i;
        }
        return (set->time_to_die - (cur_time_sus() - furthest_eaten));
                ++i;
        }
        return (set->time_to_die - (cur_time_sus() - furthest_eaten));
index e6bc43fd421f81eebcf23600e627f5f3e3d7dba2..25dd6e25a26758e7059828aef989671b9b16964f 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 15:48:58 by ljiriste          #+#    #+#             */
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 15:48:58 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/21 10:04:35 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/22 09:39:54 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -55,6 +55,7 @@ t_philo       *build_philos(pthread_mutex_t *forks, t_settings *set)
                philos[count].times_eaten = 0;
                philos[count].settings = set;
                philos[count].forks[0] = forks + count - count % 2;
                philos[count].times_eaten = 0;
                philos[count].settings = set;
                philos[count].forks[0] = forks + count - count % 2;
+               pthread_mutex_init(&philos[count].state_lock, NULL);
                if (count > 0)
                        philos[count].forks[1] = forks + count - (count + 1) % 2;
        }
                if (count > 0)
                        philos[count].forks[1] = forks + count - (count + 1) % 2;
        }
index c09afbf3a19cf5148f65d5a1080d52476af5544f..13257cec6f36410e31b0b5f302bf10b580395fb2 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/05 12:49:40 by ljiriste          #+#    #+#             */
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/05 12:49:40 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/21 10:26:01 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/22 09:41:43 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -31,6 +31,7 @@ static void   cleanup(pthread_mutex_t *forks, t_philo *philos, pthread_t *threads,
        {
                --count;
                pthread_mutex_destroy(&forks[count]);
        {
                --count;
                pthread_mutex_destroy(&forks[count]);
+               pthread_mutex_destroy(&philos[count].state_lock);
                pthread_join(threads[count], NULL);
        }
        pthread_mutex_destroy(&set->terminal);
                pthread_join(threads[count], NULL);
        }
        pthread_mutex_destroy(&set->terminal);
index f7c99cd5d0bd1011b3053c20931d1c3395707d18..412ea52482416e7f6376e1657d288598c177c370 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 14:25:18 by ljiriste          #+#    #+#             */
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/19 14:25:18 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/21 10:16:40 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/22 09:40:43 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -39,6 +39,7 @@ const char    *g_die_str = "died";
 
 //     unsigned long would be more apropriate for min_eats_num
 //     but for the ease of parsing I'm using size_t (they are the same)
 
 //     unsigned long would be more apropriate for min_eats_num
 //     but for the ease of parsing I'm using size_t (they are the same)
+//     terminal mutex is also used to lock the end member
 typedef struct s_settings
 {
        int                             end;
 typedef struct s_settings
 {
        int                             end;
@@ -56,6 +57,7 @@ typedef struct s_philo
        size_t                  times_eaten;
        size_t                  id;
        suseconds_t             last_eaten;
        size_t                  times_eaten;
        size_t                  id;
        suseconds_t             last_eaten;
+       pthread_mutex_t state_lock;
        pthread_mutex_t *forks[2];
        t_settings              *settings;
 }                                      t_philo;
        pthread_mutex_t *forks[2];
        t_settings              *settings;
 }                                      t_philo;
index 316ec5e541e2630ac2194395a360d9d63f49eed7..a3341386b5423ed48ba76699a0242a283c85fcb7 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/21 09:16:23 by ljiriste          #+#    #+#             */
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/21 09:16:23 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/03/21 10:26:14 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/03/22 09:42:20 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -34,9 +34,11 @@ void philo_eat(t_philo *philo)
        pthread_mutex_lock(philo->forks[1]);
        thread_print(philo->settings, philo->id, G_FORK_STR);
        thread_print(philo->settings, philo->id, G_EAT_STR);
        pthread_mutex_lock(philo->forks[1]);
        thread_print(philo->settings, philo->id, G_FORK_STR);
        thread_print(philo->settings, philo->id, G_EAT_STR);
+       pthread_mutex_lock(&philo->state_lock);
        philo->last_eaten = cur_time_sus();
        philo->last_eaten = cur_time_sus();
-       usleep(philo->settings->time_to_eat);
        ++philo->times_eaten;
        ++philo->times_eaten;
+       pthread_mutex_unlock(&philo->state_lock);
+       usleep(philo->settings->time_to_eat);
        pthread_mutex_unlock(philo->forks[0]);
        pthread_mutex_unlock(philo->forks[1]);
        return ;
        pthread_mutex_unlock(philo->forks[0]);
        pthread_mutex_unlock(philo->forks[1]);
        return ;