This project has been created as part of the 42 curriculum by tjacob.
Codexion is a POSIX threads synchronization project inspired by the dining philosophers problem. Several coders share a circular table of USB dongles. A coder needs both adjacent dongles to compile, then releases them before debugging and refactoring. The simulation stops when a coder burns out or when every coder has compiled the required number of times.
This implementation supports the two mandatory arbitration policies:
fifo: requests for a dongle are served in arrival order.edf: requests are served by earliest burnout deadline, usinglast_compile_start + time_to_burnout.
Compile from the repository root:
makeRun the program with all mandatory arguments:
./codexion number_of_coders time_to_burnout time_to_compile time_to_debug time_to_refactor number_of_compiles_required dongle_cooldown schedulerExample:
./codexion 4 800 200 200 200 3 10 fifo
./codexion 5 900 150 150 150 4 20 edfAll time values are in milliseconds. Invalid input is rejected, including
missing arguments, negative values, non-integers, and a scheduler different from
fifo or edf.
Deadlock prevention is handled by atomic acquisition. A coder never keeps one dongle while waiting for the second one. Instead, the coder inserts one request in each adjacent dongle heap and may compile only when both dongles select that same coder and both cooldowns have expired. This removes the hold-and-wait condition from Coffman's deadlock conditions.
Starvation is reduced through mandatory per-dongle arbitration. FIFO keeps a stable arrival order. EDF compares coder deadlines so the coder closest to burnout is served first on contended dongles, with FIFO order as a tie breaker.
Cooldown handling is part of each dongle state. When a coder releases dongles,
each dongle receives an available_at timestamp. A later request cannot acquire
that dongle before this timestamp, even if it is already first in the heap.
Precise burnout detection is handled by a dedicated monitor thread. It checks
coder deadlines every millisecond and stops the simulation immediately when a
coder misses time_to_burnout.
Log serialization is protected by a dedicated output mutex, so state messages cannot interleave on the same line.
Each coder is represented by a pthread_t. The monitor is a separate
pthread_t responsible for detecting burnout and stopping the simulation.
Each dongle owns:
- a
pthread_mutex_tprotecting its heap, held state, and cooldown timestamp; - a custom binary heap storing pending requests.
The shared simulation state uses a pthread_mutex_t to protect stop status,
request sequence numbers, compile counters, and each coder's
last_compile_start. The logger uses another pthread_mutex_t dedicated to
output.
Race conditions are prevented by locking both adjacent dongles in address order before checking whether a coder can acquire them. This gives one consistent view of both resources while avoiding lock-order deadlocks. The monitor communicates simulation shutdown by setting the shared stop flag under the state mutex. Coder acquisition loops re-check the protected dongle state regularly with a short interruptible sleep.
pthread_create(3),pthread_join(3), andpthread_mutex_lock(3)manual pages.- POSIX Threads Programming documentation.
- Classic dining philosophers and Coffman's deadlock conditions references.
- Binary heap and priority queue references for FIFO/EDF request scheduling.
AI was used as an implementation assistant to structure the synchronization strategy, write and review C code, and prepare small validation scenarios. The core project constraints, behavior, and final code were checked against the subject requirements.