Scheduler

From Bohemia Interactive Community
Revision as of 10:38, 12 July 2017 by Larrow (talk | contribs) (clear up confusion about call and its scheduling, provided some info about script handles and commands.)
Jump to navigation Jump to search

The scheduler is the part of the game engine that decides which thread runs at a certain point in time. It has the ability to pause a running thread, move it to the back of the running queue and start a new thread.

Threads

A new thread can be started in a script by using spawn, execVM and exec commands. A script or function started this way will run in a scheduled environment, where as a function which is started via call will retain the scheduling from the environment it was called from e.g a call from scheduled code will remain scheduled, a call from unscheduled code will remain unscheduled.

Scheduled Environment

Running code in a scheduled environment starts a new thread. The executing instance will not wait for the result of scheduled code and will continue on with its execution, so it is not possible to return any values from code executed in this manner although a Script handle for started thread is provided.

As described below there is no way to predict when scheduled code will have finished, although you can use the command scriptDone with the provided Script handle to query if the thread execution has finished and there is also the command terminate to abort the thread.

The advantage of scheduled code is that it runs parallel (fire and forget) and that you are able to run code with a huge performance impact (nearly) without slowing down the game.

A scheduled script runs for exactly 3ms before it is put in suspension to be resumed on the next frame, again for another 3ms and so on until the script is finished. The amount of suspension depends on FPS. At 20 FPS the duration of suspension for example is 50ms. This means that if a scheduled script cannot be completed under 3ms, the execution can stretch for undefined amount of time, subject to engine load, FPS and other non scheduled scripts running at the same time. A while true loop with sleep started in scheduled environment therefore has little chance to follow with exact interval.

Scheduled scripts always start with slight delay, subject to engine load.

Where code starts scheduled

  • init.sqf
  • initServer.sqf
  • initPlayerLocal.sqf
  • initPlayerServer.sqf
  • functions with postInit attribute
  • code execution with spawn
  • code execution with execVM
  • code execution with exec
  • code execution with call from a scheduled environment

Unscheduled Environment

Often also called non-scheduled environment but means the same and you will find both terms used in this wiki. The unscheduled environment runs (as described above) in the executing instance. The executing instance waits until the called function is finished. This ensures the execution order and is the fastest way for scripters to execute their code. The disadvantage is that a called function can halt or slow down the game if the function has a high performance consumption. Therefore those functions should be spawned and thereby run in a scheduled environment.

Where code starts unscheduled

  • triggers
  • functions with preInit attribute
  • FSM-conditions
  • Event handlers (on units and in GUI)
  • object Init Event Handlers
  • object initialization fields
  • all pre-init code executions
  • sqf code which is called from sqs-code
  • expressions of Eden Editor entity attributes
  • code execution with call from a unscheduled environment

Loops

A while do loop will be limited to 10,000 iteration in non-scheduled environment. In scheduled environment such limit does not apply.

Suspension

Suspension is the process to wait a period of time or to wait for something to happen. Methods for suspension are sleep, uiSleep, waitUntil and all other kind of loops. Suspension with sleep and uiSleep is generally forbidden in an unscheduled environment. Loops will run for 10,000 iterations before breaking the loop and continuing with the following code. If you want to use suspension in your script then ensure that you are running your code in scheduled environment. You can test your current environment for the ability of suspension with canSuspend.