apply traiged sending sig alarm to other worker thread for SRSF

main
lyuxiaosu 3 years ago
parent f78f5077a5
commit 9b97152632

@ -43,6 +43,7 @@ extern pthread_t runtime_worker_threads[];
extern uint32_t runtime_worker_threads_count;
extern int runtime_worker_threads_argument[RUNTIME_WORKER_THREAD_CORE_COUNT];
extern uint64_t runtime_worker_threads_deadline[RUNTIME_WORKER_THREAD_CORE_COUNT];
extern uint64_t runtime_worker_threads_remaining_slack[RUNTIME_WORKER_THREAD_CORE_COUNT];
extern void runtime_initialize(void);
extern void runtime_set_pthread_prio(pthread_t thread, unsigned int nice);

@ -29,6 +29,7 @@ sandbox_set_as_running(struct sandbox *sandbox, sandbox_state_t last_state)
sandbox->runnable_duration += duration_of_last_state;
current_sandbox_set(sandbox);
runtime_worker_threads_deadline[worker_thread_idx] = sandbox->absolute_deadline;
runtime_worker_threads_remaining_slack[worker_thread_idx] = sandbox->remaining_slack;
//mem_log("time %lu sandbox starts running, request id:%d name %s obj=%p remaining slack %lu, last_rs %lu now %lu last %lu \n", start_execution,
// sandbox->id, sandbox->module->name, sandbox, sandbox->remaining_slack, last_rs, now, last);
/* Does not handle context switch because the caller knows if we need to use fast or slow switched */

@ -357,6 +357,7 @@ scheduler_yield()
sandbox_exit(current_sandbox);
current_sandbox_set(NULL);
runtime_worker_threads_deadline[worker_thread_idx] = UINT64_MAX;
runtime_worker_threads_remaining_slack[worker_thread_idx] = UINT64_MAX;
/* Assumption: Base Worker context should never be preempted */
assert(worker_thread_base_context.variant == ARCH_CONTEXT_VARIANT_FAST);

@ -197,7 +197,7 @@ runtime_configure()
if (strcmp(sigalrm_policy, "BROADCAST") == 0) {
runtime_sigalrm_handler = RUNTIME_SIGALRM_HANDLER_BROADCAST;
} else if (strcmp(sigalrm_policy, "TRIAGED") == 0) {
if (unlikely(scheduler != SCHEDULER_EDF)) panic("triaged sigalrm handlers are only valid with EDF\n");
if (unlikely(scheduler != SCHEDULER_EDF && scheduler != SCHEDULER_SRSF)) panic("triaged sigalrm handlers are only valid with EDF and SRSF\n");
runtime_sigalrm_handler = RUNTIME_SIGALRM_HANDLER_TRIAGED;
} else {
panic("Invalid sigalrm policy: %s. Must be {BROADCAST|TRIAGED}\n", sigalrm_policy);

@ -32,6 +32,7 @@ pthread_t runtime_worker_threads[RUNTIME_WORKER_THREAD_CORE_COUNT];
int runtime_worker_threads_argument[RUNTIME_WORKER_THREAD_CORE_COUNT] = { 0 };
/* The active deadline of the sandbox running on each worker thread */
uint64_t runtime_worker_threads_deadline[RUNTIME_WORKER_THREAD_CORE_COUNT] = { UINT64_MAX };
uint64_t runtime_worker_threads_remaining_slack[RUNTIME_WORKER_THREAD_CORE_COUNT] = { UINT64_MAX };
/******************************************
* Shared Process / Listener Thread Logic *

@ -83,11 +83,18 @@ sigalrm_propagate_workers(siginfo_t *signal_info)
/* If using EDF, conditionally send signals. If not, broadcast */
switch (runtime_sigalrm_handler) {
case RUNTIME_SIGALRM_HANDLER_TRIAGED: {
assert(scheduler == SCHEDULER_EDF);
uint64_t local_deadline = runtime_worker_threads_deadline[i];
uint64_t global_deadline = global_request_scheduler_peek();
if (global_deadline < local_deadline) pthread_kill(runtime_worker_threads[i], SIGALRM);
continue;
//assert(scheduler == SCHEDULER_EDF);
if (scheduler == SCHEDULER_EDF) {
uint64_t local_deadline = runtime_worker_threads_deadline[i];
uint64_t global_deadline = global_request_scheduler_peek();
if (global_deadline < local_deadline) pthread_kill(runtime_worker_threads[i], SIGALRM);
continue;
} else if (scheduler == SCHEDULER_SRSF) {
uint64_t local_remaining_slack = runtime_worker_threads_remaining_slack[i];
uint64_t global_slack = global_request_scheduler_peek();
if (global_slack < local_remaining_slack) pthread_kill(runtime_worker_threads[i], SIGALRM);
continue;
}
}
case RUNTIME_SIGALRM_HANDLER_BROADCAST: {
pthread_kill(runtime_worker_threads[i], SIGALRM);
@ -175,6 +182,9 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
/* record queuelength of the current worker thread */
recording_buffer[software_interrupt_SIGALRM_kernel_count + software_interrupt_SIGALRM_thread_count] = local_workload_count;
sigalrm_propagate_workers(signal_info);
/* if disable preemption, then return directly */
if (!runtime_preemption_enabled) return;
if (current_sandbox == NULL || current_sandbox->ctxt.preemptable == false) {
/* Cannot preempt, so defer signal
* TODO: First worker gets tons of kernel sigalrms, should these be treated the same?
@ -208,7 +218,7 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
software_interrupt_disarm_timer();
/* Only the thread that receives SIGINT from the kernel or user space will broadcast SIGINT to other worker threads */
sigint_propagate_workers_listener(signal_info);
mem_log("thread id %d test buffer:",worker_thread_idx);
mem_log("thread id %d kernal sig %u thread sig %u test buffer:",worker_thread_idx, software_interrupt_SIGALRM_kernel_count, software_interrupt_SIGALRM_thread_count);
for(int i = 0; i < software_interrupt_SIGALRM_kernel_count + software_interrupt_SIGALRM_thread_count; i++) {
mem_log("%d ", recording_buffer[i]);
}
@ -245,6 +255,10 @@ software_interrupt_arm_timer(void)
{
if (!runtime_preemption_enabled) return;
/* if preemption disabled, broadcast sig alarm to all other threads to record the queuelength info */
if (!runtime_preemption_enabled) {
runtime_sigalrm_handler = RUNTIME_SIGALRM_HANDLER_BROADCAST;
}
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));

Loading…
Cancel
Save