Skip to content

MC/Subsystem improvements #6710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/__DEFINES/MC.dm
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@
/// It should not be used simply to silence CI.
#define SS_OK_TO_FAIL_INIT (1 << 6)

/// This subsystem should not be queued if it has no work.
/// Populate the [hibernate_checks] list with the names of vars to check before a subsystem is queued.
/// If the length() of each var is 0, it will not be queued.
#define SS_HIBERNATE (1 << 7)

//! SUBSYSTEM STATES
#define SS_IDLE 0 /// ain't doing shit.
#define SS_QUEUED 1 /// queued to run
Expand Down
7 changes: 4 additions & 3 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@
#define FIRE_PRIORITY_RESEARCH 10
#define FIRE_PRIORITY_VIS 10
#define FIRE_PRIORITY_AMBIENCE 10
#define FIRE_PRIORITY_GLOWSHROOMS 10 // monkestation addition: glowshroom processing subsystem
#define FIRE_PRIORITY_MEMORY_STATS 10 // monkestation addition: memory stats subsystem. uses a low priority as it takes a moment to fully profile memory.
#define FIRE_PRIORITY_GLOWSHROOMS 10
#define FIRE_PRIORITY_MEMORY_STATS 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_DATABASE 16
#define FIRE_PRIORITY_WET_FLOORS 20
Expand All @@ -230,10 +230,11 @@
#define FIRE_PRIORITY_ACID 40
#define FIRE_PRIORITY_BURNING 40
#define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PLEXORA 60 // monkestation addition: plexora
#define FIRE_PRIORITY_PLEXORA 60
#define FIRE_PRIORITY_PARALLAX 65
#define FIRE_PRIORITY_INSTRUMENTS 80
#define FIRE_PRIORITY_FLUIDS 80
#define FIRE_PRIORITY_PRIORITY_EFFECTS 90
#define FIRE_PRIORITY_STAMINA 95
#define FIRE_PRIORITY_MOBS 100
#define FIRE_PRIORITY_ASSETS 105
Expand Down
28 changes: 28 additions & 0 deletions code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,23 @@ GLOBAL_REAL(Master, /datum/controller/master)
to_chat(world, chat_message)
log_world(message)

#ifndef OPENDREAM
var/static/no_memstat = FALSE
if(no_memstat)
return
try
if(!rustg_file_exists(MEMORYSTATS_DLL_PATH))
no_memstat = TRUE
return
var/memory_summary = trimtext(replacetext(call_ext(MEMORYSTATS_DLL_PATH, "memory_stats")(), "Server mem usage:", ""))
if(memory_summary)
rustg_file_append("=== [subsystem.name] ===\n[memory_summary]\n", "[GLOB.log_directory]/profiler/memstat-init.txt")
else
no_memstat = TRUE
catch
no_memstat = TRUE
#endif

/datum/controller/master/proc/SetRunLevel(new_runlevel)
var/old_runlevel = current_runlevel
if(isnull(old_runlevel))
Expand Down Expand Up @@ -616,6 +633,17 @@ GLOBAL_REAL(Master, /datum/controller/master)
SS.postponed_fires--
SS.update_nextfire()
continue
if(SS_flags & SS_HIBERNATE)
var/list/check_vars = SS.hibernate_checks
var/enter_queue
for(var/i in 1 to length(check_vars))
if(LAZYLEN(SS.vars[check_vars[i]]))
enter_queue = TRUE
break
if(!enter_queue)
SS.hibernating = TRUE
SS.update_nextfire()
continue
SS.enqueue()
. = 1

Expand Down
12 changes: 12 additions & 0 deletions code/controllers/subsystem.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@

///Bitmap of what game states can this subsystem fire at. See [RUNLEVELS_DEFAULT] for more details.
var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire

///A list of var names present on this subsystem to be checked during CheckQueue. See [SS_HIBERNATE] for usage.
var/list/hibernate_checks

