Example #1
0
void run_benchmark(void *faulter_fn, void *handler_fn, seL4_CPtr done_ep)
{
    int error = sel4utils_start_thread(&fault_handler, (sel4utils_thread_entry_fn) handler_fn,
                                   (void *) N_HANDLER_ARGS, (void *) handler_argv, true);
    ZF_LOGF_IF(error, "Failed to start handler");

    if (config_set(CONFIG_KERNEL_RT)) {
        /* convert the fault handler to passive */
        ZF_LOGD("Waiting to convert handler to passive");
        seL4_Wait(done_ep, NULL);
        ZF_LOGD("unbound sc\n");
        error = api_sc_unbind(fault_handler.sched_context.cptr);
        ZF_LOGF_IF(error, "Failed to convert to passive");
    }

    error = sel4utils_start_thread(&faulter, (sel4utils_thread_entry_fn) faulter_fn,
                                   (void *) N_FAULTER_ARGS, (void *) faulter_argv, true);
    ZF_LOGF_IF(error, "Failed to start faulter");

    /* benchmark runs */
    benchmark_wait_children(done_ep, "faulter", 1);

    if (config_set(CONFIG_KERNEL_RT)) {
        /* convert the fault handler to active */
        ZF_LOGD("Rebound sc\n");
        error = api_sc_bind(fault_handler.sched_context.cptr, fault_handler.tcb.cptr);
        ZF_LOGF_IF(error, "Failed to convert to active");
    }
    benchmark_wait_children(done_ep, "fault handler", 1);

    error = seL4_TCB_Suspend(faulter.tcb.cptr);
    ZF_LOGF_IF(error, "Failed to suspend faulter");
    error = seL4_TCB_Suspend(fault_handler.tcb.cptr);
    ZF_LOGF_IF(error, "Failed to suspend fault handler");
}
Example #2
0
static int
suspend_test_helper_2a(seL4_CPtr *t1, seL4_CPtr *t2a, seL4_CPtr *t2b)
{
    /* Helper function that runs at a higher priority. */

    /* Start here. */
    CHECK_STEP(suspend_test_step, 0);

    /* Wait for a timer tick to make 2b run. */
    while (suspend_test_step == 1)
        /* spin */{
        ;
    }

    /* Suspend helper 2b. */
    int error = seL4_TCB_Suspend(*t2b);
    test_check(!error);

    CHECK_STEP(suspend_test_step, 2);

    /* Now suspend ourselves, passing control to the low priority process to
     * resume 2b. */
    error = seL4_TCB_Suspend(*t2a);
    test_check(!error);

    return sel4test_get_result();
}
Example #3
0
/*
 * Test that thread suspending works when idling the system.
 * Note: This test non-deterministically fails. If you find only this test
 * try re-running the test suite.
 */
