mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 03:02:54 +00:00
initial commit for process scheduler
This commit is contained in:
83
code/controllers/ProcessScheduler/core/updateQueueWorker.dm
Normal file
83
code/controllers/ProcessScheduler/core/updateQueueWorker.dm
Normal file
@@ -0,0 +1,83 @@
|
||||
datum/updateQueueWorker
|
||||
var/tmp/list/objects
|
||||
var/tmp/killed
|
||||
var/tmp/finished
|
||||
var/tmp/procName
|
||||
var/tmp/list/arguments
|
||||
var/tmp/lastStart
|
||||
var/tmp/cpuThreshold
|
||||
|
||||
datum/updateQueueWorker/New(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90)
|
||||
..()
|
||||
uq_dbg("updateQueueWorker created.")
|
||||
|
||||
init(objects, procName, arguments, cpuThreshold)
|
||||
|
||||
datum/updateQueueWorker/proc/init(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90)
|
||||
src.objects = objects
|
||||
src.procName = procName
|
||||
src.arguments = arguments
|
||||
src.cpuThreshold = cpuThreshold
|
||||
|
||||
killed = 0
|
||||
finished = 0
|
||||
|
||||
datum/updateQueueWorker/proc/doWork()
|
||||
// If there's nothing left to execute or we were killed, mark finished and return.
|
||||
if (!objects || !objects.len) return finished()
|
||||
|
||||
lastStart = world.timeofday // Absolute number of ticks since the world started up
|
||||
|
||||
var/datum/object = objects[objects.len] // Pull out the object
|
||||
objects.len-- // Remove the object from the list
|
||||
|
||||
if (istype(object) && !isturf(object) && !object.disposed && isnull(object.gcDestroyed)) // We only work with real objects
|
||||
call(object, procName)(arglist(arguments))
|
||||
|
||||
// If there's nothing left to execute
|
||||
// or we were killed while running the above code, mark finished and return.
|
||||
if (!objects || !objects.len) return finished()
|
||||
|
||||
if (world.cpu > cpuThreshold)
|
||||
// We don't want to force a tick into overtime!
|
||||
// If the tick is about to go overtime, spawn the next update to go
|
||||
// in the next tick.
|
||||
uq_dbg("tick went into overtime with world.cpu = [world.cpu], deferred next update to next tick [1+(world.time / world.tick_lag)]")
|
||||
|
||||
spawn(1)
|
||||
doWork()
|
||||
else
|
||||
spawn(0) // Execute anonymous function immediately as if we were in a while loop...
|
||||
doWork()
|
||||
|
||||
datum/updateQueueWorker/proc/finished()
|
||||
uq_dbg("updateQueueWorker finished.")
|
||||
/**
|
||||
* If the worker was killed while it was working on something, it
|
||||
* should delete itself when it finally finishes working on it.
|
||||
* Meanwhile, the updateQueue will have proceeded on with the rest of
|
||||
* the queue. This will also terminate the spawned function that was
|
||||
* created in the kill() proc.
|
||||
*/
|
||||
if(killed)
|
||||
del(src)
|
||||
|
||||
finished = 1
|
||||
|
||||
datum/updateQueueWorker/proc/kill()
|
||||
uq_dbg("updateQueueWorker killed.")
|
||||
killed = 1
|
||||
objects = null
|
||||
|
||||
/**
|
||||
* If the worker is not done in 30 seconds after it's killed,
|
||||
* we'll forcibly delete it, causing the anonymous function it was
|
||||
* running to be terminated. Hasta la vista, baby.
|
||||
*/
|
||||
spawn(300)
|
||||
del(src)
|
||||
|
||||
datum/updateQueueWorker/proc/start()
|
||||
uq_dbg("updateQueueWorker started.")
|
||||
spawn(0)
|
||||
doWork()
|
||||
Reference in New Issue
Block a user