Skip to main content
Sogen emulates Windows threading using a cooperative round-robin scheduler. Unlike preemptive multithreading, threads explicitly yield control at regular intervals, allowing deterministic execution for analysis and debugging.

Threading Model

Cooperative Scheduling

Sogen threads are not OS threads—they exist entirely within the emulator: Benefits:
  • Determinism: Same inputs always produce same execution order
  • Debugging: Easier to reproduce race conditions
  • Control: Precise instrumentation and analysis
  • Simplicity: No OS thread synchronization needed

Thread Structure

From emulator_thread.hpp:192:

Thread Creation

Threads are created via NtCreateThreadEx syscall:
From process_context.cpp:

Thread Initialization

From emulator_thread.cpp:

Thread Scheduling

Time Slices

Threads execute in fixed instruction quanta:
From windows_emulator.cpp:18. After each time slice, the scheduler checks if a thread switch is needed:

Yielding

This signals the main loop to switch threads.

Thread Selection

From windows_emulator.cpp:211:

Thread Readiness

From emulator_thread.cpp:62:

Context Switching

Thread Synchronization

Waiting for Objects

Asynchronous Procedure Calls (APCs)

APCs allow queuing work to a specific thread:
From emulator_thread.hpp:12. When a thread is alertable and has pending APCs:

Thread Termination

Threads can terminate via:
  1. Return from entry point: RtlUserThreadStart calls NtTerminateThread
  2. Explicit termination: NtTerminateThread syscall
  3. Process exit: All threads terminated when process exits
Terminated threads are cleaned up during context switch:

Next Steps