Jump to content

Does llSleep use a state machine or thread block?


Extrude Ragu
 Share

You are about to reply to a thread that has been inactive for 1683 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I am curious about the internal nature of how llSleep is handled on LL Servers.

Coming from a background in software engineering, usually to 'Sleep' in programming implies blocking the thread, something that is quite undesirable because it causes the system to no longer be able to use that thread to perform other tasks, which is why we usually prefer to turn to a more asynchronous model of programming, preferring events (eg, timers)  so as to keep the thread open for other tasks to use.

So that got me wondering, is llSleep actually blocking a thread in the server side code whenever it is being called? It would seem that, if this were true, it would make servers vulnerable to being completely thread-blocked. It seems unlikely to me that LL would want people to actually be able to sleep in threads. So I wonder perhaps does llSleep when compiled, actually generate a state machine similar to async/await model in C#?

 

Link to comment
Share on other sites

Perhaps someone with a background in Mono could hazard a more educated guess, but whether scripts are handled as proper threads or a different abstraction, they do individually block upon llSleep(). Indeed llSleep(0.0) is sometimes used to let other scripts have the processor for the rest of the simulation frame.

It's kind of important that an individual script will never handle different events asynchronously: if a handler starts running it will run to completion before any other events are processed by other handlers in that script (while of course other scripts can continue asynchronously). So in that sense, an individual script behaves like a single thread. But there's a bunch of custom programming that schedules SL simulation tasks (including but not limited to scripts), so I'm hesitant to conclude that scripts run as genuine POSIX threads.

Link to comment
Share on other sites

because we don't have access to the Mono server code, only a Linden could definitively answer this question. While there is some explanation that can be gained from Mono-Out-The-Box, Linden have done some code customisations to retrofit the old LSL model onto Mono and what those customisations are exactly I dunno

this said, it shouldn't make a lot of difference to server load as typically a LSL Mono script runs as a singular process (in LSL we can't create our own threads as we can in other languages). Script events are queued by type to that process

the queue size for each type is typically dynamically allocated from the total server queue pool size available at any given moment

when the script event queue for the type is full then no other events of that type for the script are queued

as part of dynamic allocation, what the size of a queue can be is circumstantially variable

a couple of example scripts that can help to give some idea of what is happening. Example queued listen sender and receiver:

// sender
// stick this in a prim named "sender" and reset it after
// starting the receiver

default
{
    state_entry()
    {
        llWhisper(0, "SENDER BEGIN");
        
        integer i;
        for (i; i < 800; i++)
           llSay(-7123, (string)i + " : " + (string)llFrand(20000.0));
        
        llWhisper(0, "SENDER END");
    }
}
// receiver
// stick this in a prim and reset it before starting the sender

integer buffer;

default
{
    state_entry()
    {
        llWhisper(0, "RECEIVER WAITING");
        llListen(-7123, "sender", NULL_KEY, "");
             
        // set sleep time so that sender ends before
        // receiver begins     
        llSleep(30.0); 
                      
        llWhisper(0, "RECEIVER BEGIN");        
    }

    listen(integer channel, string name, key id, string text)
    {
        if (++buffer == 700)
        {
            // depending on what else is happening on the server
            // then at times, buffer will never be 700
            llWhisper(0, "RECEIVER END " + (string)(buffer));
            buffer = 0; 
        }   
    }
    
    touch_start(integer n)
    {
        // touch to see the current event buffer count
        llWhisper(0, "BUFFER: " + (string)buffer);
    }
}

on my old mainland region the number of queued listens is 600 at time of testing. On my old Linden Homes region the number of queued listens is 700

the OP question is: What happens to a script queue when a script sleeps for some really long time?

again I dunno exactly how Linden manage this but I would think that when no further server queue pool memory is available then all current queues are shorten by some factor. In the case of the listen queue then it appears the factor is some multiple of 100

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1683 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...