///Subsystem ID. Used for when we need a technical name for the SS used by SSmetrics
var/ss_id = "generic_ss_id"

Expand All @@ -56,6 +60,9 @@
/// Scheduled world.time for next fire()
var/next_fire = 0

/// The subsystem had no work during CheckQueue and was not queued.
var/hibernating

/// Running average of the amount of milliseconds it takes the subsystem to complete a run (including all resumes but not the time spent paused)
var/cost = 0

Expand Down Expand Up @@ -185,6 +192,8 @@
/// (we loop thru a linked list until we get to the end or find the right point)
/// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
/datum/controller/subsystem/proc/enqueue()
hibernating = FALSE

var/SS_priority = priority
var/SS_flags = flags
var/datum/controller/subsystem/queue_node
Expand Down Expand Up @@ -281,6 +290,9 @@
return msg

/datum/controller/subsystem/proc/state_letter()
if(hibernating)
return "H"

switch (state)
if (SS_RUNNING)
. = "R"
Expand Down
1 change: 0 additions & 1 deletion code/controllers/subsystem/air.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ SUBSYSTEM_DEF(air)
var/list/reaction_handbook
var/list/gas_handbook


/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
msg += "AT:[round(cost_turfs,1)]|"
Expand Down
8 changes: 7 additions & 1 deletion code/controllers/subsystem/asset_loading.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
SUBSYSTEM_DEF(asset_loading)
name = "Asset Loading"
priority = FIRE_PRIORITY_ASSETS
flags = SS_NO_INIT
flags = SS_NO_INIT | SS_HIBERNATE
runlevels = RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT
var/list/datum/asset/generate_queue = list()

/datum/controller/subsystem/asset_loading/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, generate_queue),
)

/datum/controller/subsystem/asset_loading/fire(resumed)
while(length(generate_queue))
var/datum/asset/to_load = generate_queue[generate_queue.len]
Expand Down
9 changes: 8 additions & 1 deletion code/controllers/subsystem/augury.dm
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
SUBSYSTEM_DEF(augury)
name = "Augury"
flags = SS_NO_INIT
flags = SS_NO_INIT | SS_HIBERNATE
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

var/list/watchers = list()
var/list/doombringers = list()

var/list/observers_given_action = list()

/datum/controller/subsystem/augury/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, watchers),
NAMEOF(src, doombringers),
)

/datum/controller/subsystem/augury/stat_entry(msg)
msg = "W:[watchers.len]|D:[length(doombringers)]"
return ..()
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/blackbox.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(blackbox)
name = "Blackbox"
wait = 6000
wait = 10 MINUTES
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
init_order = INIT_ORDER_BLACKBOX

Expand Down
8 changes: 7 additions & 1 deletion code/controllers/subsystem/blackmarket.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(blackmarket)
name = "Blackmarket"
flags = SS_BACKGROUND
flags = SS_BACKGROUND | SS_HIBERNATE
init_order = INIT_ORDER_DEFAULT

/// Descriptions for each shipping methods.
Expand All @@ -18,6 +18,12 @@ SUBSYSTEM_DEF(blackmarket)
/// Currently queued purchases.
var/list/queued_purchases = list()

/datum/controller/subsystem/blackmarket/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, queued_purchases),
)

/datum/controller/subsystem/blackmarket/Initialize()
for(var/market in subtypesof(/datum/market) - /datum/market/auction - /datum/market/restock) //monkestation edit - MODULAR_GUNS
markets[market] += new market
Expand Down
9 changes: 8 additions & 1 deletion code/controllers/subsystem/circuit_component.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(circuit_component)
name = "Circuit Components"
wait = 0.1 SECONDS
priority = FIRE_PRIORITY_DEFAULT
flags = SS_NO_INIT
flags = SS_NO_INIT | SS_HIBERNATE

