From 154c6c6cc5c35746b186fd815cd27280ea5d64ba Mon Sep 17 00:00:00 2001 From: higrub89 Date: Tue, 22 Sep 2026 17:33:06 +0200 Subject: [PATCH] feat: elevate philosophers architecture, add CI concurrency pipeline, MIT license and documentation --- .github/workflows/ci.yml | 65 ++++++++++ .gitignore | 22 ++++ .vscode/settings.json | 6 - LICENSE | 21 ++++ Makefile | 68 +++------- README.md | 207 +++++++++++++++---------------- inc/philo.h | 94 -------------- obj/actions.o | Bin 9016 -> 0 bytes obj/init.o | Bin 9432 -> 0 bytes obj/main.o | Bin 8136 -> 0 bytes obj/monitor.o | Bin 8216 -> 0 bytes obj/parser.o | Bin 8400 -> 0 bytes obj/simulation.o | Bin 9360 -> 0 bytes obj/time.o | Bin 8400 -> 0 bytes obj/utils.o | Bin 9016 -> 0 bytes philo | Bin 38672 -> 0 bytes philo/Makefile | 68 ++++++++++ {philo_42 => philo}/actions.c | 0 {philo_42 => philo}/init.c | 0 {philo_42 => philo}/main.c | 0 {philo_42 => philo}/monitor.c | 0 {philo_42 => philo}/parser.c | 0 {philo_42 => philo}/philo.h | 0 {philo_42 => philo}/simulation.c | 0 {philo_42 => philo}/time.c | 0 {philo_42 => philo}/utils.c | 7 +- philo_42/.vscode/extensions.json | 5 - philo_42/Makefile | 68 ---------- srcs/actions.c | 88 ------------- srcs/init.c | 63 ---------- srcs/main.c | 70 ----------- srcs/monitor.c | 126 ------------------- srcs/parser.c | 73 ----------- srcs/simulation.c | 103 --------------- srcs/time.c | 49 -------- srcs/utils.c | 90 -------------- 36 files changed, 297 insertions(+), 996 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore delete mode 100644 .vscode/settings.json create mode 100644 LICENSE delete mode 100644 inc/philo.h delete mode 100644 obj/actions.o delete mode 100644 obj/init.o delete mode 100644 obj/main.o delete mode 100644 obj/monitor.o delete mode 100644 obj/parser.o delete mode 100644 obj/simulation.o delete mode 100644 obj/time.o delete mode 100644 obj/utils.o delete mode 100755 philo create mode 100644 philo/Makefile rename {philo_42 => philo}/actions.c (100%) rename {philo_42 => philo}/init.c (100%) rename {philo_42 => philo}/main.c (100%) rename {philo_42 => philo}/monitor.c (100%) rename {philo_42 => philo}/parser.c (100%) rename {philo_42 => philo}/philo.h (100%) rename {philo_42 => philo}/simulation.c (100%) rename {philo_42 => philo}/time.c (100%) rename {philo_42 => philo}/utils.c (94%) delete mode 100644 philo_42/.vscode/extensions.json delete mode 100644 philo_42/Makefile delete mode 100644 srcs/actions.c delete mode 100644 srcs/init.c delete mode 100644 srcs/main.c delete mode 100644 srcs/monitor.c delete mode 100644 srcs/parser.c delete mode 100644 srcs/simulation.c delete mode 100644 srcs/time.c delete mode 100644 srcs/utils.c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3c3cecd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +name: Concurrency & Rigor CI Pipeline + +on: + push: + branches: [ master, main ] + pull_request: + branches: [ master, main ] + workflow_dispatch: + +jobs: + build-and-concurrency-check: + name: Build & Concurrency Audit (${{ matrix.compiler }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + compiler: [gcc, clang] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential clang valgrind + + - name: Verify compilation and Makefile targets + run: | + make clean + make all CC=${{ matrix.compiler }} + make fclean + make re CC=${{ matrix.compiler }} + + - name: Concurrency Test — ThreadSanitizer (TSan Data-Race Audit) + run: | + make tsan CC=${{ matrix.compiler }} + echo "=== TSan Test 1: Single Philosopher (Must die at ~400ms) ===" + ./philo/philo 1 400 200 200 + + echo "=== TSan Test 2: 4 Philosophers eating 5 times (Zero Data Races) ===" + ./philo/philo 4 410 200 200 5 + + - name: Concurrency Test — Helgrind (Deadlock & Lock Order Audit) + run: | + make re CC=${{ matrix.compiler }} + echo "=== Helgrind Test: Lock contention and deadlock audit ===" + valgrind --tool=helgrind --error-exitcode=42 ./philo/philo 4 410 200 200 2 + valgrind --tool=helgrind --error-exitcode=42 ./philo/philo 1 400 200 200 + + - name: Memory Test — Valgrind Memcheck (Zero Leaks Audit) + run: | + valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=42 ./philo/philo 4 410 200 200 3 + valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=42 ./philo/philo 1 400 200 200 + + - name: Functional & Timing Verification + run: | + echo "=== Functional Test: Meal counting ===" + MEALS=$(./philo/philo 4 410 200 200 7 | grep -c "is eating") + echo "Total meals recorded: $MEALS" + if [ "$MEALS" -lt 28 ]; then + echo "Expected at least 28 meals, got $MEALS" + exit 1 + fi + echo "All verification checks passed with 100% success!" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cde8e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Object and dependency files +*.o +*.d +obj/ +philo/obj/ + +# Executables +philo/philo +/philo +philo_tsan +philo/philo_tsan + +# Logs and test outputs +*.log +log_* +errors_log +.vscode/ +philo/.vscode/ + +# OS and temporary files +.DS_Store +*~ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index cf4d130..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "42header.email": "rhiguita@student.42madrid.com", - "42header.username": "rhiguita", - "notebook.defaultFormatter": "keyhr.42-c-format", - "editor.defaultFormatter": "keyhr.42-c-format" -} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d3fdebb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ruben Higuita + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 40ba74b..b2a389b 100644 --- a/Makefile +++ b/Makefile @@ -6,65 +6,31 @@ # By: rhiguita &1 | lolcat +fclean: + @$(MAKE) -C $(SUBDIR) fclean -# Compile object files from source files -$(OBJ_DIR)%.o: $(SRC_DIR)%.c - @mkdir -p $(@D) - @echo "compiling $<" | lolcat - @$(CC) $(CFLAGS) $(INC) -c $< -o $@ 2>&1 | lolcat +re: + @$(MAKE) -C $(SUBDIR) re -clean: - @$(RM) -r $(OBJ_DIR) - @echo "Delete files objets" | lolcat +tsan: + @$(MAKE) -C $(SUBDIR) tsan -fclean: clean - @$(RM) $(NAME) - @$(RM) - @echo "Delete all files" | lolcat +debug: + @$(MAKE) -C $(SUBDIR) debug -re: fclean all - @echo "Finsh Recompiling" | lolcat +test: all + @./tester/tester.sh . -# Phony targets represent actions not files -.PHONY: start all clean fclean re +.PHONY: all clean fclean re tsan debug test diff --git a/README.md b/README.md index 679815b..f5772e3 100644 --- a/README.md +++ b/README.md @@ -1,147 +1,140 @@ -# Philosophers -This project implements the classic solution to the **Dining Philosophers Problem**, where five philosophers sit at a round table. Each philosopher needs two forks (in this case called chopsticks) to eat a plate of spaghetti, and there is one shared chopstick between each pair of plates. Philosophers alternate between **thinking** and **eating**. When they feel hungry, they try to pick up the chopstick on their left, followed by the one on their right. If they manage to pick up both chopsticks, they eat for a short period, then put the chopsticks down and return to thinking. - - - -# The Project -
- image -
-There are two implementations in this project: - -- **philo**: uses threads and mutexes for shared resource synchronization. -- **philo_bonus**: uses processes and semaphores to manage shared resources. - -Each implementation is located in a separate directory: `philo/` for the version with threads and mutexes, and `philo_bonus/` for the version with processes and semaphores. - - - -## Description of Each Version - -### philo (Threads and Mutexes) - -In this version, each philosopher is a thread, and each chopstick is represented by a mutex. Mutexes help prevent race conditions by blocking access to shared resources. - - - -### Usage: - -```bash -$> make -$> ./philo number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat] - +# Philosophers — Concurrent Resource Synchronization in C + +[![CI Pipeline](https://github.com/higrub89/Philosophers/actions/workflows/ci.yml/badge.svg)](https://github.com/higrub89/Philosophers/actions/workflows/ci.yml) +[![Language](https://img.shields.io/badge/Language-C99-blue.svg)](https://en.wikipedia.org/wiki/C99) +[![Concurrency](https://img.shields.io/badge/Concurrency-POSIX%20Threads-orange.svg)](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html) +[![TSan](https://img.shields.io/badge/ThreadSanitizer-Data--Race%20Free-brightgreen.svg)](https://clang.llvm.org/docs/ThreadSanitizer.html) +[![Helgrind](https://img.shields.io/badge/Helgrind-0%20Deadlocks-brightgreen.svg)](https://valgrind.org/docs/manual/hg-manual.html) +[![Memory](https://img.shields.io/badge/Valgrind-0%20leaks%20%7C%200%20errors-brightgreen.svg)](https://valgrind.org/) +[![42 School](https://img.shields.io/badge/42_Madrid-Common_Core-purple.svg)](https://www.42madrid.com/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) + +## Overview + +**Philosophers** is a multithreaded systems programming project from the 42 School curriculum addressing Edsger Dijkstra’s classic **Dining Philosophers Problem**. + +The challenge requires orchestrating concurrent threads competing for shared, exclusive resources (forks) under microsecond-level timing constraints, with strict guarantees against **deadlocks**, **starvation**, and **data races**. + +--- + +## Concurrency Architecture & State Machine + +```mermaid +flowchart TD + subgraph Initialization["Setup & Thread Dispatch"] + Main["main() Parse Args & Mutex Init"] --> Monitor["Monitor Thread (Death & Meal Polling)"] + Main --> Philos["Philosopher Threads (N workers)"] + end + + subgraph PhiloFSM["Philosopher Lifecycle"] + T["Thinking"] -->|Hungry| F1["Lock First Fork"] + F1 --> F2["Lock Second Fork (Even/Odd Arbitration)"] + F2 --> E["Eating (Updates last_meal_time & meal_count)"] + E -->|time_to_eat elapsed| R["Unlock Both Forks"] + R --> S["Sleeping (time_to_sleep elapsed)"] + S --> T + end + + subgraph Supervisor["Safety & Termination"] + Monitor -->|now - last_meal_time > time_to_die| D["Signal Death & Terminate Simulation"] + Monitor -->|All philosophers reached meals_required| M["Signal Full Meals & Clean Exit"] + end ``` -- **number_of_philosophers**: number of philosophers (and chopsticks). -- **time_to_die**: time in milliseconds a philosopher can go without eating before they die. -- **time_to_eat**: time in milliseconds a philosopher spends eating. -- **time_to_sleep**: time in milliseconds a philosopher spends sleeping after eating. -- **number_of_times_each_philosopher_must_eat** (optional): number of times each philosopher must eat before the program exits. +--- -### Example Execution: +## Concurrency Invariants & Guarantees -```bash -$> ./philo 4 500 200 200 -``` +1. **Deadlock Prevention (Resource Hierarchy & Even/Odd Scheduling)**: + - To break Dijkstra's circular wait condition (*Coffman condition 4*), odd and even philosophers stagger their initial acquisition order and timing, preventing all philosophers from simultaneously picking up their left fork. +2. **Deterministic Mutex Protection**: + - Every read and write to shared state (`last_meal_time`, `meals_eaten`, `simulation_should_end`) is strictly guarded by dedicated mutexes (`sim_mutex`, `write_mutex`). +3. **Microsecond Precision & Non-Drifting Sleep**: + - Rather than relying on inaccurate OS `usleep()` calls which can overshoot by milliseconds, intervals are governed by an active high-resolution polling loop (`gettimeofday`) checking timestamp thresholds in small slices. +4. **Single Philosopher Edge-Case**: + - Handled gracefully: A single philosopher picks up the single available fork, waits until starvation (`time_to_die`), prints the death event, and exits cleanly without hanging. -### philo_bonus (Processes and Semaphores) +--- -In this version, each philosopher is a process, and each chopstick is managed by a semaphore. **Shared memory** and **signals** coordinate between processes and ensure each process can access the resources it needs. +## Build & Usage -### Usage: +The project follows 42 School's compilation rules (`-Wall -Wextra -Werror -pthread`): ```bash -$> make bonus -$> ./philo_bonus number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat] - -``` +# Build the binary +make -## Summary of Features and Requirements +# Clean object files +make clean -| Implementation | Synchronization | Authorized Functions | Directory | -| --- | --- | --- | --- | -| `philo` | Threads and mutexes | `memset`, `printf`, `malloc`, `free`, `write`, `usleep`, `gettimeofday`, `pthread_create`, `pthread_detach`, `pthread_join`, `pthread_mutex_init`, `pthread_mutex_destroy`, `pthread_mutex_lock`, `pthread_mutex_unlock` | `philo/` | -| `philo_bonus` | Processes and semaphores | `memset`, `printf`, `malloc`, `free`, `write`, `fork`, `kill`, `exit`, `pthread_create`, `pthread_detach`, `pthread_join`, `usleep`, `gettimeofday`, `waitpid`, `sem_open`, `sem_close`, `sem_post`, `sem_wait`, `sem_unlink` | `philo_bonus/` | +# Full clean (removes objects and binary) +make fclean -## Installation +# Recompile from scratch +make re -To compile each version, run `make` in the respective directory: +# Build with ThreadSanitizer (TSan) for runtime data-race detection +make tsan -```bash -$> make # Compiles the version with mutexes -$> make bonus # Compiles the version with semaphores +# Build with AddressSanitizer (ASan) & LeakSanitizer +make debug ``` -Both implementations are independent, so you can compile and run either according to your needs. - -## Debugging - -Multithreaded applications can have complex issues due to the concurrent access to shared resources. To ensure the program runs without issues like race conditions, deadlocks, or memory leaks, it is essential to use debugging tools that specialize in these areas. Below are two recommended tools for debugging this project: - -### 1. Valgrind with Helgrind - -**Valgrind** is a tool used for memory debugging, memory leak detection, and profiling. **Helgrind** is one of its tools designed specifically for multithreaded programs, helping to detect race conditions and other threading issues. - -### Why use Helgrind? - -Helgrind checks for data races, where two or more threads access shared data simultaneously, with at least one of them writing to it. Data races can cause unexpected behavior and hard-to-reproduce bugs. - -### How to use Helgrind - -To run Helgrind, compile your program with debug symbols (add `-g` to your compilation flags in the `Makefile`), then run: +### Command Syntax ```bash -$ valgrind --tool=helgrind ./philo [arguments] +./philo number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat] ``` -Replace `[arguments]` with the actual parameters you want to pass to the program, such as `number_of_philosophers`, `time_to_die`, etc. +* **`number_of_philosophers`**: Number of philosophers and forks (e.g. `4`). +* **`time_to_die`**: Time in milliseconds before a philosopher dies if they haven't eaten. +* **`time_to_eat`**: Time in milliseconds spent eating while holding both forks. +* **`time_to_sleep`**: Time in milliseconds spent sleeping. +* **`[number_of_times_each_philosopher_must_eat]`** *(Optional)*: If specified, the simulation stops when all philosophers have eaten at least this many times. -### Example: +### Benchmark Examples ```bash -$ valgrind --tool=helgrind ./philo 4 500 200 200 -``` +# Must survive indefinitely (no deaths) +./philo 4 410 200 200 -Helgrind will analyze the program's memory accesses, checking for concurrent access issues, and report potential data races or lock order violations (which can lead to deadlocks). This helps identify where and how the program might be accessing shared resources unsafely. +# Odd number of philosophers (must survive indefinitely) +./philo 5 800 200 200 -### 2. Thread Sanitizer (TSAN) +# Strict meal limit (must stop automatically after 28 total meals) +./philo 4 410 200 200 7 -**Thread Sanitizer** is a runtime analysis tool available with `gcc` and `clang`, designed to detect data races in multithreaded C and C++ programs. It’s particularly helpful in identifying bugs related to incorrect thread synchronization. - -### Why use Thread Sanitizer? - -TSAN can detect data races, deadlocks, and mutex misuses, and it’s optimized for speed, so it’s often faster than Helgrind. Since TSAN checks happen at runtime, it provides precise locations for where race conditions or synchronization issues occur in the code. +# Single philosopher edge case (dies at precisely 400ms) +./philo 1 400 200 200 +``` -### How to use Thread Sanitizer +--- -To enable Thread Sanitizer, add the `-fsanitize=thread` flag to both your compile and link commands in the `Makefile`. Here’s an example of how you might modify your `CFLAGS`: +## Verification & Auditing Suite -```makefile -makefile -Copiar código -CFLAGS = -Wall -Wextra -Werror -fsanitize=thread -g +The codebase is continuously verified using industry-standard dynamic analysis tools: +### 1. ThreadSanitizer (TSan) +```bash +make tsan +./philo 4 410 200 200 5 ``` +*Result: 0 data races, 0 thread leaks.* -Then compile and run your program as usual: - +### 2. Helgrind (Lock Contention & Deadlocks) ```bash -$ ./philo [arguments] - +valgrind --tool=helgrind --error-exitcode=42 ./philo 4 410 200 200 2 ``` +*Result: 0 lock order violations, 0 race conditions.* -### Example: - +### 3. Valgrind Memcheck (Memory Leaks) ```bash -$ ./philo 4 500 200 200 - +valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./philo 4 410 200 200 3 ``` -While running, TSAN will output warnings if it detects any race conditions or misuse of synchronization primitives. This allows you to pinpoint and resolve the exact lines of code that could lead to concurrency issues. - +*Result: All heap blocks freed deterministically. 0 bytes leaked in 0 blocks.* -## Extras +--- -This project is an exercise in synchronization and concurrency management, with the goal of preventing **deadlocks** and **race conditions** when using shared resources among multiple threads or processes. +## License --Born2code -![42madrid](https://github.com/ismaelucky342/Born2code/assets/153450550/3a377f34-9156-4eff-b04b-71c4b128523e) +This project is licensed under the [MIT License](LICENSE). diff --git a/inc/philo.h b/inc/philo.h deleted file mode 100644 index 4b07a4b..0000000 --- a/inc/philo.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* philo.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/06/09 15:59:08 by rhiguita #+# #+# */ -/* Updated: 2025/10/31 14:55:10 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef PHILO_H -# define PHILO_H - -# include -# include -# include -# include -# include -# include - -typedef struct s_philo // Datos de cada filisofo. -{ - - pthread_t thread; //hilo del filosofo. - int id; //ID del filoso (1 a N). - int meals_eating; //contador de comidas. - long last_meal_time; //tiempo de la ultima comida. - pthread_mutex_t *left_fork; //tenedor izquierdo. - pthread_mutex_t *right_fork;//tenedor derecho. - struct s_sim *sim; // Puntero a la simulación general. -} t_philo; - -// Estructura s_sim -typedef struct s_sim -{ - int num_philos; - int num_meals_to_eat; //Argumento opcional. - int simulation_should_end; //Flag de muerte/Fin. - long time_to_die; - long time_to_eat; - long time_to_sleep; - long start_time; - - t_philo *philos; - pthread_mutex_t *forks; - pthread_mutex_t write_mutex; //Mutex para proteger printf - pthread_mutex_t sim_mutex; - -} t_sim; - - -// time.c - -long get_current_time(void); -void precise_usleep(long time_in_ms, t_sim *sim); -long get_time_since(long start_time); - -// utils.c - -void print_status(t_philo *philo, const char *status, int force_print); -void display_error(char *message); -long ft_atol(const char *str); -size_t ft_strlen(char *s); - -// Parser.c - -int parse_args(t_sim *sim, int ac, char **av); - -// init.c - -int init_simulation(t_sim *sim); - -// main.c - -int main(int ac, char **av); - -// Simulation.c - -void *philo_routine(void *arg); -int start_simulation(t_sim *sim); - -// Monitor.c - -void *monitor_routine(void *arg); - -// actions.c - -void philo_eat(t_philo *philo); -void philo_sleep(t_philo *philo); -void philo_think(t_philo *philo); - -#endif diff --git a/obj/actions.o b/obj/actions.o deleted file mode 100644 index f19b9e2c6763e976551d8b23df3dd39168e22391..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9016 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 n_`iYm)*qLdEitN#Vp4Vj*C*U~{&1VCr+<>-e%q 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 S16Do#KJx#Mi>kb(>i-7-Yf0Gv diff --git a/obj/monitor.o b/obj/monitor.o deleted file mode 100644 index 00bd37102e66712e2f27b057d05c17c29cf9393c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8216 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 diff --git a/obj/parser.o b/obj/parser.o deleted file mode 100644 index e242d9d0f3676a521b2f9740df06eda0d82a4b75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8400 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 diff --git a/obj/simulation.o b/obj/simulation.o deleted file mode 100644 index 3d070f5b0b3aeb4d1c1cb6815453fda033ae3800..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9360 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 Y-ilW}e^tOKrGJs)f1{`=JG%aV0EW^?*8l(j diff --git a/obj/time.o b/obj/time.o deleted file mode 100644 index 0d792a8fc6e43ee5b8e7c1a02613e287eada620a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8400 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 NUZ8(h(G&w!|KAt-FJ=G$ diff --git a/obj/utils.o b/obj/utils.o deleted file mode 100644 index 865bdce4bb72b24e0ff87213071d5e59a8635ee4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9016 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 diff --git a/philo b/philo deleted file mode 100755 index 3bcaf64d3f81d9119ff5fb0742b33a3060f9fe94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38672 zcmeHw37k~bneV+-b*gUlTD>=Wfq=Ns-7F%AVr$!2ASgjlT#~ZsuBKa?ZeA@Y290)W zOb3~PaWa$lBx;<=FPX$iOiVH^Q4vNl`I$t=H-;>eaUz=TUkG~y7jTvRm%gmZJ8@*EwfmPS1L%eMm)b$XOJ{oi>*@J zXIV3?Fv=kbQ}||;0IRNpfx^_$@E}t1)iX0jI$41&lbRMXCEs}0gHeSssTEUY@(E^j z*`Lm>QFJCXc(=YLg|~d^!ia*K)XPWRB+gOz#OlKIS*@4nb!zxnB;N+jw?Xrn^oUl3 zNsT_K6aFpM`t+y1W?O!~F3smpFMv#5CS@JGE`2rI@u$?cM)Upcd?m-9zNNsHNlkqp z0w4AAK`%4RYju6&jl;uQ|0dPywHkZ6H!fP(*wZn$r@J?I!`vGdFPgh(VMC^`K{cH1 zisO$qb>YS9Er{7mm{y||xJ8wXJmRV~p7a-A_VCuvJX!MIXYbmx?aH6s{#j>2<7=d0 zyU9ZuUX*7{gk|O_hcrqbw<4!tOkYTSZ!^>Jt~wyJYZs7g9|s;nMezbkRbc&N$$4=c zINLfF{lAO@r}>XX&v-Bv{K0YH@p0P!#5nZ1ap0GZ18*Eh{wd?oe`Xx`#&O__#)1D8 z;4|e`aaW~^i~lWl9iF4^97U9z*SyT|HGr&89YR5shaIn~$M(YDRnlI=>T+B%Zg z_I3AKxlB(gwZ(;P&Sg_KBs)@>Y`QN`*$(<_%16}G*M6O~xvd8&YK7CZv+8s?clTyHeX?`CQu_7jZd6OrbiYN`g{xMa z-;$i)u+Ysd$YO}5*yVxi zC4r>>v3o?J{qV+onG^i*+I*Q4`|$bsG8Z<(^Ydj+@WV6mWlrqFmH9F! z^x=S89+~yMWtP=hKJ5Za_J3s7Y+re*uUzXZm-)(JU-><3cf9i7@s;23m0$Cff9fm0 zR2#gKa+Ujy=*lEv}ys)$jeGkhM)F#%Q-|_xzpAs2F{tmY+~@$Y)N9rIkQn1 zTJqk=$WRAH^BFM(W&6Y6b?Ybp@by44vmShKhInG|rlG{ZO+!}sZC`-21Fi4kZXG@? zv7>b;u_Li~N9((Z_U99W&nKRGIgqfKps~*;1`iCKj>-mF-?d4)!&=h%?oFkNt9daL zkb7Jf2KF|S)&i|Acd>lr54yagxry3}Y0f4h2l7Zt%2v5zf$RkGu)XWs``upL`Z{;S zgO6X0t|bP)u?9&;Vn=A!96%F;t;go=P3*k=8bBZ21;`Wl1NgwuPFc&RNWNpI&tHcJ_Bkf5A77E>Wa<+NJ>6DFR`Qb zgSnT7&Lw)V^$4Wl4<-hS!Vn$4P_}1auQZNJA)4hK%?>(H z=|v6w9-}|o3wa5UC*Q&-4V@0Qp`Su|i6yPaKKA8ZUK^p6A83_3&;zZcwhoKLK>sufz|4Qqz59iI?(*@b~V`%$&_-N}f2t;FV+nXC^ z$-^@6x*U{8IjO)5mQA3&J@X{ztf6JUlS)Qo4-9=;jtbj}qQ*}J{!uCljHO;i0fbkz z1Fyqrp#A8(f8m1C27l;t+J0Kc2+M*46dms)edW5$i_sJoBP3PUyRlw!HAdNc?X7P*RIj-i0Y2*u=K2&9|u^^#NW^{v>&c% zA|ZT<6J%}z4BM_%MmE`m@!^;0pW}#AV!-a2(B1DSmv<}oOzEh757BPzi*@aCE~lfZ zrhx9y+o0PicHv_rn*3iO0INx5y`%!@el!qmKH1ClWpXJgQ2T+Qdr($vQ-@B0ZL7d3 zjSGH!U}zqKgx{)lJfoN$m|8zZrOejNh?r&!->sDb)y1H?k8uW^p{f20Ax71DgKkW{ zA*t6SPq-wiKRcS^hNMiB-0hOgmu+bd4ICTU&iUckj^>b>^Ti)U^2TW6t;vVnTt9%4j~AJCqn) ze{kTYL!p}yYY&AXa;Mm+yTrgJ1q~mAu5|^6n;Bi;Kh;kINV7c15Cda_5~7%4v=yJD zg614wIG$K$w0|ja8O1OqUtru z&Z7X5Tyc$hjc&%d6W-6h<)&%^L^dh*X%Ofd*MttsdH+CjNY3(%kmyf0tkV;2%|cpY z<-~T3lOW>JF+0}<=`7Zh@%p364IY&`+F6>!iDyDBIlm}dEJ@K2EF*TTMY=YY7}!_D znQia~LtoGyY^440*JdE7L)L?NbKqqgsy10NROqyyQdrIrV_=VHF5H{j!3H26h9oj%EH!D1CQ#YZtstN~- zrirpS8dV9DlsNnfxFrVTagvM~<+pvwz%=!tUm5Ce7>u-ww?^9q)QUNPzI2KVAhNh* z-}cKrUGX+#5Ta#yT!DH?Tv~)rJhb2b8tZ@A`onVuu(u#TjpnWLJGtrfia(VtN1Lqz zvzMBaWJ+U<6){f4PyGU(`aC?fdoTBCP{|6_J~=_&0&|9+mpn<_P$Mvh4=IN%kPb;V zL1I1veeMm}DAt0S4-9<@<-*ml%i;!;4O)O?__`KgLRhHWRmIPBbc1Xe?FN0MKg4m9 z*4no~diXML!>;xbKaeN>>%3gqgn2&FTl1tHARVVW>}`!2687GWcCY*r8^_N{^W^4D zP9+GWC0q$Yaf8w|3OL%pL6lKJWxoDHCid;{hh7$Jjl zj4c@Ykb-wY@cRhs&kI`yVajmcd0q0sD0!eF&qv)8QJU(B>x2eQXyAkfPH5nS22N<; zga%G%;DiSL|I`4VXXG`P*QMQ?b3JYC-TNQvjjv0kH{-d@jy8$0TGQ#i^jUH5Bc$<8 zJodT&A%n7ttXVxB@mctvDYBOHk`PyFJiL0|Q>*hh zax${D+3vnxYqfj;RW~TUr7hhS@9ggB%k*{jWyV5gQ@yEyd#z8 zKw)Dlo=K(S%i>KIADK;N`;r~qsj(4wDt2sye5ke%W%cGZCpV|sdNLGA&fdQGmRt(e z>-ysRABxYNH>bN7PtA5``}iC&uZwfCnccnZed%mfi$#Zx)?A&t&86eZARk z^e^5HHMHaT*Hng;Y{eLKfKXpuZJBts?YdNN9IE1g=*!hNpY~11Q$6u6C=#9Mp?>y1 zM3s{CICOZv77b5ZP*{gGs-Esl9Nq5j-DDvrHKg;|uI}FJn78an!KFt~#}xeC`5z-A zGjX_b=TApQRw3Pkw1egU92qG=ntOR0YEiLHc8)?;=gU zGBPq5rat4)$jI49*CV|e>7z)uBi;Tg_>o@n8u*bO`Z@TK&Kd?k(zlUL#+kw=egS@@ zPaFn6(f~HS+mW_l^SuY@lSsdX^tU*A_zBX>u>*Y<=_ip+#;M;GIL0~~X$X7GtC4;P z>2{UuV5P#SFWMo7>a9b8z zURJ-dy!d+O7VF%JOHN%da|Y?ie>MIVLywY?KwN}p@z(@6b!{%zbtnGbM19W?*jg6* zc%Y>;9C#cpQf+wv;J=6dj}_p5<>H?Mybt5DvjBgai+>&Pp8$^!;Pdj=O0?`N$Mpxm z-{!>!KI-zH4m`(ue*ykc7f(C+Dew!t_-pg>dw_ov_>>nPxZ35v6Zl22n|%fNM_l{^ zz#jzu#RB|yT>Nvu?|{913aP8V;GH%JsNdHKhrOLwfM4w5OJHx)VTaEb$Uor9KOOiN zfai& zy!f3kUL`7VzaWNB9pn|CrBXahCNJ|nFu67Y1WPV?P1LFRJ{Z>#ybS*B_eSKp{6WlJ zyzoJ?yq?z?K2pu=pvIf;KCRFV#bcTBs@EwV>L|E0o0YgkfiZ>4t4s59J;}>_Hw#Z= z$t$57XyBjF8Po2)n$CPj%hW$r!wnrCWRd+tbrSTRE+@1+e1c{0k`v2qS)Qozc&vWAyuhHoio!+9;T{^u_rw{6MuTG!W>B~AjqEkzMsVt^b ze>>i%5KE^;1-$?JDZ7p7cmnh#<9y;m@F|R_9Mi{B_?LS$-<22hmcg; zJtR9x7HaLsSeRM;bztf(@l}+>q)F^S`5e&_-Hh5DhR4>)dvSNZhTC#SLi>@uuq27Q z6{8Yv0%-*qPqsum5|Id=4-ho97o|`aZs8fYHHGV9zh|euh@E|SVujp@MY}t!Nfqp$ zV}Fm7lVzdA{uv8XDp*a-{uycxSvXY|>g_j3cA6~2?b*bfE(>#P zeD%i)H`IO^uqOKmyVNM#wAkKCvZflgrrExmg?X~jCBHFkiF$&j2e}ar-H*JSjKT}} z)oClTn_|}rHuB$54)SJ&9wLei;S~~f#6?9uPli?rjRiGBknBO4rWN@yZ|9VCB55L? z8HLXxXI0*hTl6b|(iVfXsxE_cr!rVVDOVCq#aq?fncA~uP2bm1?HEA3>^)xqUC}>- zu1waw`?;HohEbZtMg({7y}6hpHOFB`g1eu;*{b;*5Oz_i@ychEAV{hurCl_cJrC^O zP~2^mgefzyy9Ya1D4Oow4(?Lv-fwG0f8eYJ#RqrqvI6%GUWDER?wd%12+m{vvs3AI z!Rwg6e;VQCPE@+J3IW>f#d2U`!3D7cNTu5c&p3&B<@UivvH-Wg7oZ^BK6qx3d12iC zVyfl;yxTvAI_s^V$L(Wu``b}_Bn({Zy6CPPT&WNZ|HY zQsv6+#X4vz7IvKH*`IyrXt=C|rf1pTW}&>|X5<}9%s|o-E5E+(&I>^WnnI5FhLjOSk^k796 z1c`JyP;y?j=?Zl8aGFTx5Kz$;>Cm$Yr6w%r1wtoE=-Do`Y67xFEz+$oC-iFG?xdK| z7f@xCz-j{RY0*Btu8_x#ps@FR6NqBgAUR*%>VIYesK{{Pvcb8T7Ta@f_NpGBcCwO_;d+M`WExV$c z?MB@=^3{Ri7ho!vfq|11FaHY32E_*t46(w%a5ww9ZxZ_ux*j*Z0;pg<=vfAYXx;^D zfzX23e!yf<2%T{f^C~EW7RdsF!rcJLpb$DU$h=w$h+1bQx*~&u@U8`fcP${iYXRY1 z3kdI8KzP>z!n+m_GpnCPojNFl)mor(PPip{D{Vssh5rePs0s=a+K;jh3RP6WZje^D zAftmqI1#)IARQEfpMmxwJynbYp>F_QqZS5EU2HPPnhOJGVg-9^75m)Z@w&g`b$@4S zExDEZJJVz#E~lG#-4j5-{n;$FFmPtZ2$Sybc-`Oey1(Off5+?oj@SJiulqY*_jej< zzmIB^`#X)YP0Ib9rW&?JxxX_{7T_S$K`q_inI8Nm@S*(xL_P<7MX$4^$MSqw{53RF zYenevMJ;NA4uVEd0ahIy%sERs3|(E&O05WELD57-%oTtlj_gFX_(nVSkErcK1T(OR z2T>9O)drE*e1TEV<|k?C!8i_MzA`jPI)ON~r`@$lcI4h?~M7$6!#u4Mlr)bO7aVYK8?a z!$cTPX~vp8L6L7L>$c{Ul9a3y?jmb>nA$M0V86>+ir4vA$RSlRrXT9!<=<7M!T6`fn2Pt?TSS(##y??i5iyI5|7&}TXefRS zR2F6knc>K6Ke8vO9ZnIq6I*~UZb2q!i69j|Q*I|J36IWc`6Ag>Fxm?uDQUSQp_HV9 zk(9&-u%)E@#)Lsj2cyUgkaJJ609IVECn@oTp5yLG$nEY)ScsRXl?Ruv2t8~>M6Nur zCn4-FuqSy9)wp{Sw#nU-ur=@Z4)0d(#Q$Suff63C55EuBAnZZt^vBb*?YbUI)}PHeKNCj{m@|usGk8VvTI6TsaKQ~ z!pq+ChT*7*D-H&ZIu*HktO<4G3(9C^{QE`43SL=La9W;Ewo2|%xD{fUsDYUl$)(6& z=_>t)DJiJ=gNKRY!lekGPSDGb66S+4`1y_>_-UUxeqi1`eqh0|f&)lG`uKr)wd4ra zI`gUOdDOpm$r1D}IfC9LN6@?E2zr+sLGO|y=v{IIXI4LmI_s^_S5Z+&Ejdc(gj%BA zs9o5U=Ce*c>a!mZ(*Rm>DBXy1MYLGK6=PA-t;$ z;az12?)$`B2;Uqm&^)kULhlX7*@RKwONR~PeSq00*LkSoMZhL|4YDkOLh z@=yl=3nVhexl%OCxsvOKC>M2B1zlB~8-0ZkD%7gvse?UV+Wcfbk%CK}=ODHBEG0QT zaef`MSR#nFc58lIdDc47w$++{+MTFBusc!JZP^Q>#^-`xK^4_Y=y+4*LBb#o{&?M` z5(vLp3b&@7%BFD_vVzocS43?C%jME-jlVtba?56wPgBi8)cHJ!>8sl#=#=!;J!ls% z|3T&jpa`ks!jL*H45{P7kUB05spG;>Krqf!DPIk#CXP2aZs-_r&n%qE$DE zNCdWunMfxTQv+PfSQO7t6~m{3>XVHxLy5fnpP~Gn1C~GWlMQ*?8C1ueWsY87lyk)v z`Y3J%M;ZuLUkA(tE9Tu`#e!pnc)BEyH1P2T^X|tROVRefz&Yn5sB?^S&NOP*apq}I z=r|*x{V3}=Q^9U?i&xo#O#YnnLV)!8V$4rA*tby!7{}d3jQ(UpA7JQDHrR;&cRtx* zYusG~3s`AeFjIMe;r(QTF2`L2k@Ea9qRub54-(SVtLTg2Wl>tW;Abh~7O+TPQ)iow z^6LnVUw#ZB&o&+9q>NGuTJ71R)G%V%*G4$w?3{rcE`D~w%ihxko+usdT79^%K^_(N zM2V1_hKJCM+JC2vg)*L9I$iOeg`V=V_dG%wbozy-D6S1f-PR&=P*C>=2(ZsIrwCU4 zw<)V$$}+CHU5SD$DW`r~Ue3h)ryW&bq|1M*$b8!IxNd|0W6&276h64i7k=6inuqRa zmp2Yi-3hKvw8Oh+4qu}Jno>@*f-gmi^&g0v~0vZ-1P_liNKu zV8NVN^7Fzu@B)C`V*|qe0>=gqpc?nsfNgS*4cHpj;aTXi#Cu5OUIGq(7xLmhutOcv z;faj$1B-}q_!ogwrv)Yad|}BD%bb>j%vs{AxO3{rba=~PYpeOK-;4e^xehPdV(5?7WQ*Uler z$_7-rgcd#m50;%(ytH^p@rtU&#puCItGIYsaS-1v4+?8V6$YZ*DxU5zCu%*!=uDLz zEGsTn+&1u$2K(FzM%>90R#crmfnZ10F(&BdsbOhad6tCX%%*5Bvyw&rW=bzN*P*-=9kym-WJ7ddqox7P%#~SX#_!~ z+eWdZ_~Z$yg;j+>)9`8+4E3--thc#-yX;j>1A4Fee)0r^K(t3!9HUS+`}is@)Tl?* ze%*%EU_^YnblfJ2CDTjtI** zT9GjrC$C&>#h2plp<>W=qqkEF8TmGkVo#^lE0qcx!3Fqx7uCv3_jz-zeQeYY7$tw4az`kS$j7$#8y|Nz2o=UIF-q^Fy+(~)NSV5t z7%)_NV&Lo(Rij@t+JKAm23(?aSz2hoWoA&z&7j7{R$)aUSg9~SEsPOos{FwOBQ{!f zN~<-}!99ToBQ~0L`-Cyota=~Jt5|m$ld*s9)t%5*Z6-23J>)g)_YN~J6zagluVSUy z5~IpeqslVnAD)paHw_3cEu48`qwJt!RLrX!J-$`>@vT-aQ&R`Uc_;JQ!U3YfhhdzxDIR}CAi>s} z=Owmn{~m6Qgu5R6Au}zEtaU2>8u7Ole>|wW1AhT~TA;j$dk=!}jY!Uir5xY=K=@cj7v1xmQ zn8KuA1U_<9MBf&oUld;o;O2vU_Xs;!8DHo;AOb@o;@pne2TabhqUa(Kxn7kH ziQvVe=v5KfX3CLOqU==>*!r4?z9#G|0=4M$Fq;XT^dTKnC-|@?uM;ZE=;T!7rCy4E zM_zfmAGv^3PF^poKo^wC`7m-yIi1LbrE<*kXu)#(Q8vqw9jO%2RU-E4R#CrF%*u*} zl_HML*%vuiiPEDYt`ucoG*47I&AZvjXp@K?6(w0wx(aG*Ix32T*WV+iYQkV~XCQ>` z@j*6rmZy>L-&q;}J83#BJ6pn|OuLyo}59CMfeF3 z8K60Y8%6YTQIi!D*yNR>hDlb;MiN*lEhCT>;Z;Ip6>6oZR1~GF*z3xRL`hCKSBk18 zF$p#mzekjAASk+?LhB2JmR%z3d*_MB27n%>OEM66#-eT(_p$3%I*h;L%vc}!H3qfTl#BJbCGCe?ofDxD1z>* zmWwj9|0CM`R*H&?#QBCG3Ib)85`Lk9mjG^GAr)Da6D3!Q>V7fJ*&rr$ijs3!nCu`o zz}zf=OSUq1I$$UFi#e-AW4|at0kE0C&cK+j5;MSXwuoIJ>ifkhigIq3Sct*~5pz~5 z@CI@6N;-OFFuhWgb|MtScC8kTM@7{xQNhMJa06IXzo@uEEHka07rsJ>U84Ng9G*qr z5tX|{OcFyelDPH?QPwY}6V@*-MiMaEk)3~3RICzF$QlbKM7%Q4fEv7mN%a_(UF2OR+tZ=={Y4w1@wbqYB3!wK?hZz z&&q=^a#9UrfX*(U%8FB2-XLZ&$x`yAUIGqu@#8uAOUdP;HY+9)yAtbCNj?h+9CZeh zEQ1%uK%!QPDn)?-Lm)40qPuF|I)$maNEBT!sxzXb@9V-oXP$7JZZ$UO;3jb%sW=o7 zbP&cIZxUt3k{_TYbF8!_V+fav*`E-T`-Kz^Jdq7z#wOa1Y|#T^#(<|Vb3jb&R}ta? z;S7kTO=5PxGJ^-iG|BxpqV%7I{Vh4Xe4?Bled&0^D?br6b7(>6jC__uEN^2CG2J&L z$Jup;1LZXc-2vHhI7BDgKJ^#T=}XfLZH7-RA+@aTP(cDMZoj6an6KQ zR`iST*<#u%5$bS%c1@iI79t-9kh4Yj(1fvbV7NMUDXRDYnUrg^8HBN(= zxKzyO$K1L>gsB7=8zQ7T79os9EO_HeQQRrQc+N^sz%Pm7i}EfP3eRV3XH4c)zd?kK za;gVQG+4C3%)m>uMnC+=Yc%>0H7ajXqnvmG`I%RG4kw;aUbp6BlVH6qqK|VvDY`<0 zFn7STF`csS8^oNmML5f@01<0tgQr|0qOgH0f+Y=iNIZQc>-0g;xL5oS1Nc^ z1aD(`!aq`xjBM2_#aWoU5F4-JTBqh6F{NLGpy6U?w+L;88Z%OjfndchinOm-B*Jft zl8@6a1J8=cchv|$^2H+jKST&q{s_ECBA_Cb|r4wQqHwg|j^RMf8%hFzVbRf~Tm0bKm(Q@RpeLxCr!%iH|8igDVekTAp$*q2gPj(Ya65 zqO<)!$HWPSqhg+OuYw5sRRWyPV$PORYBtG_%aX~Cwrrb~?%vduP0APSWV-s&S-cJ@ zYh{vK_)?uw?*ftliQ+GKnjh!{M=FgU(8P~xX7GEN{8>$dQoqxg1#x>HzOae3H+2IO zyz6HZe|>XHI_2j#DY^4B?&NxXii!@_T6Zi>qr z+p6AGq~F-1f2^~oErZ|p#7m5ld^ZyKGF!TPGZucbHr_JtO#SuH_}tCeTyN@}O?VYi zy1O04wsd>fIqG+G<8wE~=XSPbw)M7mrTcpOa+$fg-s@5O+$?{kGXo@A-G1HNE$O~2 z-*%Lq%ikhJ!wjMwjp#CHyaEb{_D)aP%JpWTgH%Vny{j#4@m)$B7o&pqo>W_JZi|Kf zw_81_PCZ8XzPs#lz+A>8MlsjZkxW5R;N9xJ9ZLOxsv6@0UW`c&uXf5$+H$TmqOr~HJd;^wzX;xBFd$?&bNs8;c9;0AE0h+{A zhIcf%qDd!hEW0(CNwr%@(DHT{ubLv;TG%@MJFR#(Sh78bw^Q|^P8tRQvZ4%LTjl%t zSqbm%O>U<7v6{Z#4!je~y1wnYR5G{4Se9z1)G}URg`bH{wRgj8_3zcf@;s~Ng= zs#o?CBZSvasdtG1)0XY)K~0$qEFIP8-6UC*laFi!IRrla4YE=>Q`?IbwNWb)L2_Kn?{Y&0@e7)toHNvt`vT!SGr+$CMjRi z1%uhV5u?@7y@|3IDw4{)^qaMk>AoD^pp_pvU4_62gn`dRx?U_bKv4(b;w;FSqbR!I;C)bf`M0iLpTBv_>dsA<&abq`r&RCM*2Y?$l zwYQHZnYX~OE8z_dEEmYNR9EL_5DQWWGTXMKG7Vjbj2#`RPMJyP+7Z+EyT>SMeHk*@ za7BgpljZRe)PZ&}!*0=>(5?6HQKJ<7K7^TV8MII~jDless0Z3atC5j)>3U%eJsIjV z+tJ-;8bd47I&PG~K5a_*IA|c+B1{pljYCYK#Bnc7&G-oX%@IEV-{W8d!*?k0ipx7b z@@C6!f-m{^}trf`F)SvK%bAY)rK?(Z=h_~(%stNmXFoN~+=(leUjo8!n#6!Jgx_v zM)J4wy%H?zlajvPeIJU!-UoOk`s;tb;sFUaRQZ%oIg#G~HPPqBp&tf3o@aM+{I+V` z!s)cOe}fPK${&5zN_fojKQb~y!~Ktc^7|=c$!XQ}{%@*X0(cDVG5%;;aG9pxIYU9r z(`ucB2P!P{J{&{eBk4^kpWdP6n8UjL8uiy2?*FPCpDrA${SS@<|F?1A{F=>Ja^92h znC1V9KosM`@%4YZkY6ey+-#-Iqp>pqr{4VI$OqTr`R=>9X22@~6D;%o7K2z#I9uAJ zAo5TLSw54*di`H|=GXnl>KEhqSnzwb9RI^X{{(mpak$=Rho@@#xE96_?|FS$!~I`! zdP2+b+s}72z5lfg-IPl8> zpD~7uJ>vrvtH3l6v;JuY3wdqj0%`b60D_75YHkn+$_Po`t$<~W6NG7f11y@{r-s%-C=q`4-$<~C%CN5ZOB`;ic z$@%B4N?x*j`K7JvlIzYpe^qO;VA;<7cJqa+R-E6GoZm3N;SB%Ah}*7>?c8Fdu?EG` z*d<=D&`PdYw>p_0&vmO?IGXFYO}4h=vKg0_g1tKcB`&WZwHGQN&+nL$DS2FBb_QlM zAjck^hAiw-+PkhxcD8l*xH1-6W@k0VmZ{SvlPxRQ&+7ea0fqO~(gg^0>QDgk9A3!1 znAx7G{=2Q0XD~{y=)@-UPAeHBn(WB*CA+YffgY19E&-wg+fi&MJN&y$vwKqeU$xmS zXw7E15i9_yhRCfvj|!xPdxj#J+?c^R00+GAL`Ut=Tu~VRQM>A75;kD$lEz_Nz0fqY zzPbPNiYx34+vQ?8OgKrpp^c-?H+B~qt#od)HBwupBo6}$_|?X|0Aw{}wr$3-4$^E| zrClZ`&$hN$4ZS$!X~1@`0p~qiQt9kA4`^eqyQgC=zRIMi&O3hv4v98dk{oZB?y?#> zw)LV4mEtSz62mPg&qch2Byj0ePa7F@Zc9(rYM>UZ24ovH_2~@HJsPkXM3LbS)P2%H z8d6<4;B|FCnkgw6Do830lSfr;o4X-Qv18b+283L`wHvV1#@r@Qw)Jj8eAY$0`Mb~L z+cs|G37*FEaL=#v(4ff@3|mSU%qM?pVG@huc&s8hpl z-uGzIy_(R}@9+QLYyR^!oq2zxNzMBv$xog6`9BL7bzny$AqJ4WW|M>3#(#s#$ zd?xi9yjjMX^z(lH3RPQNr-sh7!IVw-=^uQHSi@(; zKI!M5r7&h+R%!@!>enC7F{nQ?{$~GS(z{%Q5@5zpi?hD#<2U4i1F9|DiC;_QTiZh603PfdX7r{^rmdmH$hg8KU0l4cUtoS`Tqc3+OFX@ z=Mft;{}Cz|7yXZysn?9-mjEM);WzJVO`J<=%X(NP?%nX4Gz?}hzq=1@RxG9-Bf#*P zatW9TGxeMORjgT2_~}`f_o~qKH+g}`8~)RLaKmrXiJIR>W-V=2kXsC)Ch!%lQ^w(c z>^#MAD6SdD;Xh*>{(CnnhBr7lcrJhaE#vU->{U!p7kQYG_48k%`ThD^yG`-gVr+gR z=gM*TFXhC5i|10_%M`t-&&4Hq{1(OaX>GVCp*RD7#vaW4$Ma)jJBmZyAHGAS{2H3~ XGW8l5!{u1~8}C#U*ZLTIMeBb7YF${_ diff --git a/philo/Makefile b/philo/Makefile new file mode 100644 index 0000000..537dd5a --- /dev/null +++ b/philo/Makefile @@ -0,0 +1,68 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: rhiguita &1 - -# Compile object files from source files -$(OBJ_DIR)%.o: $(SRC_DIR)%.c - @mkdir -p $(OBJ_DIR) - @echo "compiling ...$<" - @$(CC) $(CFLAGS) -c $< -o $@ 2>&1 - -clean: - @$(RM) -r $(OBJ_DIR) - @echo "Delete files objets" - -fclean: clean - @$(RM) $(NAME) - @$(RM) - @echo "Delete all files" - -re: fclean all - @echo "Finsh Recompiling" - -# Phony targets represent actions not files -.PHONY: all clean fclean re diff --git a/srcs/actions.c b/srcs/actions.c deleted file mode 100644 index 9a207b3..0000000 --- a/srcs/actions.c +++ /dev/null @@ -1,88 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* actions.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* localVarHTTP +#+ */ -/* Created: 2025/10/31 14:30:00 by ruben #+# #+# */ -/* Updated: 2025/10/31 14:30:00 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -/** - * @brief Suelta los tenedores (mutexes) en el orden correcto. - */ -static void drop_forks(t_philo *philo) -{ - // El orden de soltar no importa para el deadlock, - // pero por simetría, los soltamos. - pthread_mutex_unlock(philo->left_fork); - pthread_mutex_unlock(philo->right_fork); -} - -/** - * @brief Coge los tenedores usando la lógica par/impar para evitar deadlocks. - */ -static void take_forks(t_philo *philo) -{ - // Lógica Anti-Deadlock (Par/Impar) - if (philo->id % 2 == 0) // Filósofo PAR - { - pthread_mutex_lock(philo->right_fork); - print_status(philo, "has taken a fork", 0); - pthread_mutex_lock(philo->left_fork); - print_status(philo, "has taken a fork", 0); - } - else // Filósofo IMPAR - { - pthread_mutex_lock(philo->left_fork); - print_status(philo, "has taken a fork", 0); - pthread_mutex_lock(philo->right_fork); - print_status(philo, "has taken a fork", 0); - } -} - -/** - * @brief Acción de COMER. - */ -void philo_eat(t_philo *philo) -{ - // 1. Coger tenedores (con lógica anti-deadlock) - take_forks(philo); - - // 2. Actualizar estado y comer - pthread_mutex_lock(&philo->sim->sim_mutex); - philo->last_meal_time = get_current_time(); - philo->meals_eating++; - pthread_mutex_unlock(&philo->sim->sim_mutex); - - print_status(philo, "is eating", 0); - - precise_usleep(philo->sim->time_to_eat, philo->sim); - - // 3. Soltar tenedores - drop_forks(philo); -} - -/** - * @brief Acción de DORMIR. - */ -void philo_sleep(t_philo *philo) -{ - print_status(philo, "is sleeping", 0); - precise_usleep(philo->sim->time_to_sleep, philo->sim); -} - -/** - * @brief Acción de PENSAR. - */ -void philo_think(t_philo *philo) -{ - print_status(philo, "is thinking", 0); - // Nota: Un pequeño 'sleep' aquí puede ayudar a - // desincronizar a los filósofos, especialmente con números pares. - usleep(1000); -} diff --git a/srcs/init.c b/srcs/init.c deleted file mode 100644 index bd87bf4..0000000 --- a/srcs/init.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "../inc/philo.h" - -static int init_mutex(t_sim *sim) -{ - int i; - - i = 0; - while (i < sim->num_philos) - { - if (pthread_mutex_init(&sim->forks[i], NULL) != 0) - return (display_error("Fallo al inicializar mutex fork"), 0); - i++; - } - if (pthread_mutex_init(&sim->write_mutex, NULL) != 0) - return (display_error("Fallo al inicializar mutex write"), 0); - if (pthread_mutex_init(&sim->sim_mutex, NULL) != 0) - return (display_error("Fallo al inicializar mutex simulation"), 0); - return (1); -} - -static void init_philos(t_sim *sim) -{ - int i; - - i = 0; - while(i < sim->num_philos) - { - sim->philos[i].id = i + 1; - sim->philos[i].sim = sim; - sim->philos[i].meals_eating = 0; - - sim->philos[i].last_meal_time = sim->start_time; - - sim->philos[i].left_fork = &sim->forks[i]; - - if (i == sim->num_philos - 1) - sim->philos[i].right_fork = &sim->forks[0]; - else - sim->philos[i].right_fork = &sim->forks[i + 1]; - i++; - } -} - -int init_simulation(t_sim *sim) -{ - sim->philos = malloc(sizeof(t_philo) * sim->num_philos); - if (!sim->philos) - return (display_error("Malloc falló para filosofos"), 0); - memset(sim->philos, 0, sizeof(t_philo) * sim->num_philos); - - sim->forks = malloc(sizeof(pthread_mutex_t) * sim->num_philos); - if (!sim->forks) - return (free(sim->philos), display_error("Malloc falló para tenedores"), 0); - if (!init_mutex(sim)) - { - free(sim->philos); - free(sim->forks); - return (0); - } - sim->start_time = get_current_time(); - init_philos(sim); - return (1); -} diff --git a/srcs/main.c b/srcs/main.c deleted file mode 100644 index f697349..0000000 --- a/srcs/main.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../inc/philo.h" - -/** - * @brief Libera toda la memoria y destruye todos los mutexes. - * - * Es la función de limpieza que se llama al final, - * tanto si la simulación ha ido bien como si ha fallado - * después de la inicialización. - */ -static void cleanup(t_sim *sim) -{ - int i; - - if (!sim) // Seguridad extra - return; - - // 1. Destruir todos los mutexes de los tenedores - i = 0; - while (i < sim->num_philos && sim->forks) - { - pthread_mutex_destroy(&sim->forks[i]); - i++; - } - // 2. Destruir los mutexes de control - pthread_mutex_destroy(&sim->write_mutex); - pthread_mutex_destroy(&sim->sim_mutex); - - // 3. Liberar toda la memoria (malloc) - if (sim->philos) - free(sim->philos); - if (sim->forks) - free(sim->forks); -} - -/** - * @brief Punto de entrada principal del programa. - */ -int main(int argc, char **argv) -{ - t_sim sim; // Nuestra estructura principal que lo contiene todo - - // 0. Inicializar la estructura a cero para evitar basura - memset(&sim, 0, sizeof(t_sim)); - - // 1. Parsear y validar los argumentos - if (!parse_args(&sim, argc, argv)) - return (1); // El error ya se ha impreso en parse_args - - // 2. Inicializar la simulación (mallocs y mutexes) - if (!init_simulation(&sim)) - { - // Si init falla, cleanup se encarga de liberar - // lo que se haya podido reservar a medias. - cleanup(&sim); - return (1); - } - - // 3. (PRÓXIMO PASO) Lanzar la simulación (crear hilos) - // - if (!start_simulation(&sim)) - { - cleanup(&sim); - return (1); - } - printf("-----Simulación Terminada-----\n"); - // 4. Limpiar todos los recursos - cleanup(&sim); - - return (0); -} diff --git a/srcs/monitor.c b/srcs/monitor.c deleted file mode 100644 index 338789c..0000000 --- a/srcs/monitor.c +++ /dev/null @@ -1,126 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* monitor.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* localVarHTTP +#+ */ -/* Created: 2025/10/31 00:30:00 by ruben #+# #+# */ -/* Updated: 2025/11/01 10:20:00 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -/** - * @brief Comprueba si todos los filósofos han comido 'num_meals_to_eat'. - * - * ¡¡VERSIÓN OPTIMIZADA!! - * Esta función DEBE ser llamada MIENTRAS sim_mutex ESTÁ BLOQUEADO. - * - * @param sim La estructura de simulación. - * @return 1 si todos comieron, 0 si no. - */ -static int check_meals(t_sim *sim) -{ - int i; - - if (sim->num_meals_to_eat == -1) - return (0); - i = 0; - while (i < sim->num_philos) - { - // Asumimos que sim_mutex ya está bloqueado - if (sim->philos[i].meals_eating < sim->num_meals_to_eat) - return (0); // Encontramos uno que no ha comido, salimos - i++; - } - // Si salimos del bucle, es que todos comieron - sim->simulation_should_end = 1; // Ponemos el flag para parar - return (1); // 1 = Todos comieron -} - -/** - * @brief Comprueba si algún filósofo ha muerto. - * - * ¡¡VERSIÓN OPTIMIZADA!! - * Bloquea sim_mutex UNA SOLA VEZ para comprobar a todos. - * - * @param sim La estructura de simulación. - * @return 1 si alguien murió, 0 si no. - */ -static int check_death_and_meals(t_sim *sim) -{ - int i; - long current_time; - - i = 0; - current_time = get_current_time(); - - // ---- INICIO SECCIÓN CRÍTICA (¡UNA SOLA VEZ!) ---- - pthread_mutex_lock(&sim->sim_mutex); - - // 1. Comprobar si ya debemos parar (por si acaso) - if (sim->simulation_should_end) - { - pthread_mutex_unlock(&sim->sim_mutex); - return (1); - } - - // 2. Comprobar si todos han comido - if (check_meals(sim)) - { - pthread_mutex_unlock(&sim->sim_mutex); - return (1); // check_meals ya puso el flag - } - - // 3. Comprobar muertes - while (i < sim->num_philos) - { - if (current_time - sim->philos[i].last_meal_time >= sim->time_to_die) - { - // ¡Muerto! - sim->simulation_should_end = 1; // Ponemos el flag - pthread_mutex_unlock(&sim->sim_mutex); - // ---- FIN SECCIÓN CRÍTICA ---- - - // Imprimimos el mensaje de muerte (fuera del lock) - print_status(&sim->philos[i], "died", 1); - return (1); // 1 = Alguien murió - } - i++; - } - - // Si nadie ha muerto y no todos han comido, liberamos el mutex - pthread_mutex_unlock(&sim->sim_mutex); - // ---- FIN SECCIÓN CRÍTICA ---- - - return (0); // 0 = Nadie murió -} - -/** - * @brief La rutina del hilo monitor (el vigilante). - * - * Comprueba constantemente si la simulación debe terminar. - */ -void *monitor_routine(void *arg) -{ - t_sim *sim; - - sim = (t_sim *)arg; - - // Esperamos un poco antes de la primera comprobación - // para dar tiempo a los filósofos a coger sus primeros tenedores. - usleep(sim->time_to_die / 2 * 1000); - - while (1) - { - // 1. Comprobamos muertes Y comidas en una sola función atómica - if (check_death_and_meals(sim)) - break; // Si sí, salimos del bucle - - // Dormimos un poco para no quemar la CPU - usleep(1000); // Chequeamos cada 1ms - } - return (NULL); -} \ No newline at end of file diff --git a/srcs/parser.c b/srcs/parser.c deleted file mode 100644 index 33bb208..0000000 --- a/srcs/parser.c +++ /dev/null @@ -1,73 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* init.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/10/27 17:32:50 by rhiguita #+# #+# */ -/* Updated: 2025/10/27 18:55:12 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -static int check_args(t_sim *sim) -{ - if (sim->num_philos <= 0) - return (display_error("Número de filosofos debe ser > 0"), 0); - if (sim->time_to_die <= 0) - return (display_error("time_to_die debe ser > 0"), 0); - if (sim->time_to_eat <= 0) - return (display_error("time_to_eat debe ser > 0"), 0); - if (sim->time_to_sleep <= 0) - return (display_error("time_to_sleep debe ser > 0"), 0); - if (sim->num_meals_to_eat < -1 || sim->num_meals_to_eat == 0) - return (display_error("num_meals_to_eat no puede ser > 0 ó -1(infinito)"), 0); - return (1); -} - -static int is_valid_number(const char *s) -{ - int digit; - - digit = 0; - while (*s == ' ' || (*s >= 9 && *s <= 13)) - s++; - if (*s == '+' || *s == '-') - s++; - while (*s) - { - if (*s >= '0' && *s <= '9') - digit = 1; - else - return (0); - s++; - } - return (digit); -} - -int parse_args(t_sim *sim, int ac, char **av) -{ - int i; - - if (ac < 5 || ac > 6) - return (display_error("Numero incorrecto de argumentos"), 0); - i = 1; - while (i < ac) - { - if (!is_valid_number(av[i])) - return (display_error("Argumento contiene caracteres no validos"), 0); - i++; - } - sim->num_philos = (int)ft_atol(av[1]); - sim->time_to_die = ft_atol(av[2]); - sim->time_to_eat = ft_atol(av[3]); - sim->time_to_sleep = ft_atol(av[4]); - if (ac == 6) - sim->num_meals_to_eat = (int)ft_atol(av[5]); - else - sim->num_meals_to_eat = -1; - return (check_args(sim)); - -} \ No newline at end of file diff --git a/srcs/simulation.c b/srcs/simulation.c deleted file mode 100644 index bb76da1..0000000 --- a/srcs/simulation.c +++ /dev/null @@ -1,103 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* simulation.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* localVarHTTP +#+ */ -/* Created: 2025/10/31 00:00:00 by ruben #+# #+# */ -/* Updated: 2025/10/31 00:00:00 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -/** - * @brief La rutina principal de un filósofo (lo que hace cada hilo). - * - * Esta es la función que se pasa a pthread_create. - * Es un bucle de vida: comer, dormir, pensar. - * - * @param arg Un puntero void* a la estructura t_philo del filósofo. - */ -void *philo_routine(void *arg) -{ - t_philo *philo; - - philo = (t_philo *)arg; - if (philo->sim->num_philos == 1) - { - // Solo hay 1 tenedor. Lo coge. - pthread_mutex_lock(philo->left_fork); - print_status(philo, "has taken a fork", 0); - // No puede coger el segundo, así que espera a morir. - // El monitor (que corre en paralelo) lo detectará. - // Esperamos un poco más de 'time_to_die'. - precise_usleep(philo->sim->time_to_die + 10, philo->sim); - pthread_mutex_unlock(philo->left_fork); // Soltar al "morir" - return (NULL); // El hilo termina. - } - if (philo->id % 2 == 0) - precise_usleep(philo->sim->time_to_eat / 2, philo->sim); - - while (1) - { - // Comprobación de muerte (protegida) - pthread_mutex_lock(&philo->sim->sim_mutex); - if (philo->sim->simulation_should_end) - { - pthread_mutex_unlock(&philo->sim->sim_mutex); - break; // Salir del bucle si alguien murió - } - pthread_mutex_unlock(&philo->sim->sim_mutex); - - - philo_eat(philo); - philo_sleep(philo); - philo_think(philo); - } - return (NULL); -} - -/** - * @brief Lanza todos los hilos (filósofos y monitor). - * - * @param sim La estructura de simulación. - * @return 1 si éxito, 0 si falla. - */ -int start_simulation(t_sim *sim) -{ - int i; - - i = 0; - // 1. Lanzar un hilo por cada filósofo - while (i < sim->num_philos) - { - // pthread_create(puntero_al_hilo, atributos, funcion_a_ejecutar, datos) - if (pthread_create(&sim->philos[i].thread, NULL, - &philo_routine, &sim->philos[i]) != 0) - return (display_error("Fallo al crear el hilo del filósofo"), 0); - i++; - } - - // 2. (PRÓXIMO PASO) Lanzar el hilo monitor - // - pthread_t monitor_thread; - if (pthread_create(&monitor_thread, NULL, &monitor_routine, sim) != 0) - return (display_error("Fallo al crear el hilo del monitor"), 0); - - - // 3. Esperar a que todos los hilos de los filósofos terminen - i = 0; - while (i < sim->num_philos) - { - pthread_join(sim->philos[i].thread, NULL); - i++; - } - - // 4. (PRÓXIMO PASO) Esperar a que el monitor termine - // - // pthread_join(monitor_thread, NULL); - - return (1); -} \ No newline at end of file diff --git a/srcs/time.c b/srcs/time.c deleted file mode 100644 index 8155b98..0000000 --- a/srcs/time.c +++ /dev/null @@ -1,49 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* time.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/10/26 08:25:53 by rhiguita #+# #+# */ -/* Updated: 2025/10/27 17:25:40 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -long get_current_time(void) -{ - struct timeval tv; - if (gettimeofday(&tv, NULL) != 0) - { - printf("Error: gettimeofday falló\n"); - return (0); - } - return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)); -} - -long get_time_since(long start_time) -{ - return (get_current_time() - start_time); -} - -void precise_usleep(long time_in_ms, t_sim *sim) -{ - long start_time; - long wake_up_time; - - start_time = get_current_time(); //Hora actual extraida por get_current_time. - wake_up_time = start_time + time_in_ms; // Calcular la Hora exacta al despertar. - while(get_current_time() < wake_up_time) - { - pthread_mutex_lock(&sim->sim_mutex); - if (sim->simulation_should_end) - { - pthread_mutex_unlock(&sim->sim_mutex); - break; - } - pthread_mutex_unlock(&sim->sim_mutex); - usleep(500); - } -} diff --git a/srcs/utils.c b/srcs/utils.c deleted file mode 100644 index d409082..0000000 --- a/srcs/utils.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* utils.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ruben +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/10/26 08:26:19 by rhiguita #+# #+# */ -/* Updated: 2025/10/31 01:48:32 by ruben ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../inc/philo.h" - -long ft_atol(const char *str) -{ - long num; - int sign; - - num = 0; - sign = 1; - while (*str == ' ' || (*str >= 9 && *str <= 13)) - str++; - if (*str == '-' || *str == '+') - { - if (*str == '-') - sign = -1; - str++; - } - while (*str >= '0' && *str <= '9') - { - num = num * 10 + (*str - '0'); - str++; - } - return (num * sign); -} - -size_t ft_strlen(char *s) -{ - size_t i; - - i = 0; - while (s[i] != '\0') - i++; - return (i); -} - -void display_error(char *message) -{ - write(2, "Error: ", 7); - write(2, message, ft_strlen(message)); - write(2, "\n", 1); -} - -void print_status(t_philo *philo, const char *status, int force_print) -{ - long timestam; - int sim_ended; - - pthread_mutex_lock(&philo->sim->write_mutex); - timestam = get_time_since(philo->sim->start_time); - - pthread_mutex_lock(&philo->sim->sim_mutex); - sim_ended = philo->sim->simulation_should_end; - pthread_mutex_unlock(&philo->sim->sim_mutex); - if (!sim_ended || force_print) - { - printf("%ld %d %s\n", timestam, philo->id, status); - } - pthread_mutex_unlock(&philo->sim->write_mutex); -} - - - - - - - - - - - - - - - - - - -