This project has been created as part of the 42 curriculum by jmattion.
Codexion is a simulation project focused on concurrency and resource sharing. It models a scenario where multiple coders sit in a coworking hub, competing for limited resources (USB dongles) to compile their quantum code.
The goal is to solve a variation of the "Dining Philosophers" problem using threads and mutexes in C. The simulation requires orchestrating multiple threads (coders) that cycle through compiling, debugging, and refactoring states, while ensuring:
- No deadlocks occur.
- No coder burns out due to lack of resources.
- Resources (dongles) obey strict cooldown periods.
- Access to resources is arbitrated by specific scheduling policies (FIFO or EDF).
To compile the project run:
makeThis will generate the codexion executable.
The program requires exactly 8 arguments:
./codexion <number_of_coders> <time_to_burnout> <time_to_compile> <time_to_debug> <time_to_refactor> <number_of_compiles_required> <dongle_cooldown> <scheduler>- number_of_coders: Number of coders in the simulation.
- time_to_burnout: Time (ms) a coder can go without compiling before burning out.
- time_to_compile: Time (ms) required to compile code.
- time_to_debug: Time (ms) spent debugging.
- time_to_refactor: Time (ms) spent refactoring.
- number_of_compiles_required: Number of times a coder must compile to complete the simulation.
- dongle_cooldown: Time (ms) a dongle remains unusable after being released.
- scheduler: scheduling policy: fifo (First In, First Out) or edf (Earliest Deadline First).
Run a simulation with 4 coders, using the EDF scheduler:
./codexion 4 410 200 100 100 5 10 edfThis project implements robust solutions to common concurrency issues:
To prevent circular wait conditions (where every coder holds one dongle and waits for the other forever), we use an asymmetric acquisition strategy. Coders with odd IDs attempt to take the right dongle first, while coders with even IDs take the left one first. This breaks the symmetry and guarantees that at least one coder can always acquire both resources.
The simulation implements a custom scheduling mechanism. When a dongle becomes available, it is not simply grabbed by the fastest thread. Instead, a request is placed in a queue (logic handled in scheduler.c).
- FIFO: Grants access based on the arrival time of the request.
- EDF: Grants access to the coder closest to burnout (priority based on deadline).
Dongles have a mandatory cooldown period. This is handled by storing a timestamp (available_timestamp) in the dongle structure. Even if the mutex is unlocked, a coder cannot acquire the dongle until get_time_ms() exceeds this timestamp.
A dedicated Monitor thread constantly scans the status of all coders. If a coder's last compile time plus time_to_burnout is exceeded, the monitor immediately flags the simulation as inactive and prints the burnout message within the required precision window.
To prevent garbled output from multiple threads writing to stdout simultaneously, all printing is routed through a serializer module protected by its own mutex.
The project relies on the pthread library and uses the following primitives:
Mutexes are the core synchronization tool used to protect shared memory:
- Dongles: Each dongle has a mutex. However, acquiring the lock is not enough; the thread must also check the scheduling queue and the cooldown timestamp.
- Coders: Each coder's internal state (e.g., last_compile, compile_done, deadline) is protected by a mutex to allow safe reading by the Monitor thread.
- Table/Queue: The central request queue is protected to safely add/remove requests from multiple threads.
- Serializer: Ensures printing of logs.
- Worker Threads: Each coder runs in a separate thread (workers_routine). They loop through take_dongles, worker_compile, worker_debug, and worker_refactor.
- Monitor Thread: Runs efficiently in parallel (monitor_routine), checking strict timing conditions without blocking the worker threads.
- Shared Flags: An active flag in the main table allows for a clean shutdown of all threads once the simulation objective is met or a burnout occurs.
- POSIX Threads Programming (man pages).
- Geeks for geeks.
- Documentation: Retrieving technical documentation on pthread functions.
- Redaction: Helping to write this README file.