Skip to content

Enjot/ropeway-simulation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

213 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ropeway Simulation (C11 + System V IPC)

Multi-process chairlift/ropeway simulation using C11 and System V IPC (msg/sem/shm) on Linux.

Build & Run

cd ropeway-simulation
mkdir -p build && cd build
cmake ..
cmake --build .

# Run with default config (../config/default.conf)
./ropeway_simulation

# Run with specific config
./ropeway_simulation test1_capacity.conf

# Save logs to file (no terminal output)
./ropeway_simulation > simulation.log 2>&1

Config files are located in ../config/ relative to the binary.

Running Tests

# Run all tests
cd tests
./run_all.sh

# Run by category
./run_all.sh integration  # Tests 1-4: Basic functionality
./run_all.sh stress       # Tests 5-8: High load scenarios
./run_all.sh edge         # Tests 9-13: Edge cases
./run_all.sh recovery     # Tests 14-16: Crash recovery
./run_all.sh signal       # Tests 17-18, 20: Signal handling
./run_all.sh sync         # Test 19: Synchronization

# Run individual test
cd build
bash ../tests/test1_capacity.sh

Core Concepts

The simulation demonstrates classical Unix IPC patterns through a real-world scenario:

Process Model — Each logical component runs as a separate process created via the fork()+exec() pattern. Seven distinct process types cooperate: the orchestrating Main process, a dedicated TimeServer for clock management, Cashier for ticket sales, two platform Workers (lower/upper), a TouristGenerator, and individual Tourist processes.

Inter-Process Communication — All coordination happens through System V primitives:

  • Five message queues handle request-response flows between tourists, cashier, and workers
  • A shared memory segment stores global simulation state accessible to all processes
  • Ten semaphores control concurrent access to station capacity, chairlift slots, entry/exit gates, and emergency coordination

Signal-Driven Events — The system responds to various signals for different purposes:

  • SIGUSR1/SIGUSR2 coordinate emergency stop and resume between workers
  • SIGTSTP/SIGCONT (Ctrl+Z / fg) pause and resume the entire simulation with proper time offset tracking
  • SIGALRM triggers periodic checks and timeouts
  • SIGCHLD is handled by a dedicated zombie reaper thread via sigwait() to reap terminated children

Defensive Design — Every system call checks for errors and handles EINTR interrupts. IPC resources are cleaned up on both graceful shutdown and crash recovery. All user-provided configuration values are validated before use.

Technical Constraints

Aspect Requirement
Language C11 standard, compiled with CMake 3.18+
Dependencies Standard library, pthreads, System V IPC only
IPC Exclusively System V (no POSIX semaphores/queues)
Process creation fork() + exec() for workers, no process pools
Threading Limited to kid simulation within Tourist and zombie reaper in Main
Permissions All IPC objects use 0600 mode
Cleanup Resources removed via IPC_RMID on shutdown; ipcs empty after exit

Simulation Flow

The chairlift operates through a chain of coordinated steps:

  1. Initialization — Main generates IPC keys with ftok(), creates all resources (ipc_create), then spawns worker processes (process spawning)

  2. Time Management — TimeServer atomically updates simulated clock every 10ms (update_sim_time), compensating for any shell-level pauses (pause handling)

  3. Tourist Generation — Generator creates tourist processes with randomized attributes (age, type, VIP status) via fork()+execl() (tourist_generator_main)

  4. Ticket Purchase — Each tourist sends a request to the Cashier queue and waits for a response with pricing and validity (cashier_main)

  5. Station Entry — Tourist acquires entry gate and station capacity semaphores, then joins the platform queue (tourist lifecycle)

  6. Boarding — LowerWorker collects tourists into chairs (max 4 slots), acquires a chair semaphore, and dispatches (dispatch_chair, lower_worker_main)

  7. Arrival — UpperWorker tracks arrivals per chair and releases the chair semaphore when all passengers have disembarked (upper_worker_main)

  8. Trail Descent — Tourist simulates walking or biking down, then either re-enters for another ride or exits when ticket expires

  9. Emergency Protocol — When danger is detected, workers coordinate via SIGUSR1/SIGUSR2 signals plus message queue handshake to safely halt and resume operations (worker_trigger_emergency_stop, worker_initiate_resume)

Process Architecture

Process File Purpose
Main src/main.c Orchestrator: IPC creation, worker spawning, signal handling, zombie reaping
TimeServer src/processes/time_server.c Atomic time updates, SIGTSTP/SIGCONT pause offset
Cashier src/processes/cashier.c Ticket sales with age discounts and VIP surcharges
LowerWorker src/processes/lower_worker.c Lower platform boarding management
UpperWorker src/processes/upper_worker.c Upper platform arrivals and chair release
TouristGenerator src/processes/tourist_generator.c Spawns tourist processes via fork+exec
Tourist src/tourist/main.c Individual tourist lifecycle (buy ticket, ride, descend)

