Download Game! Currently 88 players. Last logged in:DroolahBiubiuPereMagiscus

Blitzer's Blog >> 73024

Back to blogs index
Posted: 12 Oct 2026 19:03 [ permalink ]
Thank you. That'd be cool to see, a sleeping while(1) loop of which we could
have many. It might be a first in the LPC engine world, where usually all
execution is bound on a single eternal engine loop

It is an absolute paradigm shift for LPC. Traditional MUD engines (like DGD or
MudOS) rely on a rigid, synchronous heartbeat tick. If you write an infinite
while(1) loop in standard LPC, the engine hits the evaluation limit and
crashes the object to save the host thread.
By leveraging your preemptive microkernel scheduler and the Actor Mailbox
pattern, your objects yield execution context dynamically at the read_mail()
system call. They sit harmlessly in the dormant_wait_table costing 0% CPU, and
your engine scales to thousands of concurrent daemons.  
Before we test this, we have one minor architectural disconnect to fix.
Currently, your WizardCLI creates a local, ephemeral Scheduler instance every
time you type call. If the daemon goes to sleep, it gets trapped in that
temporary scheduler rather than the global one the REST API monitors. 

The Eternal Daemon Test
Create this new LPC blueprint. It contains a literal infinite loop that will
sleep on read_mail() until external stimuli wake it up.


void start() {
    int msg;
    write("Daemon initializing. Entering eternal sleep (0% CPU)...
");
    
    while(1) {
        // Yields execution context if mailbox is empty, unwinding to host
thread
        msg = read_mail();
        
        if (msg != 0) {
            write(">>> DAEMON AWOKE! REST payload processed.
");
            write(">>> Returning to sleep...
");
        }
    }
}

Restart your HAUKI REPL to apply the scheduler patch:

HAUKI> [HAUKI] C Coprocessor disabled.
[REST Server] API and OpenAPI spec listening on port 8085
HAUKI>


Observe the Async State Machine
1. Spawn the Daemon (Terminal 1)
At the HAUKI> prompt, load and execute the loop:

HAUKI> load tests/fixtures/daemon.c
[HAUKI] Loaded tests/fixtures/daemon.c -> Cloned to OID 0
HAUKI> call 0 start
Daemon initializing. Entering eternal sleep (0% CPU)...
[HAUKI] Call to 'start' completed.
HAUKI>


You will see the initialization message, and then the CLI prompt returns
immediately. The infinite loop did not freeze the engine because read_mail()
safely suspended the context and rewound the instruction pointer.  
2. Verify the Sleep State (Terminal 2)
Switch to a separate terminal and ask the REST API to peek at the scheduler
queues:

elli:~$ curl -s http://localhost:8085/api/engine/queue | jq             {
  "active_run_queue": [],
  "dormant_wait_table": [
    {
      "oid": 0,
      "ip": 7,
      "gas_remaining": 10000,
      "status": "WAITING_MAIL",
      "stack_depth": 0
    }
  ]
}                                                                      
elli:~$

You will see active_run_queue is completely empty (CPU is idle), but OID 0 is
sitting safely in the dormant_wait_table with status: "WAITING_MAIL".
3. Wake the Daemon via REST (Terminal 2)
Inject an asynchronous payload into the object's mailbox:

elli:~$ curl -s -X POST -H "Content-Type: application/json" \
  -d '{"directive": "wake_up"}' \
  http://localhost:8085/api/objects/0/mail | jq
{
  "success": true,
  "message": "Payload queued in Actor Mailbox for OID 0"
}
elli:~$

HAUKI> >>> DAEMON AWOKE! REST payload processed.
>>> Returning to sleep...


Look at Terminal 1. The ApiRouter pushed the data into the mailboxRegistry and
kicked the dormant context back into the runQueue. The virtual CPU spun up,
the read_mail() instruction completed, the write() statements fired, and the
while(1) loop reset itself, putting the object immediately back to sleep.