diff --git a/runtime/include/sandbox_set_as_allocated.h b/runtime/include/sandbox_set_as_allocated.h index 3bbfc7b..ae69734 100644 --- a/runtime/include/sandbox_set_as_allocated.h +++ b/runtime/include/sandbox_set_as_allocated.h @@ -8,6 +8,7 @@ #include "current_sandbox.h" #include "ps_list.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" /** @@ -28,4 +29,8 @@ sandbox_set_as_allocated(struct sandbox *sandbox) sandbox_state_history_init(&sandbox->state_history); sandbox_state_history_append(&sandbox->state_history, SANDBOX_ALLOCATED); sandbox_state_totals_increment(SANDBOX_ALLOCATED); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, SANDBOX_UNINITIALIZED); + sandbox_state_transition_to_hook(sandbox, SANDBOX_ALLOCATED); } diff --git a/runtime/include/sandbox_set_as_asleep.h b/runtime/include/sandbox_set_as_asleep.h index 2c0bc04..f96bd2a 100644 --- a/runtime/include/sandbox_set_as_asleep.h +++ b/runtime/include/sandbox_set_as_asleep.h @@ -8,6 +8,7 @@ #include "sandbox_types.h" #include "sandbox_state.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" /** * Transitions a sandbox to the SANDBOX_ASLEEP state. @@ -37,11 +38,16 @@ sandbox_set_as_asleep(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_ASLEEP); sandbox_state_totals_increment(SANDBOX_ASLEEP); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_ASLEEP); } static inline void diff --git a/runtime/include/sandbox_set_as_complete.h b/runtime/include/sandbox_set_as_complete.h index 5e19c56..1a300dc 100644 --- a/runtime/include/sandbox_set_as_complete.h +++ b/runtime/include/sandbox_set_as_complete.h @@ -10,6 +10,7 @@ #include "sandbox_perf_log.h" #include "sandbox_state.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_summarize_page_allocations.h" #include "sandbox_types.h" @@ -40,7 +41,8 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_COMPLETE); sandbox_state_totals_increment(SANDBOX_COMPLETE); @@ -55,6 +57,10 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state) sandbox_perf_log_print_entry(sandbox); sandbox_summarize_page_allocations(sandbox); + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_COMPLETE); + /* Does not add to completion queue until in cooperative scheduler */ } diff --git a/runtime/include/sandbox_set_as_error.h b/runtime/include/sandbox_set_as_error.h index aa5b628..0b83827 100644 --- a/runtime/include/sandbox_set_as_error.h +++ b/runtime/include/sandbox_set_as_error.h @@ -10,6 +10,7 @@ #include "sandbox_functions.h" #include "sandbox_perf_log.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_summarize_page_allocations.h" #include "panic.h" @@ -47,8 +48,9 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change; - sandbox->duration_of_state[last_state] += duration_of_last_state; + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; + sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_ERROR); sandbox_state_totals_increment(SANDBOX_ERROR); sandbox_state_totals_decrement(last_state); @@ -60,6 +62,10 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state) sandbox_perf_log_print_entry(sandbox); sandbox_summarize_page_allocations(sandbox); + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_ERROR); + /* Does not add to completion queue until in cooperative scheduler */ } diff --git a/runtime/include/sandbox_set_as_initialized.h b/runtime/include/sandbox_set_as_initialized.h index dd369e9..131df07 100644 --- a/runtime/include/sandbox_set_as_initialized.h +++ b/runtime/include/sandbox_set_as_initialized.h @@ -8,6 +8,7 @@ #include "current_sandbox.h" #include "ps_list.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" /** @@ -35,9 +36,14 @@ sandbox_set_as_initialized(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_INITIALIZED); sandbox_state_totals_increment(SANDBOX_INITIALIZED); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_INITIALIZED); } diff --git a/runtime/include/sandbox_set_as_interrupted.h b/runtime/include/sandbox_set_as_interrupted.h index 98a651a..b9ca48a 100644 --- a/runtime/include/sandbox_set_as_interrupted.h +++ b/runtime/include/sandbox_set_as_interrupted.h @@ -8,6 +8,7 @@ #include "panic.h" #include "sandbox_functions.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" static inline void @@ -23,11 +24,16 @@ sandbox_set_as_interrupted(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; /* We do not append SANDBOX_INTERRUPTED to the sandbox_state_history because it would quickly fill the buffer */ sandbox_state_totals_increment(SANDBOX_INTERRUPTED); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_INTERRUPTED); } static inline void diff --git a/runtime/include/sandbox_set_as_preempted.h b/runtime/include/sandbox_set_as_preempted.h index 5287b84..3d30c93 100644 --- a/runtime/include/sandbox_set_as_preempted.h +++ b/runtime/include/sandbox_set_as_preempted.h @@ -7,6 +7,7 @@ #include "local_runqueue.h" #include "panic.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" /** @@ -37,11 +38,16 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_PREEMPTED); sandbox_state_totals_increment(SANDBOX_PREEMPTED); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_PREEMPTED); } static inline void diff --git a/runtime/include/sandbox_set_as_returned.h b/runtime/include/sandbox_set_as_returned.h index ae986e2..f67dea2 100644 --- a/runtime/include/sandbox_set_as_returned.h +++ b/runtime/include/sandbox_set_as_returned.h @@ -9,6 +9,7 @@ #include "sandbox_functions.h" #include "sandbox_state.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" /** @@ -44,9 +45,14 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_RETURNED); sandbox_state_totals_increment(SANDBOX_RETURNED); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_RETURNED); } diff --git a/runtime/include/sandbox_set_as_runnable.h b/runtime/include/sandbox_set_as_runnable.h index 91820dc..8e28875 100644 --- a/runtime/include/sandbox_set_as_runnable.h +++ b/runtime/include/sandbox_set_as_runnable.h @@ -7,6 +7,7 @@ #include "local_runqueue.h" #include "panic.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" /** @@ -44,11 +45,16 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNABLE); sandbox_state_totals_increment(SANDBOX_RUNNABLE); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_RUNNABLE); } diff --git a/runtime/include/sandbox_set_as_running_sys.h b/runtime/include/sandbox_set_as_running_sys.h index 9c44e34..b9ee4aa 100644 --- a/runtime/include/sandbox_set_as_running_sys.h +++ b/runtime/include/sandbox_set_as_running_sys.h @@ -8,6 +8,7 @@ #include "panic.h" #include "sandbox_functions.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" static inline void @@ -39,11 +40,15 @@ sandbox_set_as_running_sys(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); - sandbox->timestamp_of.last_state_change = now; + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNING_SYS); sandbox_state_totals_increment(SANDBOX_RUNNING_SYS); sandbox_state_totals_decrement(last_state); + + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_RUNNING_SYS); } static inline void diff --git a/runtime/include/sandbox_set_as_running_user.h b/runtime/include/sandbox_set_as_running_user.h index 0d50ed2..8559ec7 100644 --- a/runtime/include/sandbox_set_as_running_user.h +++ b/runtime/include/sandbox_set_as_running_user.h @@ -7,6 +7,7 @@ #include "current_sandbox.h" #include "panic.h" #include "sandbox_state_history.h" +#include "sandbox_state_transition.h" #include "sandbox_types.h" #include "sandbox_functions.h" @@ -35,12 +36,17 @@ sandbox_set_as_running_user(struct sandbox *sandbox, sandbox_state_t last_state) /* State Change Bookkeeping */ assert(now > sandbox->timestamp_of.last_state_change); - sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change); + sandbox->last_state_duration = now - sandbox->timestamp_of.last_state_change; + sandbox->duration_of_state[last_state] += sandbox->last_state_duration; sandbox->timestamp_of.last_state_change = now; sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNING_USER); sandbox_state_totals_increment(SANDBOX_RUNNING_USER); sandbox_state_totals_decrement(last_state); + /* State Change Hooks */ + sandbox_state_transition_from_hook(sandbox, last_state); + sandbox_state_transition_to_hook(sandbox, SANDBOX_RUNNING_USER); + barrier(); sandbox->state = SANDBOX_RUNNING_USER; /* WARNING: All code after this assignment is preemptable */ diff --git a/runtime/include/sandbox_state_transition.h b/runtime/include/sandbox_state_transition.h new file mode 100644 index 0000000..71271fd --- /dev/null +++ b/runtime/include/sandbox_state_transition.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include "sandbox_state.h" +#include "sandbox_types.h" + + +typedef void (*sandbox_state_transition_hook_t)(struct sandbox *); +extern sandbox_state_transition_hook_t sandbox_state_transition_from_hooks[SANDBOX_STATE_COUNT]; +extern sandbox_state_transition_hook_t sandbox_state_transition_to_hooks[SANDBOX_STATE_COUNT]; + +static inline void +sandbox_state_transition_from_hook(struct sandbox *sandbox, sandbox_state_t state) +{ + assert(sandbox != NULL); + assert(state < SANDBOX_STATE_COUNT); + + sandbox_state_transition_from_hooks[state](sandbox); +} + +static inline void +sandbox_state_transition_to_hook(struct sandbox *sandbox, sandbox_state_t state) +{ + assert(sandbox != NULL); + assert(state < SANDBOX_STATE_COUNT); + + sandbox_state_transition_to_hooks[state](sandbox); +} + +static inline void +sandbox_state_transition_from_hook_register(sandbox_state_t state, sandbox_state_transition_hook_t cb) +{ + assert(state < SANDBOX_STATE_COUNT); + assert(cb != NULL); + + sandbox_state_transition_from_hooks[state] = cb; +} + +static inline void +sandbox_state_transition_to_hook_register(sandbox_state_t state, sandbox_state_transition_hook_t cb) +{ + assert(state < SANDBOX_STATE_COUNT); + assert(cb != NULL); + + sandbox_state_transition_to_hooks[state] = cb; +} diff --git a/runtime/include/sandbox_types.h b/runtime/include/sandbox_types.h index 4c97b66..c79d65e 100644 --- a/runtime/include/sandbox_types.h +++ b/runtime/include/sandbox_types.h @@ -66,6 +66,7 @@ struct sandbox { /* Scheduling and Temporal State */ struct sandbox_timestamps timestamp_of; uint64_t duration_of_state[SANDBOX_STATE_COUNT]; + uint64_t last_state_duration; uint64_t absolute_deadline; uint64_t admissions_estimate; /* estimated execution time (cycles) * runtime_admissions_granularity / relative diff --git a/runtime/src/sandbox_state_transition.c b/runtime/src/sandbox_state_transition.c new file mode 100644 index 0000000..8664409 --- /dev/null +++ b/runtime/src/sandbox_state_transition.c @@ -0,0 +1,41 @@ +#include "sandbox_state_transition.h" + +void +sandbox_state_transition_hook_default(struct sandbox *sandbox) +{ + return; +} + +/* Called while nonpreemptable */ +sandbox_state_transition_hook_t sandbox_state_transition_to_hooks[SANDBOX_STATE_COUNT] = { + + [SANDBOX_UNINITIALIZED] = sandbox_state_transition_hook_default, + [SANDBOX_ALLOCATED] = sandbox_state_transition_hook_default, + [SANDBOX_INITIALIZED] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNABLE] = sandbox_state_transition_hook_default, + [SANDBOX_INTERRUPTED] = sandbox_state_transition_hook_default, + [SANDBOX_PREEMPTED] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNING_SYS] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNING_USER] = sandbox_state_transition_hook_default, + [SANDBOX_ASLEEP] = sandbox_state_transition_hook_default, + [SANDBOX_RETURNED] = sandbox_state_transition_hook_default, + [SANDBOX_COMPLETE] = sandbox_state_transition_hook_default, + [SANDBOX_ERROR] = sandbox_state_transition_hook_default +}; + +/* Called while nonpreemptable */ +sandbox_state_transition_hook_t sandbox_state_transition_from_hooks[SANDBOX_STATE_COUNT] = { + + [SANDBOX_UNINITIALIZED] = sandbox_state_transition_hook_default, + [SANDBOX_ALLOCATED] = sandbox_state_transition_hook_default, + [SANDBOX_INITIALIZED] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNABLE] = sandbox_state_transition_hook_default, + [SANDBOX_INTERRUPTED] = sandbox_state_transition_hook_default, + [SANDBOX_PREEMPTED] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNING_SYS] = sandbox_state_transition_hook_default, + [SANDBOX_RUNNING_USER] = sandbox_state_transition_hook_default, + [SANDBOX_ASLEEP] = sandbox_state_transition_hook_default, + [SANDBOX_RETURNED] = sandbox_state_transition_hook_default, + [SANDBOX_COMPLETE] = sandbox_state_transition_hook_default, + [SANDBOX_ERROR] = sandbox_state_transition_hook_default +};