IPC Reference

  • SharedState structure with flexible array member for per-tourist tracking
  • Atomic current_sim_time_ms updated by TimeServer (line 47)
  • Global flags: running, closing, emergency_stop (lines 50-53)
  • Statistics: total_tourists, total_rides, rides_by_ticket[] (lines 56-59)
  • Process PIDs for signal handling (lines 91-96)
Index Name Purpose Initial Value
0 SEM_STATE Mutex for SharedState 1
1 SEM_STATS Mutex for statistics 1
2 SEM_ENTRY_GATES Entry gate slots 4
3 SEM_EXIT_GATES Exit gate slots 2
4 SEM_LOWER_STATION Station capacity config
5 SEM_CHAIRS Chair availability 36
6 SEM_WORKER_READY Startup barrier 0
7 SEM_PLATFORM_GATES Platform gates 3
8 SEM_EMERGENCY_CLEAR Emergency release 0
9 SEM_EMERGENCY_LOCK Emergency mutex 1

Semaphore operations: src/ipc/sem.c

Message Queues (include/ipc/messages.h)

Queue ID Direction Message Type
MQ_CASHIER 1 Tourist <-> Cashier CashierMsg
MQ_PLATFORM 2 Tourist → LowerWorker PlatformMsg
MQ_BOARDING 3 LowerWorker → Tourist PlatformMsg
MQ_ARRIVALS 4 Tourist → UpperWorker ArrivalMsg
MQ_WORKER 5 Worker <-> Worker WorkerMsg

VIP Priority: Regular tourists use mtype=2, VIPs use mtype=1; msgrcv with -2 retrieves lowest mtype first (VIPs first).

Signal Handling

Signal handlers

Signal usage

Signal Purpose
SIGCHLD Zombie reaping via dedicated thread (sigwait())
SIGTERM/SIGINT Graceful shutdown
SIGALRM Periodic time checks, emergency timeouts
SIGUSR1 Emergency stop notification
SIGUSR2 Resume notification
SIGTSTP Pause simulation (shell Ctrl+Z)
SIGCONT Resume simulation (shell fg)

Function Documentation

Main Process (src/main.c)

Signal workers to stop and destroy IPC to unblock blocked operations.

Entry point: load config, block SIGCHLD, create IPC, start zombie reaper thread, spawn workers, run main loop.


IPC Management (src/ipc/ipc.c)

Clean up stale IPC resources from a previous crashed run. Checks if shared memory exists and if the stored main_pid is dead.

  • Parameters: keys - IPC keys to check
  • Returns: 1 if stale resources cleaned, 0 if no stale resources, -1 on error

Create all IPC resources (shared memory, semaphores, message queues).

  • Parameters: res - IPC resources struct to populate, keys - IPC keys, cfg - configuration
  • Returns: 0 on success, -1 on error

Attach child process to existing IPC resources.

  • Parameters: res - IPC resources struct to populate, keys - IPC keys
  • Returns: 0 on success, -1 on error

Destroy all IPC resources (message queues, semaphores, shared memory).

  • Parameters: res - IPC resources to destroy

Signal-safe IPC cleanup for use in signal handlers. Only uses async-signal-safe syscalls (msgctl, semctl, shmctl). Cleanup order: MQ → Semaphores → SHM (unblocks waiting processes first).

  • Parameters: res - IPC resources to clean up

Semaphore Operations (src/ipc/sem.c)

Create and initialize semaphore set with configured values.

  • Parameters: res - IPC resources, key - semaphore key, cfg - configuration
  • Returns: 0 on success, -1 on error

Atomically wait (decrement) a semaphore by count. Blocks until count slots are available, then acquires all at once.

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index, count - number of slots to acquire
  • Returns: 0 on success, -1 on error/interrupt

Semaphore wait with EINTR handling. Kernel handles SIGTSTP/SIGCONT automatically (process gets suspended). Only returns -1 on shutdown (EIDRM) or other errors.

  • Parameters: res - IPC resources, sem_num - semaphore index, count - number of slots
  • Returns: 0 on success, -1 on shutdown/error

Atomically post (increment) a semaphore by count. Releases count slots at once.

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index, count - number of slots to release
  • Returns: 0 on success, -1 on error

SIGTSTP handler - capture pause start time and suspend. Uses SA_RESETHAND so handler is automatically reset to SIG_DFL before this handler runs. After capture, raises SIGTSTP again to actually suspend the process.

  • Parameters: sig - signal number (unused)

