commit
79ca1f04ae
@ -1 +1,3 @@
|
||||
This is a state transition diagram of a sandbox. This maps to the state transition functions defined in `runtime/include/sandbox_set_as_*.h`
|
||||
|
||||
Technically, this does not capture all state transitions to or from SANDBOX_INTERRUPTED, as any state can be interrupted by a SIGALRM and this would clutter the diagram. The only transitions shown to or from SANDBOX_INTERRUPTED are those leading to SANDBOX_PREEMPTED, as this reflects actual changes to a sandbox within the scheduler. All other transitions to/from SANDBOX_INTERRUPTED are mostly concerned with preventing scheduler execution time from being counted against sandbox execution times.
|
||||
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 9.2 KiB |
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define PRETTY_PRINT_COLOR_CODE_RED "\033[1;31m"
|
||||
#define PRETTY_COLOR_CODE_GREEN "\033[0;32m"
|
||||
#define PRETTY_PRINT_COLOR_CODE_RESET "\033[0m"
|
||||
#define PRETTY_PRINT_GREEN_ENABLED PRETTY_COLOR_CODE_GREEN "Enabled" PRETTY_PRINT_COLOR_CODE_RESET
|
||||
#define PRETTY_PRINT_RED_DISABLED PRETTY_PRINT_COLOR_CODE_RED "Disabled" PRETTY_PRINT_COLOR_CODE_RESET
|
||||
#define PRETTY_PRINT_KEY_LEN 30
|
||||
|
||||
|
||||
static inline void
|
||||
pretty_print_key(char *heading)
|
||||
{
|
||||
printf("\t%-*s", PRETTY_PRINT_KEY_LEN, heading);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pretty_print_key_value(char *key, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
pretty_print_key(key);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pretty_print_key_enabled(char *key)
|
||||
{
|
||||
pretty_print_key_value(key, "%s\n", PRETTY_PRINT_GREEN_ENABLED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pretty_print_key_disabled(char *key)
|
||||
{
|
||||
pretty_print_key_value(key, "%s\n", PRETTY_PRINT_RED_DISABLED);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "arch/getcycles.h"
|
||||
#include "current_sandbox.h"
|
||||
#include "panic.h"
|
||||
#include "sandbox_functions.h"
|
||||
#include "sandbox_state_history.h"
|
||||
#include "sandbox_types.h"
|
||||
|
||||
static inline void
|
||||
sandbox_set_as_interrupted(struct sandbox *sandbox, sandbox_state_t last_state)
|
||||
{
|
||||
assert(sandbox);
|
||||
|
||||
/* WARNING: All code before this assignment is preemptable */
|
||||
sandbox->state = SANDBOX_INTERRUPTED;
|
||||
barrier();
|
||||
|
||||
uint64_t now = __getcycles();
|
||||
|
||||
/* State Change Bookkeeping */
|
||||
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
|
||||
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 */
|
||||
runtime_sandbox_total_increment(SANDBOX_INTERRUPTED);
|
||||
runtime_sandbox_total_decrement(last_state);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sandbox_interrupt(struct sandbox *sandbox)
|
||||
{
|
||||
sandbox_set_as_interrupted(sandbox, sandbox->state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Transition sandbox back to interrupted state
|
||||
* @param sandbox
|
||||
* @param interrupted_state - state to return to
|
||||
*/
|
||||
static inline void
|
||||
sandbox_interrupt_return(struct sandbox *sandbox, sandbox_state_t interrupted_state)
|
||||
{
|
||||
assert(sandbox);
|
||||
assert(interrupted_state != SANDBOX_INTERRUPTED);
|
||||
|
||||
uint64_t now = __getcycles();
|
||||
|
||||
/* State Change Bookkeeping */
|
||||
sandbox->duration_of_state[SANDBOX_INTERRUPTED] += (now - sandbox->timestamp_of.last_state_change);
|
||||
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 */
|
||||
runtime_sandbox_total_increment(interrupted_state);
|
||||
runtime_sandbox_total_decrement(SANDBOX_INTERRUPTED);
|
||||
|
||||
barrier();
|
||||
/* WARNING: Code after this assignment may be preemptable */
|
||||
sandbox->state = interrupted_state;
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "worker_thread.h"
|
||||
|
||||
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm_max;
|
||||
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm_replay;
|
||||
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_kernel;
|
||||
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_thread;
|
||||
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigusr;
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_alloc()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
software_interrupt_counts_deferred_sigalrm_max = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
|
||||
software_interrupt_counts_deferred_sigalrm_replay = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
|
||||
software_interrupt_counts_sigalrm_kernel = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
|
||||
software_interrupt_counts_sigalrm_thread = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
|
||||
software_interrupt_counts_sigusr = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_free()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
free((void *)software_interrupt_counts_deferred_sigalrm_max);
|
||||
free((void *)software_interrupt_counts_sigalrm_kernel);
|
||||
free((void *)software_interrupt_counts_sigalrm_thread);
|
||||
free((void *)software_interrupt_counts_sigusr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_deferred_sigalrm_max_update(int deferred_sigalrm_count)
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
if (unlikely(deferred_sigalrm_count > software_interrupt_counts_deferred_sigalrm_max[worker_thread_idx])) {
|
||||
software_interrupt_counts_deferred_sigalrm_max[worker_thread_idx] = deferred_sigalrm_count;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_deferred_sigalrm_replay_increment()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
atomic_fetch_add(&software_interrupt_counts_deferred_sigalrm_replay[worker_thread_idx], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_sigalrm_kernel_increment()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
atomic_fetch_add(&software_interrupt_counts_sigalrm_kernel[worker_thread_idx], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_sigalrm_thread_increment()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
atomic_fetch_add(&software_interrupt_counts_sigalrm_thread[worker_thread_idx], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
software_interrupt_counts_sigusr_increment()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
atomic_fetch_add(&software_interrupt_counts_sigusr[worker_thread_idx], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void software_interrupt_counts_log();
|
@ -0,0 +1,26 @@
|
||||
#include "software_interrupt_counts.h"
|
||||
#include "pretty_print.h"
|
||||
|
||||
_Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm_max;
|
||||
_Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm_replay;
|
||||
_Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_kernel;
|
||||
_Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_thread;
|
||||
_Atomic volatile sig_atomic_t *software_interrupt_counts_sigusr;
|
||||
|
||||
void
|
||||
software_interrupt_counts_log()
|
||||
{
|
||||
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
|
||||
for (int i = 0; i < runtime_worker_threads_count; i++) {
|
||||
printf("Worker %d:\n", i);
|
||||
pretty_print_key_value("Deferred Sigalrm Max", "%12d\n",
|
||||
software_interrupt_counts_deferred_sigalrm_max[i]);
|
||||
pretty_print_key_value("Deferred Sigalrm Replay", "%12d\n",
|
||||
software_interrupt_counts_deferred_sigalrm_replay[i]);
|
||||
pretty_print_key_value("Siglarm Kernel Count", "%12d\n", software_interrupt_counts_sigalrm_kernel[i]);
|
||||
pretty_print_key_value("Siglarm Thread Count", "%12d\n", software_interrupt_counts_sigalrm_thread[i]);
|
||||
pretty_print_key_value("Sigusr Count", "%12d\n", software_interrupt_counts_sigusr[i]);
|
||||
}
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
Loading…
Reference in new issue