Skip to content
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

[TM] Revert milla optimizations #1744

Closed
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: 0 additions & 5 deletions code/__DEFINES/rust.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@
/proc/milla_init_z(z)
return RUSTLIB_CALL(milla_initialize, z)

/proc/milla_load_turfs(turf/low_corner, turf/high_corner)
ASSERT(istype(low_corner))
ASSERT(istype(high_corner))
return RUSTLIB_CALL(milla_load_turfs, "milla_data", low_corner, high_corner)

/proc/set_tile_atmos(turf/T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)
return RUSTLIB_CALL(milla_set_tile, T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)

Expand Down
134 changes: 24 additions & 110 deletions code/controllers/subsystem/SSair.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,14 @@ SUBSYSTEM_DEF(air)
/// Which step we're currently on, used to let us resume if our time budget elapses.
var/currentpart = SSAIR_DEFERREDPIPENETS

/// Is MILLA currently idle? TRUE if the MILLA tick has finished, meaning data is fresh and changes can be made. FALSE if MILLA is currently running a tick, meaning data is from last tick and changes cannot be made.
var/milla_idle = TRUE
/// Is MILLA currently in synchronous mode? TRUE if data is fresh and changes can be made, FALSE if data is from last tick and changes cannot be made (because this tick is still processing).
var/is_synchronous = TRUE

/// Are we currently running in a MILLA-safe context, i.e. is milla_idle *guaranteed* to be TRUE. Nothing outside of this file should change this.
/// Are we currently running in a MILLA-safe context, i.e. is is_synchronous *guaranteed* to be TRUE. Nothing outside of this file should change this.
VAR_PRIVATE/in_milla_safe_code = FALSE

/// What sleeping callbacks are currently running?
VAR_PRIVATE/list/sleepers = list()

/// A list of callbacks waiting for MILLA to finish its tick and enter synchronous mode.
var/list/waiting_for_sync = list()
var/list/sleepable_waiting_for_sync = list()

/// The coordinates of the pressure image we're currently loading.
var/pressure_x = 0
Expand Down Expand Up @@ -161,7 +157,8 @@ SUBSYSTEM_DEF(air)
in_milla_safe_code = TRUE

setup_overlays() // Assign icons and such for gas-turf-overlays
setup_turfs()
setup_allturfs()
setup_write_to_milla()
setup_atmos_machinery(GLOB.machines)
setup_pipenets(GLOB.machines)
for(var/obj/machinery/atmospherics/A in machinery_to_construct)
Expand All @@ -176,26 +173,23 @@ SUBSYSTEM_DEF(air)
machinery_to_construct = SSair.machinery_to_construct
currentrun = SSair.currentrun
currentpart = SSair.currentpart
milla_idle = SSair.milla_idle
is_synchronous = SSair.is_synchronous

#define SLEEPABLE_TIMER (world.time + world.tick_usage * world.tick_lag / 100)
/datum/controller/subsystem/air/fire(resumed = 0)
// All atmos stuff assumes MILLA is synchronous. Ensure it actually is.
if(!milla_idle || length(sleepers) > 0)
if(!is_synchronous)
var/timer = SLEEPABLE_TIMER

while(!milla_idle || length(sleepers) > 0)
while(!is_synchronous)
// Sleep for 1ms.
sleep(0.01)
var/new_timer = SLEEPABLE_TIMER
time_slept.record_progress((new_timer - timer) * 100, FALSE)
timer = new_timer
if(MC_TICK_CHECK)
time_slept.record_progress((SLEEPABLE_TIMER - timer) * 100, FALSE)
return

time_slept.record_progress((SLEEPABLE_TIMER - timer) * 100, TRUE)

// Run the sleepless callbacks again in case more showed up since on_milla_tick_finished()
run_sleepless_callbacks()

fire_sleepless(resumed)
#undef SLEEPABLE_TIMER

Expand Down Expand Up @@ -314,7 +308,7 @@ SUBSYSTEM_DEF(air)
timer = TICK_USAGE_REAL

spawn_milla_tick_thread()
milla_idle = FALSE
is_synchronous = FALSE

cost_milla_tick = MC_AVERAGE(cost_milla_tick, get_milla_tick_time())
cost_full.record_progress(TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer), state != SS_PAUSED && state != SS_PAUSING)
Expand Down Expand Up @@ -620,10 +614,14 @@ SUBSYSTEM_DEF(air)
last_bound_mixtures = length(bound_mixtures)
return

