| coders | ||
| Makefile | ||
| README.md | ||
This project has been created as part of the 42 curriculum by semebrah.
Description
Codexion is a concurrency simulation that models a co-working hub where multiple coders compete for limited USB dongles to compile quantum code. The project demonstrates thread synchronization, mutual exclusion, and scheduling algorithms using POSIX threads in C.
Project Goal
The simulation races coders against time before they burn out. Each coder must acquire two dongles (one on their left, one on their right) to compile. The challenge is to manage resource allocation fairly while preventing deadlock and starvation.
Key Concepts
- Coders: Represented as threads, each cycles through compiling, debugging, and refactoring
- Dongles: Shared resources between adjacent coders; cooldown period applies after release
- Scheduling: FIFO (First In First Out) or EDF (Earliest Deadline First)
- Burnout: Occurs when a coder cannot compile within the specified time_to_burnout
Instructions
Compilation
make
Execution
./codexion <number_of_coders> <time_to_burnout> <time_to_compile> <time_to_debug> <time_to_refactor> <number_of_compiles_required> <dongle_cooldown> <scheduler>
Arguments
| Argument | Description |
|---|---|
number_of_coders |
Number of coders (also number of dongles) |
time_to_burnout |
Milliseconds before a coder burns out |
time_to_compile |
Milliseconds to complete compilation |
time_to_debug |
Milliseconds spent debugging |
time_to_refactor |
Milliseconds spent refactoring |
number_of_compiles_required |
Compiles needed before successful completion |
dongle_cooldown |
Milliseconds before a released dongle can be reused |
scheduler |
Either fifo or edf |
Example
./coders/codexion 4 1000 200 200 200 10 50 fifo
Cleanup
make clean # Remove object files
make fclean # Remove all build artifacts
make re # Rebuild from scratch
Blocking Cases Handled
Deadlock Prevention (Coffman Conditions)
The implementation avoids deadlock through several mechanisms:
- No circular wait: Coders acquire dongles in a fixed order (left then right for even-indexed coders, right then left for odd-indexed)
- No hold and wait: Coders acquire both dongles before starting to compile, then release both before proceeding
- Preemption: The monitor thread can force termination if burnout occurs
- Mutual exclusion: Each dongle is protected by its own mutex
Starvation Prevention
- FIFO scheduling: Requests are served in arrival order, ensuring fairness
- EDF scheduling: Coders with earliest deadlines are prioritized, guaranteeing progress for those closest to burnout
- Heap implementation: Custom priority queue ensures deterministic ordering even with equal priorities
Dongle Cooldown Handling
- Each dongle tracks its
last_usedtimestamp - After release, a coder must wait for
dongle_cooldownmilliseconds before taking that dongle again - This prevents a single coder from monopolizing a dongle
Precise Burnout Detection
- Dedicated monitor thread continuously checks all coders
- Compares
now() - last_compileagainsttime_to_burnout - Logs burnout within 10ms of actual occurrence
- Sets global
is_overflag to signal all threads to stop
Log Serialization
- Single
print_mutexprotects all output operations - Prevents interleaved messages from multiple threads
- Each state change is atomic and complete
Thread Synchronization Mechanisms
Mutexes (pthread_mutex_t)
- print_mutex: Protects printf operations for log serialization
- over_mutex: Guards the global
is_overflag - condmutex: Per-dongle mutex protecting the wait queue and heap
- info_mutex: Per-coder mutex protecting
last_compileandcompiles_done
Condition Variables (pthread_cond_t)
- Each dongle has a condition variable for signaling when it's available
- Coders wait on
dongle->conduntil they reach the front of the heap - Signal broadcasts wake the next waiting coder after release
Custom Event Implementation
The waiting queue uses a custom min-heap data structure:
- Heap structure: Binary heap with comparator function
- Entry structure: Contains coder pointer, queued_at timestamp, and calculated deadline
- Scheduling: Heap comparator switches between FIFO (queued_at) and EDF (deadline) based on scheduler argument
Race Condition Prevention
- Dongle acquisition: Coders enqueue themselves to the heap while holding
condmutex, then wait on condition variable - Safe state updates: Writing
last_compilehappens while holdinginfo_mutex - Atomic completion check: Monitor locks each coder's
info_mutexbefore reading compile count - Graceful termination:
is_overchecked before and after each phase using mutex-protected function
Resources
POSIX Threads Documentation
Concurrency Concepts
- Deadlock: Deadlock prevention - Coffman conditions and avoidance strategies
- Scheduling Algorithms: EDF Scheduling - Real-time scheduling theory
- Priority Queues: Binary Heap - Efficient implementation of priority queue
AI Usage
AI was used as a learning aid and productivity tool during this project:
- Debugging: Helped identify potential race conditions in initial implementation
- Documentation: Assisted in organizing the README structure and clarifying technical explanations
- Concept explanation: Used to deepen understanding of EDF scheduling and heap data structures
All AI-generated code was thoroughly understood, tested, and integrated according to 42's policy of taking responsibility for submitted work.