var/list/callbacks_to_invoke = list()
var/list/currentrun = list()
Expand All @@ -14,6 +14,13 @@ SUBSYSTEM_DEF(circuit_component)
var/instant_run_max_cpu_usage = 10
var/list/instant_run_callbacks_to_run = list()

/datum/controller/subsystem/circuit_component/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, callbacks_to_invoke),
NAMEOF(src, currentrun),
)

/datum/controller/subsystem/circuit_component/fire(resumed)
if(!resumed)
currentrun = callbacks_to_invoke.Copy()
Expand Down
8 changes: 7 additions & 1 deletion code/controllers/subsystem/dbcore.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#define SHUTDOWN_QUERY_TIMELIMIT (1 MINUTES)
SUBSYSTEM_DEF(dbcore)
name = "Database"
flags = SS_TICKER
flags = SS_TICKER | SS_HIBERNATE
wait = 10 // Not seconds because we're running on SS_TICKER
runlevels = RUNLEVEL_INIT|RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT
init_order = INIT_ORDER_DBCORE
Expand Down Expand Up @@ -48,6 +48,12 @@ SUBSYSTEM_DEF(dbcore)

var/db_daemon_started = FALSE

/datum/controller/subsystem/dbcore/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, all_queries),
)

/datum/controller/subsystem/dbcore/Initialize()
//We send warnings to the admins during subsystem init, as the clients will be New'd and messages
//will queue properly with goonchat
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/dcs.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(dcs)
name = "Datum Component System"
flags = SS_NO_INIT
flags = SS_NO_INIT | SS_HIBERNATE
wait = 1 SECONDS

var/list/elements_by_type = list()
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/discord.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
SUBSYSTEM_DEF(discord)
name = "Discord"
wait = 3000
wait = 5 MINUTES
init_order = INIT_ORDER_DISCORD

/// People to save to notify file
Expand Down
2 changes: 2 additions & 0 deletions code/controllers/subsystem/economy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ SUBSYSTEM_DEF(economy)
/// Tracks a temporary sum of all money in the system
/// We need this on the subsystem because of yielding and such
var/temporary_total = 0
/// The mail crate we last generated.
var/obj/structure/closet/crate/mail/economy/mail_crate

/datum/controller/subsystem/economy/Initialize()
//removes cargo from the split
Expand Down
16 changes: 14 additions & 2 deletions code/controllers/subsystem/explosions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ SUBSYSTEM_DEF(explosions)
name = "Explosions"
init_order = INIT_ORDER_EXPLOSIONS
priority = FIRE_PRIORITY_EXPLOSIONS
wait = 1
flags = SS_TICKER|SS_NO_INIT
wait = 0
flags = SS_TICKER | SS_NO_INIT | SS_HIBERNATE
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

var/cost_lowturf = 0
Expand Down Expand Up @@ -40,6 +40,18 @@ SUBSYSTEM_DEF(explosions)

var/currentpart = SSAIR_PIPENETS

/datum/controller/subsystem/explosions/PreInit(start_timeofday)
. = ..()
hibernate_checks = list(
NAMEOF(src, lowturf),
NAMEOF(src, medturf),
NAMEOF(src, highturf),
NAMEOF(src, flameturf),
NAMEOF(src, throwturf),
NAMEOF(src, low_mov_atom),
NAMEOF(src, med_mov_atom),
NAMEOF(src, high_mov_atom),
)

/datum/controller/subsystem/explosions/stat_entry(msg)
msg += "C:{"
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/fluids.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ SUBSYSTEM_DEF(fluids)
name = "Fluid"
wait = 0 // Will be autoset to whatever makes the most sense given the spread and effect waits.
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
init_order = INIT_ORDER_FLUIDS
priority = FIRE_PRIORITY_FLUIDS

Expand Down
11 changes: 9 additions & 2 deletions code/controllers/subsystem/icon_smooth.dm
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
SUBSYSTEM_DEF(icon_smooth)
name = "Icon Smoothing"
init_order = INIT_ORDER_ICON_SMOOTHING
wait = 1
wait = 0
priority = FIRE_PRIORITY_SMOOTHING
flags = SS_TICKER
flags = SS_TICKER | SS_HIBERNATE