SIGCONT handler - signal that pause has ended. Reinstalls the SIGTSTP handler (sigaction is async-signal-safe). Actual pause offset calculation happens in handle_resume().

  • Parameters: sig - signal number (unused)

Handle pause offset calculation after SIGCONT. Called outside signal handler context to safely calculate the pause duration and update the total pause offset.

Update the atomic simulated time in SharedState. Calculates current simulated time accounting for pause offsets and stores it atomically for other processes to read.

  • Parameters: state - shared state to update

Time Server process entry point. Maintains the current simulated time with sub-millisecond precision. Handles SIGTSTP/SIGCONT pause tracking and offset calculation. Atomically updates SharedState.current_sim_time_ms for other processes.

  • Parameters: res - IPC resources (shared memory for time updates), keys - IPC keys (unused)

Calculate ticket expiration time in simulated minutes.

  • Parameters: state - shared state with ticket duration settings, ticket - type of ticket being purchased
  • Returns: Expiration time in simulated minutes from midnight

Calculate ticket price for one person. Age discounts: under 10 years or 65+ get 25% off.

  • Parameters: age - tourist age in years, ticket - type of ticket being purchased, is_vip - whether tourist has VIP status (adds surcharge)
  • Returns: Price in PLN

Calculate total family ticket price. Parent and kids all get the same ticket type. Kids (4-7 years old) always get the under-10 discount.

  • Parameters: parent_age - parent's age in years, ticket - type of ticket for the family, is_vip - whether family has VIP status, kid_count - number of children (0-2)
  • Returns: Total price in PLN for entire family

Cashier process entry point. Handles ticket sales via message queue. Calculates prices with age discounts and VIP surcharges. Runs until station closes or shutdown signal received.

  • Parameters: res - IPC resources (message queues, semaphores, shared memory), keys - IPC keys (unused)

Check for random danger and trigger emergency stop if detected. Uses pause-adjusted time for cooldown calculation.

  • Parameters: res - IPC resources for emergency coordination
  • Returns: 1 if danger was detected, 0 otherwise

Dispatch the current chair with all buffered tourists. Acquires a chair slot, then sends boarding confirmations to all buffered tourists with the same departure_time so they arrive together. The upper_worker releases the chair slot when all tourists have arrived.

  • Parameters: res - IPC resources for semaphores and message queues, chair_number - chair identifier for logging, slots_used - total slots used on this chair

Lower platform worker process entry point. Manages tourist boarding onto chairlift. Buffers tourists until chair is full or queue is empty, then dispatches. Handles emergency stops and random danger detection.

  • Parameters: res - IPC resources (message queues, semaphores, shared memory), keys - IPC keys (unused)

Find or create a tracker for a chair.

  • Parameters: chair_id - chair identifier to find or create tracker for, tourists_on_chair - expected number of tourists on this chair
  • Returns: Pointer to tracker, or NULL if tracking array is full

Upper platform worker process entry point. Processes tourist arrivals at the upper platform. Tracks chairs and releases chair slots when all tourists from a chair have arrived. Handles emergency stops and random danger detection.

  • Parameters: res - IPC resources (message queues, semaphores, shared memory), keys - IPC keys (unused)

Generate random age (8-80) and check if person can have kids. Adults 26+ can be guardians for kids aged 4-7.

  • Parameters: can_have_kids - output: 1 if person can be a guardian, 0 otherwise
  • Returns: Generated age in years

Generate number of kids for a family (1-2). Distribution: ~63% one kid, ~37% two kids. Only called when family_percentage check already passed.

  • Returns: Number of children (1 or 2)

Select ticket type for a tourist. Distribution: 30% single, 20% T1, 20% T2, 15% T3, 15% daily.

  • Returns: Random ticket type

Tourist generator process entry point. Spawns tourist processes with random attributes (age, type, VIP status, ticket type, kids). Uses fork+exec to create tourist processes. Waits for all spawned tourists to exit before returning.

  • Parameters: res - IPC resources (shared memory for config values), keys - IPC keys (unused), tourist_exe - path to tourist executable

Tourist process entry point. Handles complete tourist lifecycle: ticket purchase, ride loop (enter station, board chair, ride, descend trail), and exit when ticket expires.


Emergency Coordination (src/common/worker_emergency.c)

Initiate emergency stop. Attempts to acquire SEM_EMERGENCY_LOCK to become the initiator. If lock acquired, sets emergency_stop flag and signals the other worker via SIGUSR1. If lock not acquired, falls back to receiver role.

  • Parameters: res - IPC resources, role - worker role (WORKER_LOWER or WORKER_UPPER), state - emergency state tracking

