processScheduler Update to 510 (#398)

Updates code to be 510 compile compatible.

Also introduces the new updates to the GOON processScheduler, which should make for better gameplay and less lag. Specially on high population.
This commit is contained in:
skull132
2016-06-23 02:47:12 +03:00
committed by GitHub
parent 6dfd6bf3a0
commit 02b42862c1
47 changed files with 725 additions and 1303 deletions
+1
View File
@@ -1,6 +1,7 @@
/datum/controller/process/air/setup()
name = "air"
schedule_interval = 20 // every 2 seconds
start_delay = 4
if(!air_master)
air_master = new
+34 -4
View File
@@ -1,10 +1,40 @@
// We manually initialize the alarm handlers instead of looping over all existing types
// to make it possible to write: camera.triggerAlarm() rather than alarm_manager.managers[datum/alarm_handler/camera].triggerAlarm() or a variant thereof.
/var/global/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
/var/global/datum/alarm_handler/camera/camera_alarm = new()
/var/global/datum/alarm_handler/fire/fire_alarm = new()
/var/global/datum/alarm_handler/motion/motion_alarm = new()
/var/global/datum/alarm_handler/power/power_alarm = new()
// Alarm Manager, the manager for alarms.
var/datum/controller/process/alarm/alarm_manager
/datum/controller/process/alarm
var/list/datum/alarm/all_handlers
/datum/controller/process/alarm/setup()
name = "alarm"
schedule_interval = 20 // every 2 seconds
all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
alarm_manager = src
/datum/controller/process/alarm/doWork()
alarm_manager.fire()
for(var/datum/alarm_handler/AH in all_handlers)
AH.process()
SCHECK
/datum/controller/process/alarm/getStatName()
var/list/alarms = alarm_manager.active_alarms()
return ..()+"([alarms.len])"
/datum/controller/process/alarm/proc/active_alarms()
var/list/all_alarms = new
for(var/datum/alarm_handler/AH in all_handlers)
var/list/alarms = AH.alarms
all_alarms += alarms
return all_alarms
/datum/controller/process/alarm/proc/number_of_active_alarms()
var/list/alarms = active_alarms()
return alarms.len
/datum/controller/process/alarm/statProcess()
..()
stat(null, "[number_of_active_alarms()] alarm\s")
+7 -5
View File
@@ -4,11 +4,13 @@
/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()
for(var/disease in active_diseases)
var/datum/disease/D = disease
D.process()
SCHECK
/datum/controller/process/disease/getStatName()
return ..()+"([active_diseases.len])"
/datum/controller/process/disease/statProcess()
..()
stat(null, "[active_diseases.len] disease\s")
+36 -18
View File
@@ -1,13 +1,18 @@
// The time a datum was destroyed by the GC, or null if it hasn't been
/datum/var/gcDestroyed
#define GC_COLLECTIONS_PER_RUN 150
#define GC_COLLECTION_TIMEOUT (30 SECONDS)
#define GC_FORCE_DEL_PER_RUN 30
var/datum/controller/process/garbage_collector/garbage_collector
var/list/delayed_garbage = list()
/datum/controller/process/garbage_collector
var/garbage_collect = 1 // Whether or not to actually do work
var/collection_timeout = 300 //deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
var/max_checks_multiplier = 5 //multiplier (per-decisecond) for calculating max number of tests per tick. These tests check if our GC'd objects are actually GC'd
var/max_forcedel_multiplier = 1 //multiplier (per-decisecond) for calculating max number of force del() calls per tick.
var/dels = 0 // number of del()'s we've done this tick
var/total_dels = 0 // number of total del()'s
var/tick_dels = 0 // number of del()'s we've done this tick
var/soft_dels = 0
var/hard_dels = 0 // number of hard dels in total
var/list/destroyed = list() // list of refID's of things that should be garbage collected
// refID's are associated with the time at which they time out and need to be manually del()
@@ -18,7 +23,8 @@ var/list/delayed_garbage = list()
/datum/controller/process/garbage_collector/setup()
name = "garbage"
schedule_interval = 2 SECONDS
schedule_interval = 10 SECONDS
start_delay = 3
if(!garbage_collector)
garbage_collector = src
@@ -32,13 +38,13 @@ var/list/delayed_garbage = list()
if(!garbage_collect)
return
dels = 0
var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del()
var/checkRemain = max_checks_multiplier * schedule_interval
var/maxDels = max_forcedel_multiplier * schedule_interval
tick_dels = 0
var/time_to_kill = world.time - GC_COLLECTION_TIMEOUT
var/checkRemain = GC_COLLECTIONS_PER_RUN
var/remaining_force_dels = GC_FORCE_DEL_PER_RUN
while(destroyed.len && --checkRemain >= 0)
if(dels >= maxDels)
if(remaining_force_dels <= 0)
#ifdef GC_DEBUG
testing("GC: Reached max force dels per tick [dels] vs [maxDels]")
#endif
@@ -59,13 +65,22 @@ var/list/delayed_garbage = list()
testing("GC: -- \ref[A] | [A.type] was unable to be GC'd and was deleted --")
logging["[A.type]"]++
del(A)
++dels
++hard_dels
#ifdef GC_DEBUG
hard_dels++
remaining_force_dels--
else
#ifdef GC_DEBUG
testing("GC: [refID] properly GC'd at [world.time] with timeout [GCd_at_time]")
#endif
#endif
soft_dels++
tick_dels++
total_dels++
destroyed.Cut(1, 2)
SCHECK
#undef GC_FORCE_DEL_PER_TICK
#undef GC_COLLECTION_TIMEOUT
#undef GC_COLLECTIONS_PER_TICK
/datum/controller/process/garbage_collector/proc/AddTrash(datum/A)
if(!istype(A) || !isnull(A.gcDestroyed))
@@ -77,8 +92,11 @@ var/list/delayed_garbage = list()
destroyed -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list.
destroyed["\ref[A]"] = world.time
/datum/controller/process/garbage_collector/getStatName()
return ..()+"([garbage_collector.destroyed.len]/[garbage_collector.dels]/[garbage_collector.hard_dels])"
/datum/controller/process/garbage_collector/statProcess()
..()
stat(null, "[garbage_collect ? "On" : "Off"], [destroyed.len] queued")
stat(null, "Dels: [total_dels], [soft_dels] soft, [hard_dels] hard, [tick_dels] last run")
// Tests if an atom has been deleted.
/proc/deleted(atom/A)
@@ -94,7 +112,7 @@ var/list/delayed_garbage = list()
crash_with("qdel() passed object of type [A.type]. qdel() can only handle /datum types.")
del(A)
if(garbage_collector)
garbage_collector.dels++
garbage_collector.total_dels++
garbage_collector.hard_dels++
else if(isnull(A.gcDestroyed))
// Let our friend know they're about to get collected
+1 -1
View File
@@ -10,4 +10,4 @@
log_access("AFK: [key_name(C)]")
C << "<SPAN CLASS='warning'>You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.</SPAN>"
del(C) // Don't qdel, cannot override finalize_qdel behaviour for clients.
scheck()
SCHECK
+1
View File
@@ -1,5 +1,6 @@
/datum/controller/process/lighting/setup()
name = "lighting"
start_delay = 1
schedule_interval = 5 // every .5 second
lighting_controller.initializeLighting()
+13 -21
View File
@@ -3,6 +3,7 @@
/datum/controller/process/machinery/setup()
name = "machinery"
schedule_interval = 20 // every 2 seconds
start_delay = 12
/datum/controller/process/machinery/doWork()
internal_sort()
@@ -19,10 +20,6 @@
/datum/controller/process/machinery/proc/internal_process_machinery()
for(var/obj/machinery/M in machines)
if(M && !M.gcDestroyed)
#ifdef PROFILE_MACHINES
var/time_start = world.timeofday
#endif
if(M.process() == PROCESS_KILL)
//M.inMachineList = 0 We don't use this debugging function
machines.Remove(M)
@@ -31,22 +28,13 @@
if(M && M.use_power)
M.auto_use_power()
#ifdef PROFILE_MACHINES
var/time_end = world.timeofday
if(!(M.type in machine_profiling))
machine_profiling[M.type] = 0
machine_profiling[M.type] += (time_end - time_start)
#endif
scheck()
SCHECK
/datum/controller/process/machinery/proc/internal_process_power()
for(var/datum/powernet/powerNetwork in powernets)
if(istype(powerNetwork) && !powerNetwork.disposed)
if(istype(powerNetwork) && isnull(powerNetwork.gcDestroyed))
powerNetwork.reset()
scheck()
SCHECK
continue
powernets.Remove(powerNetwork)
@@ -56,16 +44,20 @@
for(var/obj/item/I in processing_power_items)
if(!I.pwr_drain()) // 0 = Process Kill, remove from processing list.
processing_power_items.Remove(I)
scheck()
SCHECK
/datum/controller/process/machinery/proc/internal_process_pipenets()
for(var/datum/pipe_network/pipeNetwork in pipe_networks)
if(istype(pipeNetwork) && !pipeNetwork.disposed)
if(istype(pipeNetwork) && isnull(pipeNetwork.gcDestroyed))
pipeNetwork.process()
scheck()
SCHECK
continue
pipe_networks.Remove(pipeNetwork)
/datum/controller/process/machinery/getStatName()
return ..()+"(MCH:[machines.len] PWR:[powernets.len] PIP:[pipe_networks.len])"
/datum/controller/process/machinery/statProcess()
..()
stat(null, "[machines.len] machines")
stat(null, "[powernets.len] powernets")
stat(null, "[pipe_networks.len] pipenets")
stat(null, "[processing_power_items.len] power item\s")
+17 -11
View File
@@ -4,20 +4,26 @@
/datum/controller/process/mob/setup()
name = "mob"
schedule_interval = 20 // every 2 seconds
updateQueueInstance = new
start_delay = 16
/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/doWork()
if(updateQueueInstance)
updateQueueInstance.init(mob_list, "Life")
updateQueueInstance.Run()
for(last_object in mob_list)
var/mob/M = last_object
if(isnull(M.gcDestroyed))
try
M.Life()
catch(var/exception/e)
catchException(e, M)
SCHECK
else
catchBadType(M)
mob_list -= M
/datum/controller/process/mob/getStatName()
return ..()+"([mob_list.len])"
/datum/controller/process/mob/statProcess()
..()
stat(null, "[mob_list.len] mobs")
+15 -10
View File
@@ -1,14 +1,19 @@
/datum/controller/process/nanoui
var/tmp/datum/updateQueue/updateQueueInstance
/datum/controller/process/nanoui/setup()
name = "nanoui"
schedule_interval = 10 // every 1 second
updateQueueInstance = new
schedule_interval = 20 // every 2 seconds
/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()
/datum/controller/process/nanoui/getStatName()
return ..()+"([nanomanager.processing_uis.len])"
for(last_object in nanomanager.processing_uis)
var/datum/nanoui/NUI = last_object
if(istype(NUI) && isnull(NUI.gcDestroyed))
try
NUI.process()
catch(var/exception/e)
catchException(e, NUI)
else
catchBadType(NUI)
nanomanager.processing_uis -= NUI
+17 -15
View File
@@ -1,24 +1,26 @@
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/doWork()
if(updateQueueInstance)
updateQueueInstance.init(processing_objects, "process")
updateQueueInstance.Run()
for(last_object in processing_objects)
var/datum/O = last_object
if(isnull(O.gcDestroyed))
try
O:process()
catch(var/exception/e)
catchException(e, O)
SCHECK
else
catchBadType(O)
processing_objects -= O
/datum/controller/process/obj/getStatName()
return ..()+"([processing_objects.len])"
/datum/controller/process/obj/statProcess()
..()
stat(null, "[processing_objects.len] objects")
+4 -3
View File
@@ -8,7 +8,8 @@ var/global/list/turf/processing_turfs = list()
for(var/turf/T in processing_turfs)
if(T.process() == PROCESS_KILL)
processing_turfs.Remove(T)
scheck()
SCHECK
/datum/controller/process/turf/getStatName()
return ..()+"([processing_turfs.len])"
/datum/controller/process/turf/statProcess()
..()
stat(null, "[processing_turfs.len] turf\s")