///Blueprints assemble an image of what pipes/manifolds/wires look like on initialization, and thus should be taken after everything's been smoothed
var/list/blueprint_queue = list()
var/list/smooth_queue = list()
var/list/deferred = list()
var/list/deferred_by_source = list()

/datum/controller/subsystem/icon_smooth/PreInit(start_timeofday)
. = ..()
hibernate_checks = list(
NAMEOF(src, smooth_queue),
NAMEOF(src, deferred),
)

/datum/controller/subsystem/icon_smooth/fire()
// We do not want to smooth icons of atoms whose neighbors are not initialized yet,
// this causes runtimes.
Expand Down
14 changes: 6 additions & 8 deletions code/controllers/subsystem/init_profiler.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* monkestation edit: reimplemented in [monkestation\code\controllers\subsystem\init_profiler.dm]
#define INIT_PROFILE_NAME "init_profiler.json"

///Subsystem exists so we can separately log init time costs from the costs of general operation
Expand All @@ -12,19 +11,18 @@ SUBSYSTEM_DEF(init_profiler)
/datum/controller/subsystem/init_profiler/Initialize()
if(CONFIG_GET(flag/auto_profile))
write_init_profile()
return SS_INIT_SUCCESS
return SS_INIT_SUCCESS
return SS_INIT_NO_NEED

/datum/controller/subsystem/init_profiler/proc/write_init_profile()
var/current_profile_data = world.Profile(PROFILE_REFRESH, format = "json")
var/list/current_profile_data = world.Profile(PROFILE_REFRESH, format = "json")
current_profile_data = json_decode(current_profile_data) // yes this is stupid but this gets us a list in a non-awful format
CHECK_TICK
sortTim(current_profile_data, GLOBAL_PROC_REF(sort_overtime_dsc))

if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
stack_trace("Warning, profiling stopped manually before dump.")
var/prof_file = file("[GLOB.log_directory]/[INIT_PROFILE_NAME]")
if(fexists(prof_file))
fdel(prof_file)
WRITE_FILE(prof_file, current_profile_data)
rustg_file_write(json_encode(current_profile_data), "[GLOB.log_directory]/[INIT_PROFILE_NAME]")
world.Profile(PROFILE_CLEAR) //Now that we're written this data out, dump it. We don't want it getting mixed up with our current round data

#undef INIT_PROFILE_NAME
monkestation end */
13 changes: 10 additions & 3 deletions code/controllers/subsystem/lighting.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
SUBSYSTEM_DEF(lighting)
name = "Lighting"
wait = 2
wait = 0
init_order = INIT_ORDER_LIGHTING
flags = SS_TICKER
flags = SS_HIBERNATE
var/static/list/sources_queue = list() // List of lighting sources queued for update.
var/static/list/corners_queue = list() // List of lighting corners queued for update.
var/static/list/objects_queue = list() // List of lighting objects queued for update.
Expand All @@ -11,11 +11,18 @@ SUBSYSTEM_DEF(lighting)
var/allow_duped_corners = FALSE
#endif

/datum/controller/subsystem/lighting/PreInit()
. = ..()
hibernate_checks = list(
NAMEOF(src, sources_queue),
NAMEOF(src, corners_queue),
NAMEOF(src, objects_queue),
)

/datum/controller/subsystem/lighting/stat_entry(msg)
msg = "L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]"
return ..()


/datum/controller/subsystem/lighting/Initialize()
if(!initialized)
create_all_lighting_objects()
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/moods.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(mood)
name = "Mood"
flags = SS_NO_INIT | SS_BACKGROUND
flags = SS_NO_INIT | SS_BACKGROUND | SS_HIBERNATE
priority = 20
wait = 1 SECONDS
Loading
Loading