Acknowledge emergency stop from the other worker. Sets emergency_stop flag, then blocks waiting for resume message via MQ_WORKER. After resume received, signals ready and clears emergency flag.

  • Parameters: res - IPC resources, role - worker role, state - emergency state tracking

Resume operations after emergency cooldown passed. Sends READY_TO_RESUME message to other worker, waits for I_AM_READY response, sends SIGUSR2, clears emergency flag, and releases SEM_EMERGENCY_LOCK.

  • Parameters: res - IPC resources, role - worker role, state - emergency state tracking

Initialize logger with shared state and component type for colored output.

  • Parameters: state - shared state (for simulation time), comp - component type enum

Formatted log output with simulation timestamp, level, and component tag. Uses colors based on component type when output is a terminal.

  • Parameters: level - log level string, component - component name, fmt - printf-style format string

Async-signal-safe logging using only write(). For use in signal handlers.

  • Parameters: msg - message string to write

Signal-safe integer to string conversion. Does not use any non-async-signal-safe functions.

  • Parameters: n - integer to convert, buf - output buffer, buf_size - buffer size

Configuration (src/core/config.c)

Initialize configuration with default values.

  • Parameters: cfg - configuration structure to initialize

Load configuration from a file. Sets defaults first, then overrides with file values.

  • Parameters: path - path to the configuration file, cfg - configuration structure to populate
  • Returns: 0 on success, -1 on error

Validate configuration values. Prints error messages for invalid values to stderr.

  • Parameters: cfg - configuration structure to validate
  • Returns: 0 if valid, -1 if invalid

Write final simulation summary to file including duration, total tourists, total rides, per-tourist breakdown, and aggregates by ticket type. Report is saved to simulation_report.txt.

  • Parameters: state - shared state with simulation statistics, filepath - output file path
  • Returns: 0 on success, -1 on error

Time Simulation (src/core/time_sim.c)

Initialize time acceleration in shared state. Called once at startup by main process.

  • Parameters: state - shared memory state, cfg - configuration with time settings

Get current simulated time in minutes from midnight.

  • Parameters: state - shared memory state
  • Returns: Simulated minutes from midnight (e.g., 480 = 08:00)

Get current simulated time in minutes from midnight with fractional part.

  • Parameters: state - shared memory state
  • Returns: Simulated minutes from midnight as double

Check if simulation time has ended (past sim_end_minutes).

  • Parameters: state - shared memory state
  • Returns: 1 if simulation is over, 0 otherwise

Check if station is closing (approaching end time).

  • Parameters: state - shared memory state
  • Returns: 1 if closing, 0 otherwise

Convert simulated minutes to real seconds.

  • Parameters: state - shared memory state, sim_minutes - duration in simulated minutes
  • Returns: Duration in real seconds

Sleep for simulated minutes (handles pause via EINTR).

  • Parameters: state - shared memory state, sem_id - semaphore ID, sim_minutes - duration to sleep
  • Returns: 0 on success, -1 if simulation should stop

Format current simulated time as HH:MM string.

  • Parameters: state - shared memory state, buf - output buffer, buf_size - buffer size

Format minutes from midnight as HH:MM string.

  • Parameters: minutes - minutes from midnight, buf - output buffer, buf_size - buffer size

Tourist Lifecycle (src/tourist/lifecycle.c)

Buy ticket at cashier via message queue. For families, parent buys tickets for all kids.

  • Parameters: res - IPC resources, data - tourist data (updated with ticket info)
  • Returns: 0 on success, -1 if rejected or on error

Check if tourist's ticket is still valid.

  • Parameters: res - IPC resources, data - tourist data with ticket info
  • Returns: 1 if valid, 0 if expired

Check if station is closing.

  • Parameters: res - IPC resources
  • Returns: 1 if closing, 0 if open

Check if tourist is too scared to ride (~10% chance on first two rides if enabled).

  • Parameters: res - IPC resources, data - tourist data
  • Returns: 1 if scared, 0 otherwise

Get reason string for scared tourist.

  • Parameters: data - tourist data
  • Returns: Reason string for logging

Tourist Movement (src/tourist/movement.c)

Pause-aware sleep for simulated durations. Handles EINTR from signals.

  • Parameters: res - IPC resources, real_seconds - duration in real seconds, running_flag - pointer to running flag
  • Returns: 0 on success, -1 if interrupted by shutdown

Simulate riding the chairlift to the upper station.

  • Parameters: res - IPC resources, data - tourist data, departure_time - chair departure time, running_flag - pointer to running flag
  • Returns: 0 on success, -1 if interrupted by shutdown