/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))
/datum/controller/subsystem/air/proc/setup_allturfs(list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)))
for(var/turf/T as anything in turfs_to_init)
T.Initialize_Atmos(times_fired)
CHECK_TICK

/datum/controller/subsystem/air/proc/setup_allturfs_sleepless(list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)))
for(var/turf/T as anything in turfs_to_init)
T.Initialize_Atmos(times_fired)
milla_load_turfs(low_corner, high_corner)

/datum/controller/subsystem/air/proc/setup_write_to_milla()
var/watch = start_watch()
Expand Down Expand Up @@ -716,62 +714,28 @@ SUBSYSTEM_DEF(air)
// Any proc that wants MILLA to be synchronous should not sleep.
SHOULD_NOT_SLEEP(TRUE)

// Just in case someone is naughty and decides to sleep, make sure that this method runs fully anyway.
set waitfor = FALSE

if(milla_idle)
if(is_synchronous)
var/was_safe = SSair.in_milla_safe_code
SSair.in_milla_safe_code = TRUE
// This is one of four intended places to call this otherwise-unsafe proc.
// This is one of two intended places to call this otherwise-unsafe proc.
CB.private_unsafe_invoke()
SSair.in_milla_safe_code = was_safe
return

waiting_for_sync += CB

/// Similar to addtimer, but triggers once MILLA enters synchronous mode. This version allows for sleeping if it's absolutely necessary.
/datum/controller/subsystem/air/proc/sleepable_synchronize(datum/milla_safe_must_sleep/CB)
if(length(sleepers))
sleepers += CB
// This is one of four intended places to call this otherwise-unsafe proc.
CB.private_unsafe_invoke()
sleepers -= CB
return

sleepable_waiting_for_sync += CB

/datum/controller/subsystem/air/proc/is_in_milla_safe_code()
return in_milla_safe_code || length(sleepers) > 0
return in_milla_safe_code

/datum/controller/subsystem/air/proc/on_milla_tick_finished()
milla_idle = TRUE
run_sleepless_callbacks()
run_sleeping_callbacks()

/datum/controller/subsystem/air/proc/run_sleepless_callbacks()
// Just in case someone is naughty and decides to sleep, make sure that this method runs fully anyway.
set waitfor = FALSE

is_synchronous = TRUE
in_milla_safe_code = TRUE
for(var/datum/milla_safe/CB as anything in waiting_for_sync)
// This is one of four intended places to call this otherwise-unsafe proc.
// This is one of two intended places to call this otherwise-unsafe proc.
CB.private_unsafe_invoke()
waiting_for_sync.Cut()
in_milla_safe_code = FALSE

/datum/controller/subsystem/air/proc/run_sleeping_callbacks()
in_milla_safe_code = TRUE
for(var/datum/milla_safe_must_sleep/CB as anything in sleepable_waiting_for_sync)
sleepers += CB
// This is one of four intended places to call this otherwise-unsafe proc.
CB.private_unsafe_invoke()
sleepers -= CB
sleepable_waiting_for_sync.Cut()
in_milla_safe_code = FALSE

/datum/controller/subsystem/air/proc/has_sleeper(datum/milla_safe_must_sleep/sleeper)
return sleeper in sleepers

/proc/milla_tick_finished()
// Any proc that wants MILLA to be synchronous should not sleep.
SHOULD_NOT_SLEEP(TRUE)
Expand Down Expand Up @@ -846,56 +810,6 @@ SUBSYSTEM_DEF(air)
var/datum/gas_mixture/turf_air = get_turf_air(T)
turf_air.copy_from(air)

/// Create a subclass of this and implement `on_run` to manipulate tile air safely. ONLY USE THIS VERSION IF YOU CAN'T AVOID SLEEPING; it will delay atmos ticks!
/datum/milla_safe_must_sleep
var/run_args = list()

/// All subclasses should implement this.
/datum/milla_safe_must_sleep/proc/on_run(...)
CRASH("[src.type] does not implement on_run")

/// Call this to make the subclass run when it's safe to do so. Args will be passed to on_run.
/datum/milla_safe_must_sleep/proc/invoke_async(...)
run_args = args.Copy()
SSair.sleepable_synchronize(src)

/// Do not call this yourself. This is what is called to run your code from a safe context.
/datum/milla_safe_must_sleep/proc/private_unsafe_invoke()
soft_assert_safe()
on_run(arglist(run_args))

/// Used internally to check that we're running safely, but without breaking things worse if we aren't.
/datum/milla_safe_must_sleep/proc/soft_assert_safe()
ASSERT(SSair.has_sleeper(src))

/// Fetch the air for a turf. Only use from `on_run`.
/datum/milla_safe_must_sleep/proc/get_turf_air(turf/T)
RETURN_TYPE(/datum/gas_mixture)
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)
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.readonly = null
air.dirty = FALSE
if(!air.synchronized)
air.synchronized = TRUE
SSair.bound_mixtures += air
return air

/// Add air to a turf. Only use from `on_run`.
/datum/milla_safe_must_sleep/proc/add_turf_air(turf/T, datum/gas_mixture/air)
var/datum/gas_mixture/turf_air = get_turf_air(T)
turf_air.merge(air)

/// Completely replace the air for a turf. Only use from `on_run`.
/datum/milla_safe_must_sleep/proc/set_turf_air(turf/T, datum/gas_mixture/air)
var/datum/gas_mixture/turf_air = get_turf_air(T)
turf_air.copy_from(air)

#undef SSAIR_DEFERREDPIPENETS
#undef SSAIR_PIPENETS
#undef SSAIR_ATMOSMACHINERY
Expand Down
8 changes: 4 additions & 4 deletions code/datums/helper_datums/map_template.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@
stack_trace("One of the smoothing corners is bust")
catch(var/exception/e)
GLOB.space_manager.remove_dirt(placement.z)
var/datum/milla_safe_must_sleep/late_setup_level/milla = new()
milla.invoke_async(bot_left, top_right, block(ST_bot_left, ST_top_right))
var/datum/milla_safe/late_setup_level/milla = new()
milla.invoke_async(block(bot_left, top_right), block(ST_bot_left, ST_top_right))
message_admins("Map template [name] threw an error while loading. Safe exit attempted, but check for errors at [ADMIN_COORDJMP(placement)].")
log_admin("Map template [name] threw an error while loading. Safe exit attempted.")
throw e
GLOB.space_manager.remove_dirt(placement.z)
var/datum/milla_safe_must_sleep/late_setup_level/milla = new()
milla.invoke_async(bot_left, top_right, block(ST_bot_left, ST_top_right))
var/datum/milla_safe/late_setup_level/milla = new()
milla.invoke_async(block(bot_left, top_right), block(ST_bot_left, ST_top_right))

log_game("[name] loaded at [min_x],[min_y],[placement.z]")
return 1
Expand Down
24 changes: 9 additions & 15 deletions code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@
/// The effect used to render a pressure overlay from this tile.
var/obj/effect/pressure_overlay/pressure_overlay

var/list/milla_atmos_airtight = list(FALSE, FALSE, FALSE, FALSE)
var/list/milla_superconductivity = list(
OPEN_HEAT_TRANSFER_COEFFICIENT,
OPEN_HEAT_TRANSFER_COEFFICIENT,
OPEN_HEAT_TRANSFER_COEFFICIENT,
OPEN_HEAT_TRANSFER_COEFFICIENT)
var/list/milla_data = list()

new_attack_chain = TRUE

/turf/Initialize(mapload)
Expand Down Expand Up @@ -484,29 +476,31 @@
if(SSticker)
GLOB.cameranet.updateVisibility(src)

/turf/attack_by(obj/item/attacking, mob/user, params)
/turf/attack_by(obj/item/I, mob/user, params)
if(..())
return TRUE

if(can_lay_cable())
if(istype(attacking, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = attacking
if(istype(I, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = I
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby__legacy__attackchain(C, user)
return TRUE
return
C.place_turf(src, user)
return TRUE
else if(istype(attacking, /obj/item/rcl))
var/obj/item/rcl/R = attacking
else if(istype(I, /obj/item/rcl))
var/obj/item/rcl/R = I
if(R.loaded)
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby__legacy__attackchain(R, user)
return TRUE
return
R.loaded.place_turf(src, user)
R.is_empty(user)

return FALSE

/turf/proc/can_have_cabling()
return TRUE

Expand Down
Loading
Loading