SSair correctness improvments (#28057)

This commit is contained in:
Charlie Nolan
2025-01-21 20:09:14 -08:00
committed by GitHub
parent fda350cd1e
commit 28b41d925d
5 changed files with 35 additions and 43 deletions
+23 -32
View File
@@ -17,6 +17,10 @@ SUBSYSTEM_DEF(air)
flags = SS_BACKGROUND | SS_TICKER
/// How long we actually wait between ticks. Will round up to the next server tick.
var/self_wait = 0.15 SECONDS
/// MC seems to not be good at tracking whether SSair pauses, so track that ourselves.
var/was_paused = FALSE
/// And that means we also nee a replacement for times_fired.
var/milla_tick = 0
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Turfs will no longer process atmos, and all atmospheric machines (including cryotubes) will no longer function. Shuttle call recommended."
cpu_display = SS_CPUDISPLAY_HIGH
@@ -186,6 +190,10 @@ SUBSYSTEM_DEF(air)
currentpart = SSair.currentpart
milla_idle = SSair.milla_idle
/datum/controller/subsystem/air/pause()
was_paused = TRUE
return ..()
/datum/controller/subsystem/air/fire(resumed = 0)
// All atmos stuff assumes MILLA is synchronous. Ensure it actually is.
var/now = world.timeofday + (world.tick_lag * world.tick_usage) / 100
@@ -200,12 +208,13 @@ SUBSYSTEM_DEF(air)
// Run the sleepless callbacks again in case more showed up since on_milla_tick_finished()
run_sleepless_callbacks()
fire_sleepless(resumed)
fire_sleepless(resumed || was_paused)
/datum/controller/subsystem/air/proc/fire_sleepless(resumed)
// Any proc that wants MILLA to be synchronous should not sleep.
SHOULD_NOT_SLEEP(TRUE)
in_milla_safe_code = TRUE
was_paused = FALSE
var/timer = TICK_USAGE_REAL
@@ -317,6 +326,7 @@ SUBSYSTEM_DEF(air)
timer = TICK_USAGE_REAL
spawn_milla_tick_thread()
milla_tick++
milla_idle = FALSE
cost_milla_tick = MC_AVERAGE(cost_milla_tick, get_milla_tick_time())
@@ -415,9 +425,9 @@ SUBSYSTEM_DEF(air)
// Bind the MILLA tile we got, if needed.
if(isnull(T.bound_air))
bind_turf(T, milla_tile)
else if(T.bound_air.lastread < times_fired)
else if(T.bound_air.lastread < milla_tick)
T.bound_air.copy_from_milla(milla_tile)
T.bound_air.lastread = times_fired
T.bound_air.lastread = milla_tick
T.bound_air.readonly = null
T.bound_air.dirty = FALSE
T.bound_air.synchronized = FALSE
@@ -446,7 +456,7 @@ SUBSYSTEM_DEF(air)
if(isnull(S.wind_tick))
// Didn't have wind before, add it.
windy_tiles += S
S.wind_tick = times_fired
S.wind_tick = milla_tick
S.wind_x = x_flow
S.wind_y = y_flow
T.high_pressure_movements(x_flow, y_flow)
@@ -463,15 +473,17 @@ SUBSYSTEM_DEF(air)
var/list/currentrun = src.currentrun
while(length(currentrun))
var/turf/simulated/S = currentrun[length(currentrun)]
currentrun.len--
if(!istype(S))
currentrun.len--
continue
if(S.update_hotspot())
// Is still a hotspot, keep it.
new_hotspots += S
currentrun.len--
if(MC_TICK_CHECK)
return
@@ -627,33 +639,12 @@ SUBSYSTEM_DEF(air)
/datum/controller/subsystem/air/proc/setup_turfs(turf/low_corner = locate(1, 1, 1), turf/high_corner = locate(world.maxx, world.maxy, world.maxz))
for(var/turf/T as anything in block(low_corner, high_corner))
T.Initialize_Atmos(times_fired)
T.Initialize_Atmos(milla_tick)
milla_load_turfs(low_corner, high_corner)
for(var/turf/T as anything in block(low_corner, high_corner))
T.milla_data.len = 0
T.milla_data = null
/datum/controller/subsystem/air/proc/setup_write_to_milla()
var/watch = start_watch()
log_startup_progress("Writing tiles to MILLA...")
//cache for sanic speed (lists are references anyways)
var/list/cache = bound_mixtures
var/count = length(cache)
while(length(cache))
var/datum/gas_mixture/bound_to_turf/mixture = cache[length(cache)]
cache.len--
if(mixture.dirty)
in_milla_safe_code = TRUE
// This is one of two places expected to call this otherwise-unsafe method.
mixture.private_unsafe_write()
in_milla_safe_code = FALSE
mixture.bound_turf.bound_air = null
mixture.bound_turf = null
CHECK_TICK
log_startup_progress("Wrote [count] tiles in [stop_watch(watch)]s.")
/datum/controller/subsystem/air/proc/setup_atmos_machinery(list/machines_to_init)
var/watch = start_watch()
log_startup_progress("Initializing atmospherics machinery...")
@@ -713,7 +704,7 @@ SUBSYSTEM_DEF(air)
milla_tile = new/list(MILLA_TILE_SIZE)
get_tile_atmos(T, milla_tile)
B.copy_from_milla(milla_tile)
B.lastread = src.times_fired
B.lastread = src.milla_tick
B.readonly = null
B.dirty = FALSE
B.synchronized = FALSE
@@ -832,11 +823,11 @@ SUBSYSTEM_DEF(air)
soft_assert_safe()
// This is one of two intended places to call this otherwise-unsafe proc.
var/datum/gas_mixture/bound_to_turf/air = T.private_unsafe_get_air()
if(air.lastread < SSair.times_fired)
if(air.lastread < SSair.milla_tick)
var/list/milla_tile = new/list(MILLA_TILE_SIZE)
get_tile_atmos(T, milla_tile)
air.copy_from_milla(milla_tile)
air.lastread = SSair.times_fired
air.lastread = SSair.milla_tick
air.readonly = null
air.dirty = FALSE
if(!air.synchronized)
@@ -882,11 +873,11 @@ SUBSYSTEM_DEF(air)
soft_assert_safe()
// This is one of two intended places to call this otherwise-unsafe proc.
var/datum/gas_mixture/bound_to_turf/air = T.private_unsafe_get_air()
if(air.lastread < SSair.times_fired)
if(air.lastread < SSair.milla_tick)
var/list/milla_tile = new/list(MILLA_TILE_SIZE)
get_tile_atmos(T, milla_tile)
air.copy_from_milla(milla_tile)
air.lastread = SSair.times_fired
air.lastread = SSair.milla_tick
air.readonly = null
air.dirty = FALSE
if(!air.synchronized)
+5 -5
View File
@@ -641,11 +641,11 @@
RETURN_TYPE(/datum/gas_mixture)
// This is one of two intended places to call this otherwise-unsafe proc.
var/datum/gas_mixture/bound_to_turf/air = private_unsafe_get_air()
if(air.lastread < SSair.times_fired)
if(air.lastread < SSair.milla_tick)
var/list/milla_tile = new/list(MILLA_TILE_SIZE)
get_tile_atmos(src, milla_tile)
air.copy_from_milla(milla_tile)
air.lastread = SSair.times_fired
air.lastread = SSair.milla_tick
air.readonly = null
air.dirty = FALSE
air.synchronized = FALSE
@@ -678,7 +678,7 @@
return FALSE
// If it's old, delete it.
if(active_hotspot.death_timer < SSair.times_fired)
if(active_hotspot.death_timer < SSair.milla_tick)
QDEL_NULL(active_hotspot)
return FALSE
else
@@ -687,7 +687,7 @@
if(isnull(active_hotspot))
active_hotspot = new(src)
active_hotspot.death_timer = SSair.times_fired + 4
active_hotspot.death_timer = SSair.milla_tick + 4
if(air.hotspot_volume() > 0)
active_hotspot.temperature = air.hotspot_temperature()
active_hotspot.volume = air.hotspot_volume() * CELL_VOLUME
@@ -699,7 +699,7 @@
return TRUE
/turf/simulated/proc/update_wind()
if(wind_tick != SSair.times_fired)
if(wind_tick != SSair.milla_tick)
QDEL_NULL(wind_effect)
wind_tick = null
return FALSE
@@ -129,9 +129,9 @@
if(direction == 0)
return
if(last_high_pressure_movement_time >= SSair.times_fired - 3)
if(last_high_pressure_movement_time >= SSair.milla_tick - 3)
return
last_high_pressure_movement_time = SSair.times_fired
last_high_pressure_movement_time = SSair.milla_tick
air_push(direction, (force - force_needed) / force_needed)
@@ -171,7 +171,7 @@
#define INDEX_SOUTH 3
#define INDEX_WEST 4
/turf/proc/Initialize_Atmos(times_fired)
/turf/proc/Initialize_Atmos(milla_tick)
// This is one of two places expected to call this otherwise-unsafe method.
var/list/connectivity = private_unsafe_recalculate_atmos_connectivity()
var/list/air = list(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature)
@@ -762,6 +762,7 @@ What are the archived variables for?
#undef QUANTIZE
/datum/gas_mixture/bound_to_turf
synchronized = FALSE
var/dirty = FALSE
var/lastread = 0
var/turf/bound_turf = null
@@ -32,11 +32,11 @@
if(!partner)
return 0
if(!SSair || SSair.times_fired <= update_cycle)
if(!SSair || SSair.milla_tick <= update_cycle)
return 0
update_cycle = SSair.times_fired
partner.update_cycle = SSair.times_fired
update_cycle = SSair.milla_tick
partner.update_cycle = SSair.milla_tick
var/air_heat_capacity = air_contents.heat_capacity()
var/other_air_heat_capacity = partner.air_contents.heat_capacity()