Simulate walking or biking down the trail.

  • Parameters: res - IPC resources, data - tourist data, running_flag - pointer to running flag
  • Returns: 0 on success, -1 if interrupted by shutdown

Tourist Initialization (src/tourist/init.c)

Parse command line arguments and populate tourist data.

  • Parameters: argc - argument count, argv - argument vector, data - tourist data structure
  • Returns: 0 on success, -1 on error

Get logging tag based on tourist type and VIP status.

  • Parameters: data - tourist data
  • Returns: Logging tag string (e.g., "VIP CYCLIST", "FAMILY", "TOURIST")

Install signal handlers for tourist process.

  • Parameters: running_flag - pointer to running flag to clear on SIGTERM/SIGINT

Spawn a worker process via fork.

  • Parameters: worker_func - worker entry point, res - IPC resources, keys - IPC keys, name - worker name for logging
  • Returns: Child PID on success, -1 on error

Spawn the tourist generator process via fork.

  • Parameters: res - IPC resources, keys - IPC keys, tourist_exe - path to tourist executable
  • Returns: Child PID on success, -1 on error

IPC Functions (src/ipc/)

Generate IPC keys using ftok.

  • Parameters: keys - structure to populate, path - file path for key generation
  • Returns: 0 on success, -1 on error

Clean up stale IPC resources from a previous crashed run.

  • Parameters: keys - IPC keys to check
  • Returns: 1 if cleaned, 0 if no stale resources, -1 on error

Detach from IPC resources (for child processes before exit).

  • Parameters: res - IPC resources to detach from

Signal-safe IPC cleanup for use in signal handlers. Only uses async-signal-safe syscalls.

  • Parameters: res - IPC resources to clean up

Atomically wait (decrement) a semaphore by count.

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index, count - slots to acquire
  • Returns: 0 on success, -1 on error or signal interruption

Atomically post (increment) a semaphore by count.

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index, count - slots to release
  • Returns: 0 on success, -1 on error

Non-blocking semaphore wait (try to decrement by 1).

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index
  • Returns: 0 on success, -1 if would block or on error

Semaphore wait with EINTR handling and pause support. Retries on EINTR.

  • Parameters: res - IPC resources, sem_num - semaphore index, count - slots to acquire
  • Returns: 0 on success, -1 on shutdown or error

Get current semaphore value.

  • Parameters: sem_id - semaphore set ID, sem_num - semaphore index
  • Returns: Current value, or -1 on error

Wait for emergency stop to clear. Tracks emergency_waiters for reliable wakeup.

  • Parameters: res - IPC resources

Release all processes waiting for emergency to clear.

  • Parameters: res - IPC resources

Signal that a worker has completed initialization.

  • Parameters: res - IPC resources
  • Returns: 0 on success, -1 on error

Wait for all workers to signal ready.

  • Parameters: res - IPC resources, expected_count - number of workers to wait for
  • Returns: 0 on success, -1 on error/timeout

Initialize signal handling module. Must be called before install_signal_handlers().

  • Parameters: res - pointer to IPC resources for signal-safe cleanup

Install all signal handlers for main process. Sets up SIGCHLD, SIGINT, SIGTERM, SIGALRM handlers.


Reap zombie child processes (non-blocking). Called from main loop when SIGCHLD is received.

Wait for all worker processes to exit (blocking). Called during shutdown.


Tourist Stats (src/tourist/stats.c)

Record tourist entry in shared state for final report.

  • Parameters: res - IPC resources, data - tourist data

Update ride statistics after completing a ride. Counts parent and all kids.

  • Parameters: res - IPC resources, data - tourist data

Tourist Boarding (src/tourist/boarding.c)

Board the chairlift by messaging lower worker.

  • Parameters: res - IPC resources, data - tourist data, departure_time_out - receives departure time, chair_id_out - receives chair ID, tourists_on_chair_out - receives tourist count
  • Returns: 0 on success, -1 on error or shutdown

Arrive at upper station and notify upper worker.

  • Parameters: res - IPC resources, data - tourist data, chair_id - chair ID, tourists_on_chair - tourist count
  • Returns: 0 on success, -1 on error

Tourist Threads (src/tourist/threads.c)

Thread function for kid simulation. Kids log and exit immediately.

  • Parameters: arg - pointer to KidThreadData
  • Returns: NULL

Thread function for bike simulation. Bikes log and exit immediately.

  • Parameters: arg - pointer to BikeThreadData
  • Returns: NULL

Create threads for kids and bike (if cyclist).

  • Parameters: data - tourist data, family - family state, kid_data - kid thread data array, kid_threads - thread handles array, bike_data - bike thread data, bike_thread - bike thread handle, bike_thread_created - output flag
  • Returns: 0 on success, -1 on error