static int
test_thread_suspend(env_t env)
{
    helper_thread_t t1;
    volatile seL4_Word counter;
    ZF_LOGD("test_thread_suspend\n");
    create_helper_thread(env, &t1);

    set_helper_priority(&t1, 100);
    start_helper(env, &t1, (helper_fn_t) counter_func, (seL4_Word) &counter, 0, 0, 0);

    timer_periodic(env->timer->timer, 10 * NS_IN_MS);
    timer_start(env->timer->timer);
    sel4_timer_handle_single_irq(env->timer);

    seL4_Word old_counter;

    /* Let the counter thread run. We might have a pending interrupt, so
     * wait twice. */
    wait_for_timer_interrupt(env);
    wait_for_timer_interrupt(env);

    old_counter = counter;

    /* Let it run again. */
    wait_for_timer_interrupt(env);

    /* Now, counter should have moved. */
    test_check(counter != old_counter);
    old_counter = counter;

    /* Suspend the thread, and wait again. */
    seL4_TCB_Suspend(t1.thread.tcb.cptr);
    wait_for_timer_interrupt(env);

    /* Counter should not have moved. */
    test_check(counter == old_counter);
    old_counter = counter;

    /* Check once more for good measure. */
    wait_for_timer_interrupt(env);

    /* Counter should not have moved. */
    test_check(counter == old_counter);
    old_counter = counter;

    /* Resume the thread and check it does move. */
    seL4_TCB_Resume(t1.thread.tcb.cptr);
    wait_for_timer_interrupt(env);
    test_check(counter != old_counter);

    /* Done. */
    timer_stop(env->timer->timer);
    sel4_timer_handle_single_irq(env->timer);
    cleanup_helper(env, &t1);

    return sel4test_get_result();
}
Example #4
0
static void
sel4_abort(void)
{
    /* Suspend ourselves. This will cap fault if a setup routine has not saved
     * our TCB cap in the TLS region.
     */
    seL4_TCB_Suspend(camkes_get_tls()->tcb_cap);

    /* We expect to never be woken up. */
    while (1); /* Shut the compiler up about noreturn. */
}
Example #5
0
int
vm_stop(vm_t* vm)
{
    return seL4_TCB_Suspend(vm_get_tcb(vm));
}
Example #6
0
int
main(int argc, char **argv)
{
    env_t *env;
    irquser_results_t *results;
    vka_object_t endpoint = {0};

    static size_t object_freq[seL4_ObjectTypeCount] = {
        [seL4_TCBObject] = 2,
        [seL4_EndpointObject] = 1,
#ifdef CONFIG_KERNEL_RT
        [seL4_SchedContextObject] = 2,
        [seL4_ReplyObject] = 2
#endif
    };

    env = benchmark_get_env(argc, argv, sizeof(irquser_results_t), object_freq);
    benchmark_init_timer(env);
    results = (irquser_results_t *) env->results;

    if (vka_alloc_endpoint(&env->slab_vka, &endpoint) != 0) {
        ZF_LOGF("Failed to allocate endpoint\n");
    }

    /* set up globals */
    done_ep = endpoint.cptr;
    timer = &env->timer;
    timer_signal = env->ntfn.cptr;

    int error = ltimer_reset(&env->timer.ltimer);
    ZF_LOGF_IF(error, "Failed to start timer");

    error = ltimer_set_timeout(&env->timer.ltimer, INTERRUPT_PERIOD_NS, TIMEOUT_PERIODIC);
    ZF_LOGF_IF(error, "Failed to configure timer");

    sel4bench_init();

    sel4utils_thread_t ticker, spinner;

    /* measurement overhead */
    ccnt_t start, end;
    for (int i = 0; i < N_RUNS; i++) {
        SEL4BENCH_READ_CCNT(start);
        SEL4BENCH_READ_CCNT(end);
        results->overheads[i] = end - start;
    }

    /* create a frame for the shared time variable so we can share it between processes */
    ccnt_t *local_current_time = (ccnt_t *) vspace_new_pages(&env->vspace, seL4_AllRights, 1, seL4_PageBits);
    if (local_current_time == NULL) {
        ZF_LOGF("Failed to allocate page");
    }

    /* first run the benchmark between two threads in the current address space */
    benchmark_configure_thread(env, endpoint.cptr, seL4_MaxPrio - 1, "ticker", &ticker);
    benchmark_configure_thread(env, endpoint.cptr, seL4_MaxPrio - 2, "spinner", &spinner);

    error = sel4utils_start_thread(&ticker, (sel4utils_thread_entry_fn) ticker_fn, (void *) results->thread_results,
                                   (void *) local_current_time, true);
    if (error) {
        ZF_LOGF("Failed to start ticker");
    }

    char strings[1][WORD_STRING_SIZE];
    char *spinner_argv[1];

    sel4utils_create_word_args(strings, spinner_argv, 1, (seL4_Word) local_current_time);
    error = sel4utils_start_thread(&spinner, (sel4utils_thread_entry_fn) spinner_fn, (void *) 1, (void *) spinner_argv, true);
    assert(!error);

    benchmark_wait_children(endpoint.cptr, "child of irq-user", 1);

    /* stop spinner thread */
    error = seL4_TCB_Suspend(spinner.tcb.cptr);
    assert(error == seL4_NoError);

    error = seL4_TCB_Suspend(ticker.tcb.cptr);
    assert(error == seL4_NoError);

    /* now run the benchmark again, but run the spinner in another address space */

    /* restart ticker */
    error = sel4utils_start_thread(&ticker,  (sel4utils_thread_entry_fn) ticker_fn, (void *) results->process_results,
                                   (void *) local_current_time, true);
    assert(!error);

    sel4utils_process_t spinner_process;
    benchmark_shallow_clone_process(env, &spinner_process, seL4_MaxPrio - 2, spinner_fn, "spinner");

    /* share the current time variable with the spinner process */
    void *current_time_remote = vspace_share_mem(&env->vspace, &spinner_process.vspace,
                                                 (void *) local_current_time, 1, seL4_PageBits,
                                                 seL4_AllRights, true);
    assert(current_time_remote != NULL);

    /* start the spinner process */
    sel4utils_create_word_args(strings, spinner_argv, 1, (seL4_Word) current_time_remote);
    error = sel4utils_spawn_process(&spinner_process, &env->slab_vka, &env->vspace, 1, spinner_argv, 1);
    if (error) {
        ZF_LOGF("Failed to start spinner process");
    }

    benchmark_wait_children(endpoint.cptr, "child of irq-user", 1);

    /* done -> results are stored in shared memory so we can now return */
    benchmark_finished(EXIT_SUCCESS);
    return 0;
}