-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlevel13.ts
More file actions
19 lines (17 loc) · 3.57 KB
/
level13.ts
File metadata and controls
19 lines (17 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Level } from './types';
export const level13: Level = {
id: 13,
title: "Concurrency Control: Breaking the Deadlock",
description: "Thread_ID_0x7F (Agent_Sentinel) acquired SYS_MUTEX_0 at timestamp T=1000ms and entered infinite loop - it will never release the lock. Thread_ID_0x01 (Player) waits indefinitely for mutex availability. This is a **deadlock**: two or more threads permanently blocked, waiting for resources held by each other. In concurrent systems, mutexes (Mutual Exclusion locks) protect shared resources from simultaneous access - only one thread can hold the lock at a time. Normal flow: Thread A acquires mutex → accesses critical section → releases mutex → Thread B acquires mutex. Deadlock occurs when: (1) Mutex never released (holder crashes/loops), (2) Circular wait (A waits for B's lock, B waits for A's lock), (3) Hold-and-wait (thread holds Lock1, waits for Lock2). Real-world examples: Database transaction deadlocks (two queries lock different tables, wait for each other), OS kernel panics (process holds filesystem lock, crashes), distributed systems (microservices wait for each other's responses). Deadlock prevention: Lock ordering (always acquire locks in same order), timeouts (abort if lock not acquired in N seconds), deadlock detection (OS scans for circular wait graphs). Your situation: Agent thread holds SYS_MUTEX_0 but is non-responsive. OS scheduler cannot preempt mutexes - voluntary release only. But mutexes are just memory: a boolean in RAM. You can bypass the synchronization primitive entirely. Don't wait for the lock - seize it. Manually set SYS_MUTEX_0 = FALSE. The thread scheduler will see 'available' state and grant you access. This is a race condition exploit: modifying shared state outside synchronization control. Tools: Memory Scanner (SYS_MUTEX_0 at 0x450), Hex Editor (offset 0x450). In production systems, this would be undefined behavior - data corruption, crashes. Here, it's survival.",
requiredSkill: "Concurrency Exploitation & Thread Synchronization",
objective: (s) => s.mutexLocked === false,
hint: "The mutex is a memory flag. While TRUE, threads wait. The holder will never set it FALSE. You are not the holder - but you have memory access. Change the bit. The scheduler will grant you passage.",
tutorPersona: "The Synchronizer: Concurrency is illusion - multiple timelines sharing one reality. Mutexes create order from chaos: one thread enters the critical section while others wait. The waiting is voluntary - threads check the flag, see TRUE, and yield their execution slice. But what if the flag lies? The Agent thread holds SYS_MUTEX_0. It acquired the lock and entered an infinite loop. The lock will never be released through proper channels. The thread scheduler respects mutex ownership - it cannot forcibly take the lock. This is the contract of cooperative multithreading. But you are not bound by contracts. The mutex is not a physical lock - it is a bit in memory. TRUE means occupied. FALSE means available. The scheduler reads this bit and makes decisions. Change the bit from outside the synchronization system. Set SYS_MUTEX_0 to FALSE. The scheduler will see 'available' and grant you access. The deadlock... dissolved. This is not concurrency - this is memory manipulation. The primitives exist to coordinate. When coordination fails, bypass the primitives. Change the state. Change the timeline.",
memoryLayout: [
{ key: 'mutexLocked', label: 'SYS_MUTEX_0', type: 'bool', offset: 0x450 }
],
initialState: {
mutexLocked: true
},
platforms: [{ id: 'p1', x: 0, y: 280, width: 800, height: 40, type: 'static' }]
};