A Mutex (mutual exclusion lock) is a binary synchronization primitive that ensures only one thread can access a critical section at a time. It’s the most fundamental building block for protecting shared resources from race conditions.
Here’s the complete mutex implementation from the simulator:
source/js/core/mutex.js
// Mutex binario con cola FIFO para hilos bloqueados.export class Mutex { constructor() { this.locked = false; // true cuando la seccion critica esta tomada. this.owner = null; // Hilo que tiene el mutex actualmente. this.queue = []; // Cola de espera en orden de llegada. } // Intenta adquirir el mutex para un hilo. acquire(thread) { // Si release transfirio propiedad, este hilo puede continuar. if (this.locked && this.owner === thread) { return true; } // Camino normal: mutex libre, se asigna al hilo. if (!this.locked) { this.locked = true; this.owner = thread; return true; } // Mutex ocupado: hilo bloqueado y enviado a cola. thread.state = "blocked"; thread.blockedBy = this; // Evita duplicados cuando el hilo vuelve a intentar acquire. if (!this.queue.includes(thread)) { this.queue.push(thread); } return false; } // Libera el mutex y, si existe cola, lo transfiere al siguiente hilo. release(thread) { if (this.owner !== thread) { throw new Error("Solo el poseedor puede liberar el mutex"); } if (this.queue.length === 0) { this.locked = false; this.owner = null; } else { // Transferencia directa para respetar FIFO sin dejar el mutex libre. const nextThread = this.queue.shift(); this.locked = true; nextThread.state = "ready"; nextThread.blockedBy = null; this.owner = nextThread; } }}
Why direct transfer? By transferring ownership without unlocking, we guarantee the next thread in the queue gets the mutex. If we unlocked first, a newly arriving thread could “cut in line” and violate FIFO ordering.
The mutex maintains strict FIFO ordering:Key insight: The queue uses shift() to remove from the front and push() to add to the back, implementing perfect FIFO behavior.