Join all family threads (kids and bike).

  • Parameters: data - tourist data, kid_threads - thread handles array, bike_thread - bike thread handle, bike_thread_created - whether bike thread was created

Configuration Parameters

Config file format: KEY=VALUE with # comments.

Parameter Default Purpose
STATION_CAPACITY 50 Max tourists in lower station
SIMULATION_DURATION_REAL_SECONDS 120 Real time duration
SIM_START_HOUR/SIM_START_MINUTE 8:00 Simulated start time
SIM_END_HOUR/SIM_END_MINUTE 17:00 Simulated end time
CHAIR_TRAVEL_TIME_SIM_MINUTES 1 Chair ride duration (sim minutes)
TOTAL_TOURISTS 100 Tourists to generate (must be > 0)
TOURIST_SPAWN_DELAY_US 10000 Spawn delay (microseconds)
VIP_PERCENTAGE 1 VIP tourist percentage
WALKER_PERCENTAGE 50 Walker vs cyclist ratio
TRAIL_WALK_TIME_SIM_MINUTES 2 Walking trail duration (sim minutes)
TRAIL_BIKE_*_TIME_SIM_MINUTES 1/2/3 Bike trail durations (fast/med/slow)
TICKET_T*_DURATION_SIM_MINUTES 60/120/180 Time ticket durations
DANGER_PROBABILITY 0 Emergency detection (0-100)
DANGER_DURATION_SIM_MINUTES 30 Emergency duration
DEBUG_LOGS_ENABLED 1 Show debug logs
Constant Value Purpose
CHAIR_CAPACITY 4 Max slots per chair
MAX_CHAIRS_IN_TRANSIT 36 Concurrent chairs
TOTAL_CHAIRS 72 Total chairs in system
ENTRY_GATES 4 Entry gate count
EXIT_GATES 2 Exit gate count
PLATFORM_GATES 3 Platform gate count
MAX_KIDS_PER_ADULT 2 Max children per guardian

TouristType: TOURIST_WALKER (0), TOURIST_CYCLIST (1), TOURIST_FAMILY (2)

TicketType: TICKET_SINGLE (0), TICKET_TIME_T1 (1), TICKET_TIME_T2 (2), TICKET_TIME_T3 (3), TICKET_DAILY (4)

TouristStage: 10 lifecycle stages from STAGE_AT_CASHIER (0) to STAGE_LEAVING (9)

Component Color
TOURIST Bright green
VIP Bright red
CASHIER Yellow
LOWER_WORKER Blue
UPPER_WORKER Cyan
GENERATOR Magenta
MAIN White
IPC Gray
TIME_SERVER Bright yellow

Test Suite Details

Integration Tests (1-4)

test1_capacity.sh - Lower Station Capacity Limit

  • Goal: Station visitor count never exceeds N
  • Rationale: Tests for race condition between 4 entry gates incrementing station count via SEM_LOWER_STATION. Without proper semaphore synchronization, concurrent sem_wait() calls could allow count > N briefly.
  • Parameters: station_capacity=5, tourists=15, simulation_time=1s
  • Expected: Max observed count <= 5. No zombies. IPC cleaned.

test2_children.sh - Children Under 8 with Guardians

  • Goal: Children board with guardians, max 2 kids per adult
  • Rationale: Tests atomic multi-slot semaphore acquisition for families. sem_wait_n(SEM_LOWER_STATION, family_size) must be atomic - partial acquisition would split family or cause deadlock if slots < family_size.
  • Parameters: walker_percentage=80, family_percentage=80, tourists=15, simulation_time=1s
  • Expected: Families board together. No adult has >2 kids. No deadlock.

test3_vip.sh - VIP Priority Without Queue Starvation

  • Goal: VIPs skip entry gates while regular tourists wait in queue
  • Rationale: VIPs bypass SEM_ENTRY_GATES entirely, reaching the platform faster when gates are congested. Verifies VIPs log "skipped gate queue" while regulars log "entered through gate", and both groups are served.
  • Parameters: vip_percentage=30, tourists=30, simulation_time=1s
  • Expected: VIPs skip gates, regulars enter gates, both groups served.

test4_emergency.sh - Emergency Stop and Resume (Signals)

  • Goal: SIGUSR1 stops chairlift, SIGUSR2 resumes after worker confirmation
  • Rationale: Tests signal handler coordination via SEM_EMERGENCY_LOCK and SEM_EMERGENCY_CLEAR. Race condition possible if both workers try to initiate emergency simultaneously. Resume requires both workers to signal ready.
  • Parameters: SIGUSR1/SIGUSR2 injection with 0.5s delays, simulation_time=3s
  • Expected: Emergency stop logged. Resume only after both workers ready.

