Overview
Instructions are the individual operations that threads execute. Each instruction has a type field and optional parameters. The execution engine processes instructions using a dispatcher pattern.
Instruction Types
All instruction types are defined in instructions.js:
export const Instructions = {
ACQUIRE: "acquire" , // Intentar tomar el mutex.
WITHDRAW: "withdraw" , // Retirar dinero de la cuenta.
DEPOSIT: "deposit" , // Ingresar dinero en la cuenta.
RELEASE: "release" , // Soltar el mutex.
WAIT_SEM: "wait_sem" , // Intentar tomar un token del semaforo.
PRINT: "print" , // Simular impresion de trabajo.
SIGNAL_SEM: "signal_sem" , // Liberar token del semaforo.
WAIT_FOOD: "wait_food" , // Cliente espera comida si aun no esta lista.
EAT_FOOD: "eat_food" , // Cliente consume el plato reservado.
COOK_DISH: "cook_dish" , // Chef prepara un plato.
SIGNAL_FOOD: "signal_food" , // Chef avisa que hay comida lista.
ENTER_READ: "enter_read" , // Lector intenta entrar al monitor en modo lectura.
READ_BOOK: "read_book" , // Lector lee el libro compartido.
EXIT_READ: "exit_read" , // Lector sale del monitor.
ENTER_WRITE: "enter_write" , // Escritor intenta entrar al monitor en modo escritura.
UPDATE_CATALOG: "update_catalog" , // Escritor actualiza catalogo.
EXIT_WRITE: "exit_write" , // Escritor sale del monitor.
RUN_STAGE: "run_stage" , // Corredor avanza en un tramo de la carrera.
BARRIER_WAIT: "barrier_wait" , // Corredor espera en checkpoint hasta que lleguen todos.
BUILD_STAGE: "build_stage" , // Trabajador construye una etapa de la casa.
JOIN_THREAD: "join_thread" , // Espera a que termine un hilo especifico.
AWAIT_ALL: "await_all" , // Espera a que termine un grupo de hilos.
COMPLETE_HOUSE: "complete_house" , // Marca entrega final de la casa.
PETERSON_LOCK: "peterson_lock" , // Robot intenta entrar a estacion compartida.
USE_STATION: "use_station" , // Robot usa la estacion critica.
PETERSON_UNLOCK: "peterson_unlock" , // Robot libera estacion compartida.
END: "end" , // Finalizar ejecucion del hilo.
};
Mutex Instructions
Used in the Bank Scenario to protect critical sections.
ACQUIRE
Attempts to acquire a mutex lock. Blocks if the mutex is already held.
{ type : Instructions . ACQUIRE }
Execution:
case Instructions . ACQUIRE :
if ( mutex . acquire ( thread )) {
thread . nextInstruction ();
return `🔑 ${ thread . name } entro en Seccion Critica` ;
}
return `🔒 ${ thread . name } esta esperando el Mutex` ;
If the mutex is unavailable, the thread does NOT advance its program counter and will retry in the next step.
RELEASE
Releases a previously acquired mutex lock.
{ type : Instructions . RELEASE }
Execution:
case Instructions . RELEASE :
mutex . release ( thread );
thread . nextInstruction ();
return `🔓 ${ thread . name } salio y libero el Mutex` ;
Example: Mutex Protection
const instructions = [
{ type: Instructions . ACQUIRE }, // Enter critical section
{ type: Instructions . WITHDRAW , amount: 100 }, // Protected operation
{ type: Instructions . RELEASE }, // Exit critical section
{ type: Instructions . END }
];
Bank Instructions
Operations on a shared bank account.
WITHDRAW
Withdraws money from the shared account. Never allows negative balance.
{ type : Instructions . WITHDRAW , amount : 100 }
Parameters:
amount - Amount to withdraw (number)
Execution:
case Instructions . WITHDRAW :
const requested = Number ( inst . amount ) || 0 ;
const allowed = Math . min ( requested , Math . max ( 0 , account . balance ));
account . balance -= allowed ;
thread . nextInstruction ();
if ( allowed < requested ) {
return `⚠️ ${ thread . name } pidio retirar $ ${ requested } , pero solo se retiro $ ${ allowed } (saldo insuficiente)` ;
}
return `💸 ${ thread . name } modifico el saldo: -$ ${ allowed } ` ;
DEPOSIT
Deposits money into the shared account.
{ type : Instructions . DEPOSIT , amount : 150 }
Parameters:
amount - Amount to deposit (number)
Execution:
case Instructions . DEPOSIT :
account . balance += inst . amount ;
thread . nextInstruction ();
return `💵 ${ thread . name } ingreso al saldo: +$ ${ inst . amount } ` ;
Semaphore Instructions
Used in the Printer Scenario to manage limited resources.
WAIT_SEM
Attempts to acquire a semaphore token and printer. Blocks if none available.
{ type : Instructions . WAIT_SEM }
Execution:
case Instructions . WAIT_SEM : {
const printerIndex = ctx . semaphore . wait ( thread , ctx . printers );
if ( printerIndex !== null ) {
thread . nextInstruction ();
return `🟢 ${ thread . name } obtuvo Impresora- ${ printerIndex + 1 } ` ;
}
return `⏳ ${ thread . name } espera una impresora libre` ;
}
PRINT
Simulates printing pages on the assigned printer.
{ type : Instructions . PRINT , pages : 5 }
Parameters:
pages - Number of pages to print (number)
Execution:
case Instructions . PRINT : {
const pages = Math . max ( 1 , Number ( inst . pages ) || 1 );
const printerIndex = ctx . semaphore . getAssignedPrinter ( thread );
thread.nextInstruction();
if ( printerIndex === null ) {
return `⚠️ ${ thread . name } no tiene impresora asignada` ;
}
return `🖨️ ${ thread . name } imprime ${ pages } paginas en Impresora- ${ printerIndex + 1 } ` ;
}
SIGNAL_SEM
Releases the semaphore token and printer.
{ type : Instructions . SIGNAL_SEM }
Execution:
case Instructions . SIGNAL_SEM : {
const printerIndex = ctx . semaphore . getAssignedPrinter ( thread );
if ( printerIndex !== null && ctx.printers?.[ printerIndex ]) {
const printer = ctx . printers [ printerIndex ];
const pages = Math . max ( 1 , Number ( thread . jobPages ) || 1 );
printer . completedJobs += 1 ;
printer . totalPages += pages ;
printer . lastCompletedJob = { name: thread . name , pages };
}
const transfer = ctx . semaphore . signal ( thread , ctx . printers );
thread.nextInstruction();
if (transfer.nextThread) {
return `🔁 ${ thread . name } libera Impresora- ${ printerIndex + 1 } y la pasa a ${ transfer . nextThread . name } ` ;
}
return `✅ ${ thread . name } libera Impresora- ${ printerIndex + 1 } ` ;
}
Example: Semaphore Usage
const instructions = [
{ type: Instructions . WAIT_SEM }, // Acquire printer
{ type: Instructions . PRINT , pages: 10 }, // Use printer
{ type: Instructions . SIGNAL_SEM }, // Release printer
{ type: Instructions . END }
];
Condition Variable Instructions
Used in the Restaurant Scenario for producer-consumer coordination.
WAIT_FOOD
Customer waits for food to be available.
{ type : Instructions . WAIT_FOOD }
Execution:
case Instructions . WAIT_FOOD : {
if (ctx.restaurant.availableDishes > 0) {
ctx . restaurant . availableDishes -= 1 ;
thread . hasReservedDish = true ;
thread . nextInstruction ();
return `🍽️ ${ thread . name } recibio un plato y pasa a comer` ;
}
thread. state = "blocked" ;
thread. blockedBy = ctx . restaurant . foodCondition ;
ctx.restaurant.foodCondition.wait(thread);
return `🪑 ${ thread . name } espera comida en el restaurante` ;
}
EAT_FOOD
Customer consumes their reserved dish.
{ type : Instructions . EAT_FOOD }
COOK_DISH
Chef prepares a dish.
{ type : Instructions . COOK_DISH }
Execution:
case Instructions . COOK_DISH : {
ctx.restaurant.availableDishes += 1 ;
ctx.restaurant.totalCooked += 1 ;
thread.nextInstruction ();
return `👨🍳 ${ thread . name } preparo un plato ( ${ ctx . restaurant . totalCooked } / ${ ctx . restaurant . mealsTarget } )` ;
}
SIGNAL_FOOD
Chef signals that food is ready, waking a waiting customer.
{ type : Instructions . SIGNAL_FOOD }
Execution:
case Instructions . SIGNAL_FOOD : {
const awakened = ctx . restaurant . foodCondition . signal ();
thread.nextInstruction();
if (! awakened ) {
return `📣 ${ thread . name } anuncio comida, pero no habia clientes esperando` ;
}
awakened. state = "ready" ;
awakened. blockedBy = null ;
return `🔔 ${ thread . name } llamo a ${ awakened . name } : comida lista` ;
}
Monitor Instructions
Used in the Library Scenario for readers-writers synchronization.
ENTER_READ / EXIT_READ
Readers enter and exit the monitor in shared read mode.
{ type : Instructions . ENTER_READ }
{ type : Instructions . EXIT_READ }
READ_BOOK
Reads a book while holding read access.
{ type : Instructions . READ_BOOK , title : "Libro-1" }
Parameters:
title - Book title (string, optional)
ENTER_WRITE / EXIT_WRITE
Writers enter and exit the monitor in exclusive write mode.
{ type : Instructions . ENTER_WRITE }
{ type : Instructions . EXIT_WRITE }
UPDATE_CATALOG
Updates the library catalog (requires write access).
{ type : Instructions . UPDATE_CATALOG }
Execution:
case Instructions . UPDATE_CATALOG : {
ctx.library.catalogVersion += 1 ;
ctx.library.totalWrites += 1 ;
thread.nextInstruction ();
return `🗂️ ${ thread . name } actualizo catalogo a version ${ ctx . library . catalogVersion } ` ;
}
Barrier Instructions
Used in the Race Scenario for synchronization points.
RUN_STAGE
Runner advances through a race stage.
{ type : Instructions . RUN_STAGE , stage : "to-checkpoint" }
{ type : Instructions . RUN_STAGE , stage : "to-finish" }
Parameters:
stage - Stage identifier (string)
BARRIER_WAIT
Runner waits at checkpoint until all runners arrive.
{ type : Instructions . BARRIER_WAIT }
Execution:
case Instructions . BARRIER_WAIT : {
const result = ctx . race . barrier . arrive ( thread );
if (!result.passed) {
return `🧱 ${ thread . name } espera en el checkpoint ( ${ ctx . race . barrier . waitingQueue . length } / ${ ctx . race . totalRacers - 1 } en cola)` ;
}
if (!thread.passedCheckpoint) {
thread . passedCheckpoint = true ;
ctx . race . passedCheckpointCount += 1 ;
}
thread.nextInstruction();
if (!result.opened) {
return `✅ ${ thread . name } cruza el checkpoint tras apertura de barrera` ;
}
const releasedNames = result . released . map (( t ) => t . name ). join ( ", " );
return `🚦 ${ thread . name } abrio barrera y libero a: ${ releasedNames } ` ;
}
Thread Coordination Instructions
Used in the House Scenario for task dependencies.
BUILD_STAGE
Worker builds a construction stage over multiple ticks.
{ type : Instructions . BUILD_STAGE , stage : "Cimientos" , duration : 3 }
Parameters:
stage - Stage name (string)
duration - Number of ticks required (number)
Execution:
case Instructions . BUILD_STAGE : {
const stage = inst . stage || "Etapa" ;
const total = Math . max ( 1 , Number ( inst . duration ) || 1 );
const progressMap = ( thread . stageProgress ??= {});
const current = ( progressMap [ stage ] ?? 0 ) + 1 ;
progressMap [stage] = current;
if (current < total) {
return `🧱 ${thread.name} construye ${stage} (${current}/${total})`;
}
if (ctx.house?.stages?.[stage]) {
ctx.house.stages[stage].done = true;
}
thread.nextInstruction();
return `🏗️ ${thread.name} termino ${stage}`;
}
BUILD_STAGE is the only instruction that executes over multiple ticks without advancing the program counter until completion.
JOIN_THREAD
Waits for a specific thread to finish.
{ type : Instructions . JOIN_THREAD , target : "Maestro-Cimientos" }
Parameters:
target - Name of thread to wait for (string)
Execution:
case Instructions . JOIN_THREAD : {
const target = inst . target ;
const ready = ctx . joinManager . join ( thread , target );
if (! ready ) {
thread . state = "blocked" ;
thread . blockedBy = ctx . joinManager ;
return `⛓️ ${ thread . name } espera join de ${ target } ` ;
}
thread.nextInstruction();
return `✅ ${ thread . name } join cumplido con ${ target } ` ;
}
AWAIT_ALL
Waits for multiple threads to finish.
{ type : Instructions . AWAIT_ALL , targets : [ "Techador" , "Instalador" ] }
Parameters:
targets - Array of thread names to wait for (string[])
COMPLETE_HOUSE
Marks house construction as complete.
{ type : Instructions . COMPLETE_HOUSE }
Peterson’s Algorithm Instructions
Used in the Peterson Scenario for two-thread mutual exclusion.
PETERSON_LOCK
Attempts to enter critical section using Peterson’s algorithm.
{ type : Instructions . PETERSON_LOCK }
Execution:
case Instructions . PETERSON_LOCK : {
const id = Number ( thread . petersonId );
const entered = ctx . station . lock . lock ( id );
if (! entered ) {
thread . state = "blocked" ;
thread . blockedBy = ctx . station . lock ;
return `🤖 ${ thread . name } espera turno en estacion (turn= ${ ctx . station . lock . turn + 1 } )` ;
}
thread.nextInstruction();
return `🔐 ${ thread . name } entro a estacion compartida` ;
}
Requires thread.petersonId to be set to 0 or 1.
USE_STATION
Uses the shared station (critical section).
{ type : Instructions . USE_STATION }
PETERSON_UNLOCK
Exits critical section using Peterson’s algorithm.
{ type : Instructions . PETERSON_UNLOCK }
Control Flow Instructions
END
Marks thread as finished and wakes any threads waiting for it.
{ type : Instructions . END }
Execution:
case Instructions . END :
thread . state = "finished" ;
if ( ctx . joinManager ) {
const awakened = ctx . joinManager . markFinished ( thread );
awakened . forEach (( waitingThread ) => {
waitingThread . state = "ready" ;
waitingThread . blockedBy = null ;
});
if ( awakened . length > 0 ) {
const names = awakened . map (( t ) => t . name ). join ( ", " );
return `🏁 ${ thread . name } finalizo y desperto a: ${ names } ` ;
}
}
return `🏁 ${ thread . name } finalizo sus tareas` ;
Always end thread instruction sequences with END, or the engine will automatically mark the thread as finished when it runs out of instructions.
Instruction Composition
Instructions are composed into sequences that define thread behavior:
Bank Thread
Printer Thread
House Worker Thread
[
{ type: Instructions . ACQUIRE },
{ type: Instructions . WITHDRAW , amount: 100 },
{ type: Instructions . RELEASE },
{ type: Instructions . END }
]
Next Steps
Scenarios Learn how scenarios compose instructions into complete simulations
Execution Engine Understand how instructions are executed