diff --git a/btime.dll b/btime.dll deleted file mode 100644 index af6c82a998..0000000000 Binary files a/btime.dll and /dev/null differ diff --git a/btime.so b/btime.so deleted file mode 100644 index edb3cc3113..0000000000 Binary files a/btime.so and /dev/null differ diff --git a/code/__defines/btime.dm b/code/__defines/btime.dm deleted file mode 100644 index d4cefc3524..0000000000 --- a/code/__defines/btime.dm +++ /dev/null @@ -1,18 +0,0 @@ -// Comment this out if the external btime library is unavailable -#define PRECISE_TIMER_AVAILABLE - -#ifdef PRECISE_TIMER_AVAILABLE -var/global/__btime__libName = "btime.[world.system_type==MS_WINDOWS?"dll":"so"]" -#define TimeOfHour (__extern__timeofhour) -#define __extern__timeofhour text2num(call(__btime__libName, "gettime")()) -/hook/startup/proc/checkbtime() - try - // This will always return 1 unless the btime library cannot be accessed - if(TimeOfHour || 1) return 1 - catch(var/exception/e) - log_to_dd("PRECISE_TIMER_AVAILABLE is defined in btime.dm, but calling the btime library failed: [e]") - log_to_dd("This is a fatal error. The world will now shut down.") - del(world) -#else -#define TimeOfHour (world.timeofday % 36000) -#endif \ No newline at end of file diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm index 198f87eccc..da1c2aebd1 100644 --- a/code/__defines/math_physics.dm +++ b/code/__defines/math_physics.dm @@ -26,4 +26,7 @@ #define INFINITY 1.#INF #define TICKS_IN_DAY 24*60*60*10 -#define TICKS_IN_SECOND 10 \ No newline at end of file +#define TICKS_IN_SECOND 10 + +#define SIMPLE_SIGN(X) ((X) < 0 ? -1 : 1) +#define SIGN(X) ((X) ? SIMPLE_SIGN(X) : 0) diff --git a/code/__defines/process_scheduler.dm b/code/__defines/process_scheduler.dm index 76449b9a4b..d9c8f106ef 100644 --- a/code/__defines/process_scheduler.dm +++ b/code/__defines/process_scheduler.dm @@ -11,10 +11,9 @@ #define PROCESS_DEFAULT_HANG_ALERT_TIME 600 // 60 seconds #define PROCESS_DEFAULT_HANG_RESTART_TIME 900 // 90 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_SLEEP_INTERVAL 8 // 1/8th of a tick // SCHECK macros // This references src directly to work around a weird bug with try/catch #define SCHECK_EVERY(this_many_calls) if(++src.calls_since_last_scheck >= this_many_calls) sleepCheck() -#define SCHECK SCHECK_EVERY(50) \ No newline at end of file +#define SCHECK sleepCheck() diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index 19e2206cd0..75842ca30f 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -4,16 +4,55 @@ #define MINUTE *600 #define MINUTES *600 +#define HOUR *36000 +#define HOURS *36000 + +#define DAY *864000 +#define DAYS *864000 + +#define TimeOfGame (get_game_time()) +#define TimeOfTick (world.tick_usage*0.01*world.tick_lag) + +/proc/get_game_time() + var/global/time_offset = 0 + var/global/last_time = 0 + var/global/last_usage = 0 + + var/wtime = world.time + var/wusage = world.tick_usage * 0.01 + + if(last_time < wtime && last_usage > 1) + time_offset += last_usage - 1 + + last_time = wtime + last_usage = wusage + + return wtime + (time_offset + wusage) * world.tick_lag + var/roundstart_hour = 0 -//Returns the world time in english -proc/worldtime2text(time = world.time, timeshift = 1) +var/station_date = "" +var/next_station_date_change = 1 DAY + +#define station_adjusted_time(time) time2text(time + station_time_in_ticks, "hh:mm") +#define round_duration_in_ticks (round_start_time ? world.time - round_start_time : 0) +#define station_time_in_ticks (roundstart_hour HOURS + round_duration_in_ticks) + +/proc/stationtime2text() if(!roundstart_hour) roundstart_hour = pick(2,7,12,17) - return timeshift ? time2text(time+(36000*roundstart_hour), "hh:mm") : time2text(time, "hh:mm") + return time2text(station_time_in_ticks, "hh:mm") -proc/worlddate2text() - return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD") +/proc/stationdate2text() + var/update_time = FALSE + if(station_time_in_ticks > next_station_date_change) + next_station_date_change += 1 DAY + update_time = TRUE + if(!station_date || update_time) + var/extra_days = round(station_time_in_ticks / (1 DAY)) DAYS + var/timeofday = world.timeofday + extra_days + station_date = num2text((text2num(time2text(timeofday, "YYYY"))+544)) + "-" + time2text(timeofday, "MM-DD") + return station_date -proc/time_stamp() +/proc/time_stamp() return time2text(world.timeofday, "hh:mm:ss") /* Returns 1 if it is the selected month and day */ @@ -36,9 +75,7 @@ var/round_start_time = 0 round_start_time = world.time return 1 -#define round_duration_in_ticks (round_start_time ? world.time - round_start_time : 0) - -/proc/round_duration_as_text() +/proc/roundduration2text() if(!round_start_time) return "00:00" if(last_round_duration && world.time < next_duration_update) @@ -55,3 +92,8 @@ var/round_start_time = 0 last_round_duration = "[hours]:[mins]" next_duration_update = world.time + 1 MINUTES return last_round_duration + +//Can be useful for things dependent on process timing +/proc/process_schedule_interval(var/process_name) + var/datum/controller/process/process = processScheduler.getProcess(process_name) + return process.schedule_interval \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/_stubs.dm b/code/controllers/ProcessScheduler/core/_stubs.dm deleted file mode 100644 index 1aa2c8efb8..0000000000 --- a/code/controllers/ProcessScheduler/core/_stubs.dm +++ /dev/null @@ -1,19 +0,0 @@ -/** - * _stubs.dm - * - * This file contains constructs that the process scheduler expects to exist - * in a standard ss13 fork. - */ - -/** - * 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) - log_debug("Diary: \[[diaryType]:[type]] [text]") - else - log_debug("Log: \[[type]] [text]") diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index b7767c367f..836d2124bd 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -69,10 +69,10 @@ * recordkeeping vars */ - // Records the time (1/10s timeofday) at which the process last finished sleeping + // Records the time (1/10s timeoftick) at which the process last finished sleeping var/tmp/last_slept = 0 - // Records the time (1/10s timeofday) at which the process last began running + // Records the time (1/10s timeofgame) at which the process last began running var/tmp/run_start = 0 // Records the number of times this process has been killed and restarted @@ -106,12 +106,8 @@ last_object = null /datum/controller/process/proc/started() - var/timeofhour = TimeOfHour - // Initialize last_slept so we can know when to sleep - last_slept = timeofhour - // Initialize run_start so we can detect hung processes. - run_start = timeofhour + run_start = TimeOfGame // Initialize defer count cpu_defer_count = 0 @@ -163,18 +159,13 @@ setStatus(PROCESS_STATUS_HUNG) /datum/controller/process/proc/handleHung() - var/timeofhour = TimeOfHour var/datum/lastObj = last_object var/lastObjType = "null" if(istype(lastObj)) lastObjType = lastObj.type - // If timeofhour 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") + var/msg = "[name] process hung at tick #[ticks]. Process was unresponsive for [(TimeOfGame - run_start) / 10] seconds and was restarted. Last task: [last_task]. Last Object Type: [lastObjType]" + log_debug(msg) message_admins(msg) main.restartProcess(src.name) @@ -182,8 +173,8 @@ /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 @@ -208,17 +199,12 @@ if (main.getCurrentTickElapsedTime() > main.timeAllowance) sleep(world.tick_lag) cpu_defer_count++ - last_slept = TimeOfHour + last_slept = 0 else - var/timeofhour = TimeOfHour - // If timeofhour has rolled over, then we need to adjust. - if (timeofhour < last_slept) - last_slept -= 36000 - - if (timeofhour > last_slept + sleep_interval) + if (TimeOfTick > 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 + last_slept = TimeOfTick /datum/controller/process/proc/update() // Clear delta @@ -239,10 +225,7 @@ /datum/controller/process/proc/getElapsedTime() - var/timeofhour = TimeOfHour - if (timeofhour < run_start) - return timeofhour - (run_start - 36000) - return timeofhour - run_start + return TimeOfGame - run_start /datum/controller/process/proc/tickDetail() return @@ -343,6 +326,11 @@ stat("[name]", "T#[getTicks()] | AR [averageRunTime] | LR [lastRunTime] | HR [highestRunTime] | D [cpu_defer_count]") /datum/controller/process/proc/catchException(var/exception/e, var/thrower) + if(istype(e)) // Real runtimes go to the real error handler + // There are two newlines here, because handling desc sucks + e.desc = " Caught by process: [name]\n\n" + e.desc + world.Error(e, e_src = thrower) + return var/etext = "[e]" var/eid = "[e]" // Exception ID, for tracking repeated exceptions var/ptext = "" // "processing..." text, for what was being processed (if known) @@ -369,4 +357,4 @@ /datum/controller/process/proc/catchBadType(var/datum/caught) if(isnull(caught) || !istype(caught) || !isnull(caught.gcDestroyed)) return // Only bother with types we can identify and that don't belong - catchException("Type [caught.type] does not belong in process' queue") \ No newline at end of file + catchException("Type [caught.type] does not belong in process' queue") diff --git a/code/controllers/ProcessScheduler/core/processScheduler.dm b/code/controllers/ProcessScheduler/core/processScheduler.dm index bde79fba07..dc412ee92a 100644 --- a/code/controllers/ProcessScheduler/core/processScheduler.dm +++ b/code/controllers/ProcessScheduler/core/processScheduler.dm @@ -43,8 +43,6 @@ var/global/datum/controller/processScheduler/processScheduler var/tmp/currentTick = 0 - var/tmp/currentTickStart = 0 - var/tmp/timeAllowance = 0 var/tmp/cpuAverage = 0 @@ -247,7 +245,7 @@ var/global/datum/controller/processScheduler/processScheduler /datum/controller/processScheduler/proc/recordStart(var/datum/controller/process/process, var/time = null) if (isnull(time)) - time = TimeOfHour + time = TimeOfGame last_queued[process] = world.time last_start[process] = time else @@ -256,11 +254,7 @@ var/global/datum/controller/processScheduler/processScheduler /datum/controller/processScheduler/proc/recordEnd(var/datum/controller/process/process, var/time = null) if (isnull(time)) - time = TimeOfHour - - // If world.timeofday has rolled over, then we need to adjust. - if (time < last_start[process]) - last_start[process] -= 36000 + time = TimeOfGame var/lastRunTime = time - last_start[process] @@ -349,29 +343,23 @@ var/global/datum/controller/processScheduler/processScheduler updateCurrentTickData() return 0 else - return TimeOfHour - currentTickStart + return TimeOfTick /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.001 * abs(error)) + var/tmp/timeAllowanceDelta = SIMPLE_SIGN(error) * -0.5 * world.tick_lag * max(0, 0.001 * 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) - /datum/controller/processScheduler/proc/statProcesses() if(!isRunning) stat("Processes", "Scheduler not running") @@ -379,4 +367,7 @@ var/global/datum/controller/processScheduler/processScheduler stat("Processes", "[processes.len] (R [running.len] / Q [queued.len] / I [idle.len])") stat(null, "[round(cpuAverage, 0.1)] CPU, [round(timeAllowance, 0.1)/10] TA") for(var/datum/controller/process/p in processes) - p.statProcess() \ No newline at end of file + p.statProcess() + +/datum/controller/processScheduler/proc/getProcess(var/process_name) + return nameToProcessMap[process_name] diff --git a/code/controllers/ProcessScheduler/test/processScheduler.js b/code/controllers/ProcessScheduler/test/processScheduler.js deleted file mode 100644 index 0a4f111355..0000000000 --- a/code/controllers/ProcessScheduler/test/processScheduler.js +++ /dev/null @@ -1,56 +0,0 @@ -(function ($) { - function setRef(theRef) { - ref = theRef; - } - - function jax(action, data) { - if (typeof data === 'undefined') - data = {}; - var params = []; - for (var k in data) { - if (data.hasOwnProperty(k)) { - params.push(encodeURIComponent(k) + '=' + encodeURIComponent(data[k])); - } - } - var newLoc = '?src=' + ref + ';action=' + action + ';' + params.join(';'); - window.location = newLoc; - } - - function requestRefresh(e) { - jax("refresh", null); - } - - function handleRefresh(processTable) { - $('#processTable').html(processTable); - initProcessTableButtons(); - } - - function requestKill(e) { - var button = $(e.currentTarget); - jax("kill", {name: button.data("process-name")}); - } - - function requestEnable(e) { - var button = $(e.currentTarget); - jax("enable", {name: button.data("process-name")}); - } - - function requestDisable(e) { - var button = $(e.currentTarget); - jax("disable", {name: button.data("process-name")}); - } - - function initProcessTableButtons() { - $(".kill-btn").on("click", requestKill); - $(".enable-btn").on("click", requestEnable); - $(".disable-btn").on("click", requestDisable); - } - - window.setRef = setRef; - window.handleRefresh = handleRefresh; - - $(function() { - initProcessTableButtons(); - $('#btn-refresh').on("click", requestRefresh); - }); -}(jQuery)); \ No newline at end of file diff --git a/polaris.dme b/polaris.dme index 4c0a8079c6..e45ca4c92e 100644 --- a/polaris.dme +++ b/polaris.dme @@ -21,7 +21,6 @@ #include "code\__defines\admin.dm" #include "code\__defines\appearance.dm" #include "code\__defines\atmos.dm" -#include "code\__defines\btime.dm" #include "code\__defines\chemistry.dm" #include "code\__defines\damage_organs.dm" #include "code\__defines\dna.dm" @@ -152,7 +151,6 @@ #include "code\controllers\Processes\ticker.dm" #include "code\controllers\Processes\turf.dm" #include "code\controllers\Processes\vote.dm" -#include "code\controllers\ProcessScheduler\core\_stubs.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" #include "code\datums\ai_law_sets.dm"