Stress Tests (5-8)

test5_stress.sh - High Throughput Stress Test

  • Goal: Simulation completes without timeout under high concurrency
  • Rationale: Tests for deadlock between MQ_CASHIER, MQ_PLATFORM, MQ_BOARDING under load. Concurrent tourists stress all semaphores and message queues simultaneously - exposes circular wait conditions or semaphore exhaustion.
  • Parameters: tourists=6000, station_capacity=500, simulation_time=180s, rapid spawn (no delay)
  • Expected: No timeout (deadlock). No zombies. IPC cleaned.

test6_race.sh - Entry Gate Race Condition Test

  • Goal: Capacity N=5 never exceeded across 10 iterations
  • Rationale: Tests TOCTOU race in SEM_LOWER_STATION. Multiple tourists calling sem_wait() simultaneously could interleave check-and-decrement operations. 10 iterations increases probability of catching intermittent race.
  • Parameters: tourists=10, N=5, simulation_time=3s, 10 iterations
  • Expected: Count <= 5 in all iterations. 100% pass rate.

test7_emergency_race.sh - Emergency Race Condition Test

  • Goal: Only one worker initiates emergency when both detect danger
  • Rationale: Tests race on SEM_EMERGENCY_LOCK when lower_worker and upper_worker both call sem_trywait() simultaneously. Double-initiation would corrupt emergency state or cause deadlock waiting on SEM_EMERGENCY_CLEAR.
  • Parameters: danger_probability=100, tourists=10, simulation_time=3s
  • Expected: Single initiator per emergency. No deadlock. System recovers.

test8_chair_saturation.sh - Chair Saturation Test

  • Goal: Tourists block on SEM_CHAIRS when all 36 chairs are in transit
  • Rationale: Tests semaphore blocking behavior when SEM_CHAIRS reaches zero. Fast boarding + slow travel saturates chairs. Verifies sem_wait() blocks correctly and sem_post() from arrivals unblocks waiting tourists.
  • Parameters: tourists=20, station_capacity=50, simulation_time=3s
  • Expected: Max 36 chairs in transit. No deadlock on chair exhaustion.

Edge Case Tests (9-13)

test9_zero.sh - Zero Tourists Edge Case

  • Goal: Graceful rejection of invalid configuration (0 tourists)
  • Rationale: Tests config validation. TOTAL_TOURISTS=0 is rejected at startup with clear error message. Verifies no IPC resources are leaked when startup fails early.
  • Parameters: tourists=0, simulation_time=1s
  • Expected: Config rejected gracefully. No IPC leaks from failed startup.

test10_single.sh - Single Tourist Edge Case

  • Goal: One tourist completes full lifecycle without concurrency
  • Rationale: Baseline test - verifies message passing chain works: tourist→MQ_CASHIER→cashier→MQ_PLATFORM→lower_worker→MQ_BOARDING→tourist→MQ_ARRIVALS→upper_worker. No concurrency masks IPC bugs.
  • Parameters: tourists=1, walker, simulation_time=1s
  • Expected: Tourist completes ride. All IPC handoffs succeed.

test11_capacity_one.sh - Capacity One Edge Case

  • Goal: Only 1 tourist in station at any time with N=1
  • Rationale: Tests convoy effect on SEM_LOWER_STATION. With N=1, all tourists serialize on single semaphore slot. Potential for priority inversion or starvation if sem_wait() ordering is unfair.
  • Parameters: N=1, tourists=10, simulation_time=1s
  • Expected: Max count=1. All tourists eventually served. No deadlock.

test12_all_vip.sh - All VIPs Edge Case

  • Goal: All tourists served when everyone has same mtype=1 priority
  • Rationale: Tests msgrcv() behavior when all messages have identical mtype. Verifies FIFO ordering within same priority level. Edge case where priority differentiation provides no benefit - system must still function.
  • Parameters: vip_percentage=100, tourists=10, simulation_time=1s
  • Expected: FIFO order maintained. All tourists served. No starvation.

test13_all_families.sh - All Families Edge Case

  • Goal: Families board atomically without splitting
  • Rationale: Tests semop() with sem_op > 1 for atomic multi-slot acquisition. Family of 3 must acquire 3 slots atomically - partial acquisition would split family or deadlock if remaining capacity < family_size.
  • Parameters: walker_percentage=100, family_percentage=100, tourists=10, simulation_time=1s
  • Expected: No split families. Atomic acquisition verified. No deadlock.

Recovery Tests (14-16)

