Process and Process Scheduler Tweaks

This commit is contained in:
Krausus
2015-07-18 13:14:32 -04:00
parent fd87909ff5
commit c520ebd8a5
22 changed files with 257 additions and 204 deletions
@@ -85,7 +85,13 @@
var/tmp/last_object
datum/controller/process/New(var/datum/controller/processScheduler/scheduler)
// Counts the number of times an exception has occurred; gets reset after 10
var/tmp/list/exceptions = list()
// Number of deciseconds to delay before starting the process
var/start_delay = 0
/datum/controller/process/New(var/datum/controller/processScheduler/scheduler)
..()
main = scheduler
previousStatus = "idle"
@@ -99,7 +105,7 @@ datum/controller/process/New(var/datum/controller/processScheduler/scheduler)
last_task = 0
last_object = null
datum/controller/process/proc/started()
/datum/controller/process/proc/started()
// Initialize last_slept so we can know when to sleep
last_slept = world.timeofday
@@ -114,48 +120,48 @@ datum/controller/process/proc/started()
onStart()
datum/controller/process/proc/finished()
/datum/controller/process/proc/finished()
ticks++
idle()
main.processFinished(src)
onFinish()
datum/controller/process/proc/doWork()
/datum/controller/process/proc/doWork()
datum/controller/process/proc/setup()
/datum/controller/process/proc/setup()
datum/controller/process/proc/process()
/datum/controller/process/proc/process()
started()
doWork()
finished()
datum/controller/process/proc/running()
/datum/controller/process/proc/running()
idle = 0
queued = 0
running = 1
hung = 0
setStatus(PROCESS_STATUS_RUNNING)
datum/controller/process/proc/idle()
/datum/controller/process/proc/idle()
queued = 0
running = 0
idle = 1
hung = 0
setStatus(PROCESS_STATUS_IDLE)
datum/controller/process/proc/queued()
/datum/controller/process/proc/queued()
idle = 0
running = 0
queued = 1
hung = 0
setStatus(PROCESS_STATUS_QUEUED)
datum/controller/process/proc/hung()
/datum/controller/process/proc/hung()
hung = 1
setStatus(PROCESS_STATUS_HUNG)
datum/controller/process/proc/handleHung()
/datum/controller/process/proc/handleHung()
var/datum/lastObj = last_object
var/lastObjType = "null"
if(istype(lastObj))
@@ -172,7 +178,7 @@ datum/controller/process/proc/handleHung()
main.restartProcess(src.name)
datum/controller/process/proc/kill()
/datum/controller/process/proc/kill()
if (!killed)
var/msg = "[name] process was killed at tick #[ticks]."
logTheThing("debug", null, null, msg)
@@ -187,7 +193,7 @@ datum/controller/process/proc/kill()
// This should del
del(src)
datum/controller/process/proc/scheck(var/tickId = 0)
/datum/controller/process/proc/scheck(var/tickId = 0)
if (killed)
// The kill proc is the only place where killed is set.
// The kill proc should have deleted this datum, and all sleeping procs that are
@@ -196,8 +202,8 @@ datum/controller/process/proc/scheck(var/tickId = 0)
// For each tick the process defers, it increments the cpu_defer_count so we don't
// defer indefinitely
if (world.cpu >= cpu_threshold + cpu_defer_count * 10)
sleep(1)
if (world.cpu >= (cpu_threshold + cpu_defer_count * world.tick_lag * 10))
sleep(world.tick_lag)
cpu_defer_count++
last_slept = world.timeofday
else
@@ -210,7 +216,7 @@ datum/controller/process/proc/scheck(var/tickId = 0)
sleep(0)
last_slept = world.timeofday
datum/controller/process/proc/update()
/datum/controller/process/proc/update()
// Clear delta
if(previousStatus != status)
setStatus(status)
@@ -224,18 +230,18 @@ datum/controller/process/proc/update()
else if (elapsedTime > hang_warning_time)
setStatus(PROCESS_STATUS_MAYBE_HUNG)
datum/controller/process/proc/getElapsedTime()
/datum/controller/process/proc/getElapsedTime()
if (world.timeofday < run_start)
return world.timeofday - (run_start - 864000)
return world.timeofday - run_start
datum/controller/process/proc/tickDetail()
/datum/controller/process/proc/tickDetail()
return
datum/controller/process/proc/getContext()
/datum/controller/process/proc/getContext()
return "<tr><td>[name]</td><td>[main.averageRunTime(src)]</td><td>[main.last_run_time[src]]</td><td>[main.highest_run_time[src]]</td><td>[ticks]</td></tr>\n"
datum/controller/process/proc/getContextData()
/datum/controller/process/proc/getContextData()
return list(
"name" = name,
"averageRunTime" = main.averageRunTime(src),
@@ -247,10 +253,10 @@ datum/controller/process/proc/getContextData()
"disabled" = disabled
)
datum/controller/process/proc/getStatus()
/datum/controller/process/proc/getStatus()
return status
datum/controller/process/proc/getStatusText(var/s = 0)
/datum/controller/process/proc/getStatusText(var/s = 0)
if(!s)
s = status
switch(s)
@@ -269,21 +275,21 @@ datum/controller/process/proc/getStatusText(var/s = 0)
else
return "UNKNOWN"
datum/controller/process/proc/getPreviousStatus()
/datum/controller/process/proc/getPreviousStatus()
return previousStatus
datum/controller/process/proc/getPreviousStatusText()
/datum/controller/process/proc/getPreviousStatusText()
return getStatusText(previousStatus)
datum/controller/process/proc/setStatus(var/newStatus)
/datum/controller/process/proc/setStatus(var/newStatus)
previousStatus = status
status = newStatus
datum/controller/process/proc/setLastTask(var/task, var/object)
/datum/controller/process/proc/setLastTask(var/task, var/object)
last_task = task
last_object = object
datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target)
/datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target)
main = target.main
name = target.name
schedule_interval = target.schedule_interval
@@ -296,22 +302,52 @@ datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target
last_object = target.last_object
copyStateFrom(target)
datum/controller/process/proc/copyStateFrom(var/datum/controller/process/target)
/datum/controller/process/proc/copyStateFrom(var/datum/controller/process/target)
datum/controller/process/proc/onKill()
/datum/controller/process/proc/onKill()
datum/controller/process/proc/onStart()
/datum/controller/process/proc/onStart()
datum/controller/process/proc/onFinish()
/datum/controller/process/proc/onFinish()
datum/controller/process/proc/disable()
/datum/controller/process/proc/disable()
disabled = 1
datum/controller/process/proc/enable()
/datum/controller/process/proc/enable()
disabled = 0
/datum/controller/process/proc/getLastRunTime()
return main.getProcessLastRunTime(src)
/datum/controller/process/proc/getHighestRunTime()
return main.getProcessHighestRunTime(src)
/datum/controller/process/proc/getTicks()
return ticks
/datum/controller/process/proc/statProcess()
stat("[name]", "T#[getTicks()]|LR [getLastRunTime()]|HR [getHighestRunTime()]|D [cpu_defer_count]")
/datum/controller/process/proc/catchException(var/exception/e, var/thrower)
var/etext = "[e]"
var/eid = "[e]" // Exception ID, for tracking repeated exceptions
var/ptext = "" // "processing..." text, for what was being processed (if known)
if(istype(e))
etext += " in [e.file], line [e.line]"
eid = "[e.file]:[e.line]"
if(eid in exceptions)
if(exceptions[eid]++ >= 10)
return
else
exceptions[eid] = 1
if(istype(thrower, /datum))
var/datum/D = thrower
ptext = " processing [D.type]"
if(istype(thrower, /atom))
var/atom/A = thrower
ptext += " ([A]) ([A.x],[A.y],[A.z])"
world.log << "\[[time_stamp()]\] Process [name] caught exception[ptext]: [etext]"
if(exceptions[eid] >= 10)
world.log << "This exception will now be ignored for ten minutes."
spawn(6000)
exceptions[eid] = 0
@@ -66,6 +66,7 @@ var/global/datum/controller/processScheduler/processScheduler
/datum/controller/processScheduler/proc/start()
isRunning = 1
updateStartDelays()
spawn(0)
process()
@@ -108,12 +109,8 @@ var/global/datum/controller/processScheduler/processScheduler
if (p.disabled || p.running || p.queued || !p.idle)
continue
// If world.timeofday has rolled over, then we need to adjust.
if (world.timeofday < last_start[p])
last_start[p] -= 864000
// If the process should be running by now, go ahead and queue it
if (world.timeofday > last_start[p] + p.schedule_interval)
if (world.time >= last_start[p] + p.schedule_interval)
setQueuedProcessState(p)
/datum/controller/processScheduler/proc/runQueuedProcesses()
@@ -176,6 +173,10 @@ var/global/datum/controller/processScheduler/processScheduler
nameToProcessMap[newProcess.name] = newProcess
/datum/controller/processScheduler/proc/updateStartDelays()
for(var/datum/controller/process/p in processes)
if(p.start_delay)
last_start[p] = world.time - p.start_delay
/datum/controller/processScheduler/proc/runProcess(var/datum/controller/process/process)
spawn(0)
@@ -222,17 +223,13 @@ var/global/datum/controller/processScheduler/processScheduler
/datum/controller/processScheduler/proc/recordStart(var/datum/controller/process/process, var/time = null)
if (isnull(time))
time = world.timeofday
time = world.time
last_start[process] = time
/datum/controller/processScheduler/proc/recordEnd(var/datum/controller/process/process, var/time = null)
if (isnull(time))
time = world.timeofday
// If world.timeofday has rolled over, then we need to adjust.
if (time < last_start[process])
last_start[process] -= 864000
time = world.time
var/lastRunTime = time - last_start[process]
@@ -316,5 +313,16 @@ var/global/datum/controller/processScheduler/processScheduler
/datum/controller/processScheduler/proc/getProcessLastRunTime(var/datum/controller/process/process)
return last_run_time[process]
/datum/controller/processScheduler/proc/getProcessHighestRunTime(var/datum/controller/process/process)
return highest_run_time[process]
/datum/controller/processScheduler/proc/getIsRunning()
return isRunning
/datum/controller/processScheduler/proc/statProcesses()
if(!isRunning)
stat("Processes", "Scheduler not running")
return
stat("Processes", "[processes.len] (R[running.len]/Q[queued.len]/I[idle.len])")
for(var/datum/controller/process/p in processes)
p.statProcess()
+24 -3
View File
@@ -15,9 +15,17 @@ var/global/datum/controller/process/air_system/air_master
var/failed_ticks = 0
var/tick_progress = 0
// Stats
var/last_active = 0
var/last_excited = 0
var/last_hpd = 0
var/last_hotspots = 0
var/last_asc = 0
/datum/controller/process/air_system/setup()
name = "air"
schedule_interval = 20 // every 2 seconds
start_delay = 4
air_master = src
world << "<span class='danger'>Processing Geometry...</span>"
@@ -32,30 +40,41 @@ var/global/datum/controller/process/air_system/air_master
current_cycle++
process_active_turfs()
process_excited_groups()
scheck()
process_high_pressure_delta()
process_hotspots()
process_super_conductivity()
scheck()
return 1
/datum/controller/process/air_system/statProcess()
..()
stat(null, "[last_active] active")
stat(null, "[last_excited] EG|[last_hpd] HPD|[last_asc] ASC|[last_hotspots] Hot")
/datum/controller/process/air_system/proc/process_hotspots()
last_hotspots = hotspots.len
for(var/obj/effect/hotspot/H in hotspots)
H.process()
scheck()
/datum/controller/process/air_system/proc/process_super_conductivity()
last_asc = active_super_conductivity.len
for(var/turf/simulated/T in active_super_conductivity)
T.super_conduct()
scheck()
/datum/controller/process/air_system/proc/process_high_pressure_delta()
last_hpd = high_pressure_delta.len
for(var/turf/T in high_pressure_delta)
T.high_pressure_movements()
T.pressure_difference = 0
high_pressure_delta.len = 0
scheck()
high_pressure_delta.Cut()
/datum/controller/process/air_system/proc/process_active_turfs()
last_active = active_turfs.len
for(var/turf/simulated/T in active_turfs)
T.process_cell()
scheck()
/datum/controller/process/air_system/proc/remove_from_active(var/turf/simulated/T)
if(istype(T))
@@ -100,6 +119,7 @@ var/global/datum/controller/process/air_system/air_master
active_turfs |= T
/datum/controller/process/air_system/proc/process_excited_groups()
last_excited = excited_groups.len
for(var/datum/excited_group/EG in excited_groups)
EG.breakdown_cooldown ++
if(EG.breakdown_cooldown == 10)
@@ -107,6 +127,7 @@ var/global/datum/controller/process/air_system/air_master
return
if(EG.breakdown_cooldown > 20)
EG.dismantle()
scheck()
/datum/controller/process/air_system/proc/setup_overlays()
plmaster = new /obj/effect/overlay()
+18 -10
View File
@@ -1,20 +1,28 @@
/datum/controller/process/bot
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/bot/setup()
name = "bot"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
/datum/controller/process/bot/started()
..()
if(!updateQueueInstance)
if(!aibots)
aibots = list()
else if(aibots.len)
updateQueueInstance = new
if(!aibots)
aibots = list()
/datum/controller/process/bot/statProcess()
..()
stat(null, "[aibots && aibots.len] bots")
/datum/controller/process/bot/doWork()
if(updateQueueInstance)
updateQueueInstance.init(aibots, "bot_process")
updateQueueInstance.Run()
for(var/obj/machinery/bot/B in aibots)
if(istype(B) && isnull(B.gcDestroyed))
// Some bots sleep when they process, but there's not many bots, so just spawn them off
spawn(-1)
try
B.bot_process()
catch(var/exception/e)
catchException(e, B)
// Use src explicitly after a try/catch, or BYOND messes src up. I have no idea why.
src.scheck()
else
aibots -= B
-11
View File
@@ -1,11 +0,0 @@
/datum/controller/process/disease
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/disease/setup()
name = "disease"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
/datum/controller/process/disease/doWork()
updateQueueInstance.init(active_diseases, "process")
updateQueueInstance.Run()
@@ -1,5 +1,5 @@
/datum/controller/process/emergencyShuttle/setup()
name = "emergency shuttle"
name = "e-shuttle"
schedule_interval = 20 // every 2 seconds
if(!emergency_shuttle)
+10 -6
View File
@@ -1,10 +1,14 @@
/datum/controller/process/garbage/setup()
/datum/controller/process/garbage_collector/setup()
name = "garbage"
schedule_interval = 20 // every 2 seconds
if(!garbageCollector)
garbageCollector = new
garbageCollector = src
/datum/controller/process/garbage/doWork()
garbageCollector.process()
scheck()
/datum/controller/process/garbage_collector/doWork()
// Garbage collection code can be found in code\modules\garbage collection\garbage_collector.dm
processGarbage()
/datum/controller/process/garbage_collector/statProcess()
..()
stat(null, "[del_everything ? "Off" : "On"], [queue.len] queued")
stat(null, "Dels: [dels_count], [soft_dels] soft, [hard_dels] hard")
+15
View File
@@ -0,0 +1,15 @@
var/global/datum/controller/process/lighting/lighting_controller
/datum/controller/process/lighting/setup()
name = "lighting"
schedule_interval = LIGHTING_INTERVAL
start_delay = 1
lighting_controller = src
create_lighting_overlays()
/datum/controller/process/lighting/statProcess()
..()
stat(null, "[last_light_count] lights, [last_overlay_count] overlays")
// Lighting process code located in modules\lighting\lighting_process.dm
+21 -8
View File
@@ -1,6 +1,12 @@
/datum/controller/process/machinery/setup()
name = "machinery"
schedule_interval = 20 // every 2 seconds
start_delay = 12
/datum/controller/process/machinery/statProcess()
..()
stat(null, "[machines.len] machines")
stat(null, "[powernets.len] powernets")
/datum/controller/process/machinery/doWork()
process_power()
@@ -13,13 +19,16 @@
var/time_start = world.timeofday
#endif
if(M.process() == PROCESS_KILL)
//M.inMachineList = 0 We don't use this debugging function
machines.Remove(M)
continue
try
if(M.process() == PROCESS_KILL)
//M.inMachineList = 0 We don't use this debugging function
machines.Remove(M)
continue
if(M && M.use_power)
M.auto_use_power()
if(M && M.use_power)
M.auto_use_power()
catch(var/exception/e)
catchException(e, M)
#ifdef PROFILE_MACHINES
var/time_end = world.timeofday
@@ -37,8 +46,12 @@
/datum/controller/process/machinery/proc/process_power()
for(var/datum/powernet/powerNetwork in powernets)
if(istype(powerNetwork) && isnull(powerNetwork.gcDestroyed))
powerNetwork.reset()
scheck()
try
powerNetwork.reset()
catch(var/exception/e)
catchException(e, powerNetwork)
// Use src explicitly after a try/catch, or BYOND messes src up. I have no idea why.
src.scheck()
continue
else
powernets -= powerNetwork
+18 -11
View File
@@ -1,27 +1,34 @@
/datum/controller/process/mob
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/mob/setup()
name = "mob"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
start_delay = 16
if(!mob_master)
mob_master = new
mob_master.Setup()
/datum/controller/process/mob/started()
..()
if(!updateQueueInstance)
if(!mob_list)
mob_list = list()
else if(mob_list.len)
updateQueueInstance = new
if(!mob_list)
mob_list = list()
/datum/controller/process/mob/statProcess()
..()
stat(null, "[mob_list.len] mobs")
/datum/controller/process/mob/doWork()
if(updateQueueInstance)
updateQueueInstance.init(mob_list, "Life")
updateQueueInstance.Run()
mob_master.process()
for(var/mob/M in mob_list)
if(istype(M) && isnull(M.gcDestroyed))
try
M.Life()
catch(var/exception/e)
catchException(e, M)
// Use src explicitly after a try/catch, or BYOND messes src up. I have no idea why.
src.scheck()
else
mob_list -= M
mob_master.process()
var/global/datum/controller/mob_system/mob_master
+12 -4
View File
@@ -1,11 +1,19 @@
/datum/controller/process/nanoui
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/nanoui/setup()
name = "nanoui"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
/datum/controller/process/nanoui/statProcess()
..()
stat(null, "[nanomanager.processing_uis.len] UIs")
/datum/controller/process/nanoui/doWork()
updateQueueInstance.init(nanomanager.processing_uis, "process")
updateQueueInstance.Run()
for(var/datum/nanoui/NUI in nanomanager.processing_uis)
if(istype(NUI) && isnull(NUI.gcDestroyed))
try
NUI.process()
catch(var/exception/e)
catchException(e, NUI)
else
nanomanager.processing_uis -= NUI
+17 -10
View File
@@ -1,21 +1,28 @@
var/global/list/object_profiling = list()
/datum/controller/process/obj
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/obj/setup()
name = "obj"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
start_delay = 8
/datum/controller/process/obj/started()
..()
if(!updateQueueInstance)
if(!processing_objects)
processing_objects = list()
else if(processing_objects.len)
updateQueueInstance = new
if(!processing_objects)
processing_objects = list()
/datum/controller/process/obj/statProcess()
..()
stat(null, "[processing_objects.len] objects")
/datum/controller/process/obj/doWork()
if(updateQueueInstance)
updateQueueInstance.init(processing_objects, "process")
updateQueueInstance.Run()
for(var/obj/O in processing_objects)
if(istype(O) && isnull(O.gcDestroyed))
try
O.process()
catch(var/exception/e)
catchException(e, O)
// Use src explicitly after a try/catch, or BYOND messes src up. I have no idea why.
src.scheck()
else
processing_objects -= O
+11 -2
View File
@@ -1,12 +1,21 @@
/datum/controller/process/pipenet/setup()
name = "pipenet"
schedule_interval = 20 // every 2 seconds
start_delay = 18
/datum/controller/process/pipenet/statProcess()
..()
stat(null, "[pipe_networks.len] pipe nets")
/datum/controller/process/pipenet/doWork()
for(var/datum/pipe_network/pipeNetwork in pipe_networks)
if(istype(pipeNetwork) && isnull(pipeNetwork.gcDestroyed))
pipeNetwork.process()
scheck()
try
pipeNetwork.process()
catch(var/exception/e)
catchException(e, pipeNetwork)
// Use src explicitly after a try/catch, or BYOND messes src up. I have no idea why.
src.scheck()
continue
else
pipe_networks -= pipeNetwork
+1 -1
View File
@@ -1,5 +1,5 @@
/datum/controller/process/Shuttle/setup()
name = "shuttle controller"
name = "shuttle"
schedule_interval = 20 // every 2 seconds
if(!shuttle_controller)
+1 -1
View File
@@ -1,5 +1,5 @@
/datum/controller/process/supply/setup()
name = "supply controller"
name = "supply"
schedule_interval = 300 // every 30 seconds
/datum/controller/process/supply/doWork()
+1 -3
View File
@@ -42,8 +42,6 @@ datum/controller/game_controller
var/list/shuttle_list // For debugging and VV
var/datum/ore_distribution/asteroid_ore_map // For debugging and VV.
var/global/datum/garbage_collector/garbageCollector
datum/controller/game_controller/New()
//There can be only one master_controller. Out with the old and in with the new.
if(master_controller != src)
@@ -255,7 +253,7 @@ datum/controller/game_controller/proc/process()
// GC
timer = world.timeofday
last_thing_processed = garbageCollector.type
garbageCollector.process()
garbageCollector.processGarbage()
garbageCollectorCost = (world.timeofday - timer) / 10
//TIMING