mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
510 + btime mostly removed + screen overlays overhaul + Paradise sched improvements
This commit is contained in:
@@ -7,12 +7,12 @@
|
||||
#define PROCESS_STATUS_HUNG 6
|
||||
|
||||
// Process time thresholds
|
||||
#define PROCESS_DEFAULT_HANG_WARNING_TIME 300 // 30 seconds
|
||||
#define PROCESS_DEFAULT_HANG_ALERT_TIME 600 // 60 seconds
|
||||
#define PROCESS_DEFAULT_HANG_RESTART_TIME 900 // 90 seconds
|
||||
#define PROCESS_DEFAULT_HANG_WARNING_TIME 900 // 90 seconds
|
||||
#define PROCESS_DEFAULT_HANG_ALERT_TIME 1800 // 180 seconds
|
||||
#define PROCESS_DEFAULT_HANG_RESTART_TIME 2400 // 240 seconds
|
||||
#define PROCESS_DEFAULT_SCHEDULE_INTERVAL 50 // 50 ticks
|
||||
#define PROCESS_DEFAULT_SLEEP_INTERVAL 8 // 2 ticks
|
||||
#define PROCESS_DEFAULT_CPU_THRESHOLD 90 // 90%
|
||||
#define PROCESS_DEFAULT_TICK_ALLOWANCE 25 // 25% of one tick
|
||||
|
||||
|
||||
//#define UPDATE_QUEUE_DEBUG
|
||||
// If btime.dll is available, do this shit
|
||||
@@ -22,9 +22,8 @@
|
||||
var/global/__btime__lastTimeOfHour = 0
|
||||
var/global/__btime__callCount = 0
|
||||
var/global/__btime__lastTick = 0
|
||||
var/global/__btime__dll = "[world.system_type==MS_WINDOWS ? "btime.dll":"./btime.so"]"
|
||||
#define TimeOfHour __btime__timeofhour()
|
||||
#define __extern__timeofhour text2num(call("[__btime__dll]", "gettime")())
|
||||
#define __extern__timeofhour text2num(call("btime.[world.system_type==MS_WINDOWS?"dll":"so"]", "gettime")())
|
||||
proc/__btime__timeofhour()
|
||||
if (!(__btime__callCount++ % 50))
|
||||
if (world.time > __btime__lastTick)
|
||||
@@ -34,4 +33,4 @@ proc/__btime__timeofhour()
|
||||
return global.__btime__lastTimeOfHour
|
||||
#else
|
||||
#define TimeOfHour world.timeofday % 36000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,31 +1,3 @@
|
||||
/**
|
||||
* _stubs.dm
|
||||
*
|
||||
* This file contains constructs that the process scheduler expects to exist
|
||||
* in a standard ss13 fork.
|
||||
*/
|
||||
/*
|
||||
/**
|
||||
* message_admins
|
||||
*
|
||||
* sends a message to admins
|
||||
*/
|
||||
/proc/message_admins(msg)
|
||||
to_chat(world, msg)
|
||||
*/
|
||||
/**
|
||||
* logTheThing
|
||||
*
|
||||
* In goonstation, this proc writes a message to either the world log or diary.
|
||||
*
|
||||
* Blame Keelin.
|
||||
*/
|
||||
/proc/logTheThing(type, source, target, text, diaryType)
|
||||
if(diaryType)
|
||||
to_chat(world, "Diary: \[[diaryType]:[type]] [text]")
|
||||
else
|
||||
to_chat(world, "Log: \[[type]] [text]")
|
||||
|
||||
/**
|
||||
* var/disposed
|
||||
*
|
||||
@@ -35,4 +7,4 @@
|
||||
/datum/var/disposed
|
||||
// Garbage collection (controller).
|
||||
/datum/var/gcDestroyed
|
||||
/datum/var/timeDestroyed
|
||||
/datum/var/timeDestroyed
|
||||
|
||||
@@ -44,11 +44,10 @@
|
||||
// process running again.
|
||||
var/tmp/schedule_interval = PROCESS_DEFAULT_SCHEDULE_INTERVAL // run every 50 ticks
|
||||
|
||||
// Process sleep interval
|
||||
// This controls how often the process will yield (call sleep(0)) while it is running.
|
||||
// Every concurrent process should sleep periodically while running in order to allow other
|
||||
// processes to execute concurrently.
|
||||
var/tmp/sleep_interval
|
||||
// Process tick allowance
|
||||
// This controls what percentage a single tick (0 to 100) the process should be
|
||||
// allowed to run before sleeping.
|
||||
var/tmp/tick_allowance = PROCESS_DEFAULT_TICK_ALLOWANCE
|
||||
|
||||
// hang_warning_time - this is the time (in 1/10 seconds) after which the server will begin to show "maybe hung" in the context window
|
||||
var/tmp/hang_warning_time = PROCESS_DEFAULT_HANG_WARNING_TIME
|
||||
@@ -59,9 +58,6 @@
|
||||
// hang_restart_time - After this much time(in 1/10 seconds), the server will automatically kill and restart the process.
|
||||
var/tmp/hang_restart_time = PROCESS_DEFAULT_HANG_RESTART_TIME
|
||||
|
||||
// cpu_threshold - if world.cpu >= cpu_threshold, scheck() will call sleep(1) to defer further work until the next tick. This keeps a process from driving a tick into overtime (causing perceptible lag)
|
||||
var/tmp/cpu_threshold = PROCESS_DEFAULT_CPU_THRESHOLD
|
||||
|
||||
// How many times in the current run has the process deferred work till the next tick?
|
||||
var/tmp/cpu_defer_count = 0
|
||||
|
||||
@@ -75,6 +71,9 @@
|
||||
// Records the time (1/10s timeofday) at which the process last began running
|
||||
var/tmp/run_start = 0
|
||||
|
||||
// Records the world.tick_usage (0 to 100) at which the process last began running
|
||||
/var/tmp/tick_start = 0
|
||||
|
||||
// Records the number of times this process has been killed and restarted
|
||||
var/tmp/times_killed
|
||||
|
||||
@@ -91,19 +90,22 @@ datum/controller/process/New(var/datum/controller/processScheduler/scheduler)
|
||||
previousStatus = "idle"
|
||||
idle()
|
||||
name = "process"
|
||||
sleep_interval = world.tick_lag / PROCESS_DEFAULT_SLEEP_INTERVAL
|
||||
last_slept = 0
|
||||
run_start = 0
|
||||
tick_start = 0
|
||||
ticks = 0
|
||||
last_task = 0
|
||||
last_object = null
|
||||
|
||||
datum/controller/process/proc/started()
|
||||
// Initialize last_slept so we can know when to sleep
|
||||
last_slept = TimeOfHour
|
||||
// Initialize last_slept so we can record timing information
|
||||
last_slept = TimeOfGame
|
||||
|
||||
// Initialize run_start so we can detect hung processes.
|
||||
run_start = TimeOfHour
|
||||
run_start = TimeOfGame
|
||||
|
||||
// Initialize tick_start so we can know when to sleep
|
||||
tick_start = world.tick_usage
|
||||
|
||||
// Initialize defer count
|
||||
cpu_defer_count = 0
|
||||
@@ -160,13 +162,8 @@ datum/controller/process/proc/handleHung()
|
||||
if(istype(lastObj))
|
||||
lastObjType = lastObj.type
|
||||
|
||||
// If world.timeofday has rolled over, then we need to adjust.
|
||||
if (TimeOfHour < run_start)
|
||||
run_start -= 36000
|
||||
|
||||
var/msg = "[name] process hung at tick #[ticks]. Process was unresponsive for [(TimeOfHour - run_start) / 10] seconds and was restarted. Last task: [last_task]. Last Object Type: [lastObjType]"
|
||||
logTheThing("debug", null, null, msg)
|
||||
logTheThing("diary", null, null, msg, "debug")
|
||||
log_debug(msg)
|
||||
message_admins(msg)
|
||||
|
||||
main.restartProcess(src.name)
|
||||
@@ -174,15 +171,13 @@ datum/controller/process/proc/handleHung()
|
||||
datum/controller/process/proc/kill()
|
||||
if (!killed)
|
||||
var/msg = "[name] process was killed at tick #[ticks]."
|
||||
logTheThing("debug", null, null, msg)
|
||||
logTheThing("diary", null, null, msg, "debug")
|
||||
log_debug(msg)
|
||||
message_admins(msg)
|
||||
//finished()
|
||||
|
||||
// Allow inheritors to clean up if needed
|
||||
onKill()
|
||||
|
||||
killed = TRUE
|
||||
|
||||
// This should del
|
||||
del(src)
|
||||
|
||||
@@ -199,19 +194,15 @@ 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 (main.getCurrentTickElapsedTime() > main.timeAllowance)
|
||||
sleep(world.tick_lag*1)
|
||||
if (world.tick_usage > 100 || (world.tick_usage - tick_start) > tick_allowance)
|
||||
sleep(world.tick_lag)
|
||||
cpu_defer_count++
|
||||
last_slept = TimeOfHour
|
||||
else
|
||||
// If world.timeofday has rolled over, then we need to adjust.
|
||||
if (TimeOfHour < last_slept)
|
||||
last_slept -= 36000
|
||||
tick_start = world.tick_usage
|
||||
|
||||
if (TimeOfHour > last_slept + sleep_interval)
|
||||
// If we haven't slept in sleep_interval deciseconds, sleep to allow other work to proceed.
|
||||
sleep(0)
|
||||
last_slept = TimeOfHour
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
datum/controller/process/proc/update()
|
||||
// Clear delta
|
||||
@@ -231,9 +222,7 @@ datum/controller/process/proc/update()
|
||||
setStatus(PROCESS_STATUS_MAYBE_HUNG)
|
||||
|
||||
datum/controller/process/proc/getElapsedTime()
|
||||
if (TimeOfHour < run_start)
|
||||
return TimeOfHour - (run_start - 36000)
|
||||
return TimeOfHour - run_start
|
||||
return TimeOfGame - run_start
|
||||
|
||||
datum/controller/process/proc/tickDetail()
|
||||
return
|
||||
@@ -293,9 +282,9 @@ datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target
|
||||
main = target.main
|
||||
name = target.name
|
||||
schedule_interval = target.schedule_interval
|
||||
sleep_interval = target.sleep_interval
|
||||
last_slept = 0
|
||||
run_start = 0
|
||||
tick_start = 0
|
||||
times_killed = target.times_killed
|
||||
ticks = target.ticks
|
||||
last_task = target.last_task
|
||||
|
||||
@@ -42,17 +42,11 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
|
||||
var/tmp/currentTickStart = 0
|
||||
|
||||
var/tmp/timeAllowance = 0
|
||||
|
||||
var/tmp/cpuAverage = 0
|
||||
|
||||
var/tmp/timeAllowanceMax = 0
|
||||
|
||||
/datum/controller/processScheduler/New()
|
||||
..()
|
||||
scheduler_sleep_interval = world.tick_lag
|
||||
timeAllowance = world.tick_lag * 0.5
|
||||
timeAllowanceMax = world.tick_lag
|
||||
|
||||
/**
|
||||
* deferSetupFor
|
||||
@@ -68,10 +62,9 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
/datum/controller/processScheduler/proc/setup()
|
||||
// There can be only one
|
||||
if(processScheduler && (processScheduler != src))
|
||||
del(processScheduler)
|
||||
processScheduler = src
|
||||
else if(!processScheduler)
|
||||
processScheduler = src
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
var/process
|
||||
// Add all the processes we can find, except for the ticker
|
||||
for (process in typesof(/datum/controller/process) - /datum/controller/process)
|
||||
@@ -87,13 +80,7 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
process()
|
||||
|
||||
/datum/controller/processScheduler/proc/process()
|
||||
updateCurrentTickData()
|
||||
|
||||
for(var/i=world.tick_lag,i<world.tick_lag*50,i+=world.tick_lag)
|
||||
spawn(i) updateCurrentTickData()
|
||||
while(isRunning)
|
||||
// Hopefully spawning this for 50 ticks in the future will make it the first thing in the queue.
|
||||
spawn(world.tick_lag*50) updateCurrentTickData()
|
||||
checkRunningProcesses()
|
||||
queueProcesses()
|
||||
runQueuedProcesses()
|
||||
@@ -115,7 +102,6 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
// Check status changes
|
||||
if(status != previousStatus)
|
||||
//Status changed.
|
||||
|
||||
switch(status)
|
||||
if(PROCESS_STATUS_PROBABLY_HUNG)
|
||||
message_admins("Process '[p.name]' may be hung.")
|
||||
@@ -196,7 +182,6 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
|
||||
nameToProcessMap[newProcess.name] = newProcess
|
||||
|
||||
|
||||
/datum/controller/processScheduler/proc/runProcess(var/datum/controller/process/process)
|
||||
spawn(0)
|
||||
process.process()
|
||||
@@ -326,6 +311,11 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
var/datum/controller/process/process = nameToProcessMap[processName]
|
||||
process.disable()
|
||||
|
||||
/datum/controller/processScheduler/proc/sign(var/x)
|
||||
if (x == 0)
|
||||
return 1
|
||||
return x / abs(x)
|
||||
|
||||
/datum/controller/processScheduler/proc/getProcess(var/name)
|
||||
return nameToProcessMap[name]
|
||||
|
||||
@@ -334,32 +324,3 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
|
||||
/datum/controller/processScheduler/proc/getIsRunning()
|
||||
return isRunning
|
||||
|
||||
/datum/controller/processScheduler/proc/getCurrentTickElapsedTime()
|
||||
if (world.time > currentTick)
|
||||
updateCurrentTickData()
|
||||
return 0
|
||||
else
|
||||
return TimeOfHour - currentTickStart
|
||||
|
||||
/datum/controller/processScheduler/proc/updateCurrentTickData()
|
||||
if (world.time > currentTick)
|
||||
// New tick!
|
||||
currentTick = world.time
|
||||
currentTickStart = TimeOfHour
|
||||
updateTimeAllowance()
|
||||
cpuAverage = (world.cpu + cpuAverage + cpuAverage) / 3
|
||||
|
||||
|
||||
/datum/controller/processScheduler/proc/updateTimeAllowance()
|
||||
// Time allowance goes down linearly with world.cpu.
|
||||
var/tmp/error = cpuAverage - 100
|
||||
var/tmp/timeAllowanceDelta = sign(error) * -0.5 * world.tick_lag * max(0, 0.01 * abs(error))
|
||||
|
||||
//timeAllowance = world.tick_lag * min(1, 0.5 * ((200/max(1,cpuAverage)) - 1))
|
||||
timeAllowance = min(timeAllowanceMax, max(0, timeAllowance + timeAllowanceDelta))
|
||||
|
||||
/datum/controller/processScheduler/proc/sign(var/x)
|
||||
if (x == 0)
|
||||
return 1
|
||||
return x / abs(x)
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
if(type == "config")
|
||||
switch (name)
|
||||
if ("resource_urls")
|
||||
config.resource_urls = text2list(value, " ")
|
||||
config.resource_urls = splittext(value, " ")
|
||||
|
||||
if ("admin_legacy_system")
|
||||
config.admin_legacy_system = 1
|
||||
|
||||
@@ -18,7 +18,7 @@ var/soft_dels = 0
|
||||
if(L.len == 1)
|
||||
to_chat(usr, "No garbage collector deletions this round")
|
||||
return
|
||||
usr << browse(list2text(L),"window=harddellogs")
|
||||
usr << browse(jointext(L,""),"window=harddellogs")
|
||||
|
||||
/datum/garbage_collector
|
||||
var/list/queue = new
|
||||
@@ -193,4 +193,4 @@ var/soft_dels = 0
|
||||
testing("Found [src.type] \ref[src] in [thing.type]'s [varname] list var.")
|
||||
testing("Completed search for references to a [type].")
|
||||
usr.client.running_find_references = null
|
||||
*/
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user