test14_sigterm.sh - SIGTERM Cleanup Test

  • Goal: No orphaned IPC resources after SIGTERM shutdown
  • Rationale: Tests ipc_cleanup() is called from SIGTERM handler. Semaphores, shared memory, and message queues must be released via semctl(RMID), shmctl(RMID), msgctl(RMID). Leaked IPC persists until reboot.
  • Parameters: Uses test1_capacity.conf (1s, 15 tourists), SIGTERM mid-run
  • Expected: ipcs empty after shutdown. No zombies. All children terminated.

test15_sigkill_recovery.sh - SIGKILL Recovery Test

  • Goal: New run cleans orphaned IPC from previous crash
  • Rationale: SIGKILL bypasses signal handlers - no ipc_cleanup() runs. Tests ipc_cleanup_stale() at startup: must detect orphaned resources via ftok() key collision and remove before creating new IPC objects.
  • Parameters: Uses test1_capacity.conf, SIGKILL first run, start second run
  • Expected: Second run succeeds. Stale IPC cleaned. Log shows cleanup.

test16_child_death.sh - Child Death Test

  • Goal: Main process shuts down gracefully when child dies unexpectedly
  • Rationale: Tests SIGCHLD handler and zombie reaper thread. Killing cashier mid-run must trigger: waitpid() reaps child, main detects worker death, initiates shutdown. Without proper handling: zombies or orphaned children.
  • Parameters: Uses test1_capacity.conf, kill cashier mid-simulation
  • Expected: Main detects death. Graceful shutdown. No zombies or IPC leaks.

Signal Tests (17-18)

test17_pause_resume.sh - Pause/Resume Test (SIGTSTP/SIGCONT)

  • Goal: Simulated time offset adjusts for pause duration
  • Rationale: Tests SIGTSTP/SIGCONT handlers in time_server. Pause duration must be added to time_offset so accelerated simulation time doesn't jump. Without offset adjustment: tickets expire during pause, time discontinuity.
  • Parameters: Uses test1_capacity.conf (1s simulation), SIGTSTP then SIGCONT
  • Expected: Time continues smoothly after resume. No expired tickets.

test18_rapid_signals.sh - Rapid Signals Test

  • Goal: No crash under rapid signal delivery to worker processes
  • Rationale: Tests signal handler reentrancy in workers. Rapid SIGUSR1 can interrupt handler mid-execution. Main process does not handle SIGUSR1 (default action terminates), so signals are sent to child worker processes. Non-async-signal-safe functions in handler cause undefined behavior.
  • Parameters: 10 SIGUSR1 signals with 50ms delay, sent to child process
  • Expected: No segfault. No hang. Simulation survives signal storm.

Sync Correctness Tests (19)

test19_sigalrm_sync.sh - SIGALRM Sync Test

  • Goal: Verify simulation works with SIGALRM-based sync (no usleep polling)
  • Rationale: Confirms refactored code uses blocking IPC + alarm() correctly. All IPC_NOWAIT+usleep polling has been replaced with blocking calls that use SIGALRM for periodic wakeup. EINTR handled properly on alarm interrupt.
  • Parameters: tourists=15, simulation_time=1s (uses test1_capacity.conf)
  • Expected: Simulation completes. No deadlock. No leftover IPC.

test20_sigint_emergency.sh - SIGINT During Emergency Stop

  • Goal: Graceful shutdown when Ctrl+C is sent during emergency stop
  • Rationale: Workers blocked on msgrcv() during emergency handshake must wake up on SIGINT (EINTR) and proceed with shutdown. Emergency lock (SEM_EMERGENCY_LOCK) must be released. IPC cleanup must complete even when chairlift is stopped.
  • Parameters: danger_probability=100, danger_duration=120min (long duration ensures SIGINT hits during emergency)
  • Expected: Clean shutdown within 15s. No zombies. No orphaned processes. No leftover IPC.

Test Output

Tests check for:

  • Capacity violations: Station count never exceeds configured limit
  • Zombie processes: No defunct processes after shutdown
  • IPC cleanup: ipcs shows no leftover resources
  • Log analysis: Parses simulation logs for expected behavior

Compliance Notes

  • C11 + CMake 3.18: No external dependencies
  • System V IPC only: No POSIX IPC
  • fork+exec: All workers spawned via fork+exec pattern
  • ftok: All IPC keys generated via ftok
  • Signal safety: Only async-signal-safe functions in handlers
  • EINTR handling: All blocking operations handle interrupts
  • IPC cleanup: Resources destroyed on shutdown via IPC_RMID
  • Threads: Only for kids/bikes within Tourist process and zombie reaper

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors