Skip to content

Commit

Permalink
Speed-up Tests
Browse files Browse the repository at this point in the history
Reduce unnecessary sleeping or long SC periods, without
reducing the quality of the tests.

Optimise test_fault() and test_ipc_pair() by taking init code
out of the inner loop and re-using the created processes.

These changes more than halve the time needed to run all tests.

Signed-off-by: Indan Zupancic <[email protected]>
  • Loading branch information
Indanz committed Nov 24, 2024
1 parent fe4839e commit 9367d34
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 137 deletions.
2 changes: 1 addition & 1 deletion apps/sel4test-driver/src/tests/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ int test_timer(driver_env_t env)
int error = tm_alloc_id_at(&env->tm, TIMER_ID);
test_assert_fatal(!error);

error = tm_register_cb(&env->tm, TIMEOUT_PERIODIC, 1 * NS_IN_S, 0, TIMER_ID,
error = tm_register_cb(&env->tm, TIMEOUT_PERIODIC, 100 * NS_IN_MS, 0, TIMER_ID,
test_callback, (uintptr_t) &test_data);
test_assert_fatal(!error);

Expand Down
141 changes: 69 additions & 72 deletions apps/sel4test-tests/src/tests/faults.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,74 +694,73 @@ static int test_fault(env_t env, int fault_type, bool inter_as)
vka_object_t reply;
error = vka_alloc_reply(&env->vka, &reply);

for (int restart = 0; restart <= 1; restart++) {
for (int prio = 100; prio <= 102; prio++) {
for (int badged = 0; badged <= 1; badged++) {
seL4_Word handler_arg0, handler_arg1;
/* The endpoint on which faults are received. */
seL4_CPtr fault_ep = vka_alloc_endpoint_leaky(&env->vka);
if (badged) {
seL4_CPtr badged_fault_ep = get_free_slot(env);
cnode_mint(env, fault_ep, badged_fault_ep, seL4_AllRights, EXPECTED_BADGE);

fault_ep = badged_fault_ep;
}
for (int badged = 0; badged <= 1; badged++) {
seL4_Word handler_arg0, handler_arg1;
/* The endpoint on which faults are received. */
seL4_CPtr fault_ep = vka_alloc_endpoint_leaky(&env->vka);
if (badged) {
seL4_CPtr badged_fault_ep = get_free_slot(env);
cnode_mint(env, fault_ep, badged_fault_ep, seL4_AllRights, EXPECTED_BADGE);

fault_ep = badged_fault_ep;
}

seL4_CPtr faulter_vspace, faulter_cspace, reply_cptr;

if (inter_as) {
create_helper_process(env, &faulter_thread);
create_helper_process(env, &handler_thread);

/* copy the fault endpoint to the faulter */
cspacepath_t path;
vka_cspace_make_path(&env->vka, fault_ep, &path);
seL4_CPtr remote_fault_ep = sel4utils_copy_path_to_process(&faulter_thread.process, path);
assert(remote_fault_ep != -1);

if (!config_set(CONFIG_KERNEL_MCS)) {
fault_ep = remote_fault_ep;
}

/* copy the fault endpoint to the handler */
handler_arg0 = sel4utils_copy_path_to_process(&handler_thread.process, path);
assert(handler_arg0 != -1);

/* copy the fault tcb to the handler */
vka_cspace_make_path(&env->vka, get_helper_tcb(&faulter_thread), &path);
handler_arg1 = sel4utils_copy_path_to_process(&handler_thread.process, path);
assert(handler_arg1 != -1);

reply_cptr = sel4utils_copy_cap_to_process(&handler_thread.process, &env->vka,
reply.cptr);
faulter_cspace = faulter_thread.process.cspace.cptr;
faulter_vspace = faulter_thread.process.pd.cptr;
} else {
create_helper_thread(env, &faulter_thread);
create_helper_thread(env, &handler_thread);
faulter_cspace = env->cspace_root;
faulter_vspace = env->page_directory;
handler_arg0 = fault_ep;
handler_arg1 = get_helper_tcb(&faulter_thread);
reply_cptr = reply.cptr;
}
seL4_CPtr faulter_vspace, faulter_cspace, reply_cptr;

set_helper_priority(env, &handler_thread, 101);
error = api_tcb_set_space(get_helper_tcb(&faulter_thread),
fault_ep,
faulter_cspace,
api_make_guard_skip_word(seL4_WordBits - env->cspace_size_bits),
faulter_vspace, seL4_NilData);
test_error_eq(error, seL4_NoError);
set_helper_priority(env, &faulter_thread, prio);
if (inter_as) {
create_helper_process(env, &faulter_thread);
create_helper_process(env, &handler_thread);

/* copy the fault endpoint to the faulter */
cspacepath_t path;
vka_cspace_make_path(&env->vka, fault_ep, &path);
seL4_CPtr remote_fault_ep = sel4utils_copy_path_to_process(&faulter_thread.process, path);
assert(remote_fault_ep != -1);

if (!config_set(CONFIG_KERNEL_MCS)) {
fault_ep = remote_fault_ep;
}

// Ensure that the BADGED and RESTART bits are not
// already set on the cptr.
test_assert(!(reply_cptr & (BIT(RESTART) | BIT(BADGED))));
seL4_Word flags_and_reply = reply_cptr |
(badged ? BIT(BADGED) : 0) |
(restart ? BIT(RESTART) : 0);
/* copy the fault endpoint to the handler */
handler_arg0 = sel4utils_copy_path_to_process(&handler_thread.process, path);
assert(handler_arg0 != -1);

/* copy the fault tcb to the handler */
vka_cspace_make_path(&env->vka, get_helper_tcb(&faulter_thread), &path);
handler_arg1 = sel4utils_copy_path_to_process(&handler_thread.process, path);
assert(handler_arg1 != -1);

reply_cptr = sel4utils_copy_cap_to_process(&handler_thread.process, &env->vka, reply.cptr);
faulter_cspace = faulter_thread.process.cspace.cptr;
faulter_vspace = faulter_thread.process.pd.cptr;
} else {
create_helper_thread(env, &faulter_thread);
create_helper_thread(env, &handler_thread);
faulter_cspace = env->cspace_root;
faulter_vspace = env->page_directory;
handler_arg0 = fault_ep;
handler_arg1 = get_helper_tcb(&faulter_thread);
reply_cptr = reply.cptr;
}

set_helper_priority(env, &handler_thread, 101);
error = api_tcb_set_space(get_helper_tcb(&faulter_thread),
fault_ep,
faulter_cspace,
api_make_guard_skip_word(seL4_WordBits - env->cspace_size_bits),
faulter_vspace, seL4_NilData);
test_error_eq(error, seL4_NoError);

// Ensure that the BADGED and RESTART bits are not
// already set on the cptr.
test_assert(!(reply_cptr & (BIT(RESTART) | BIT(BADGED))));

for (int restart = 0; restart <= 1; restart++) {
seL4_Word flags_and_reply = reply_cptr |
(badged ? BIT(BADGED) : 0) |
(restart ? BIT(RESTART) : 0);
for (int prio = 100; prio <= 102; prio++) {
set_helper_priority(env, &faulter_thread, prio);
start_helper(env, &handler_thread, (helper_fn_t) handle_fault,
handler_arg0, handler_arg1, fault_type, flags_and_reply);
start_helper(env, &faulter_thread, (helper_fn_t) cause_fault,
Expand All @@ -771,13 +770,11 @@ static int test_fault(env_t env, int fault_type, bool inter_as)
if (restart) {
wait_for_helper(&faulter_thread);
}

cleanup_helper(env, &handler_thread);
cleanup_helper(env, &faulter_thread);
}
}
cleanup_helper(env, &handler_thread);
cleanup_helper(env, &faulter_thread);
}

return sel4test_get_result();
}

Expand Down Expand Up @@ -856,13 +853,13 @@ int test_timeout_fault(env_t env)
seL4_CPtr ro = vka_alloc_reply_leaky(&env->vka);

create_helper_thread(env, &helper);
set_helper_sched_params(env, &helper, US_IN_MS, US_IN_S, data);
set_helper_sched_params(env, &helper, 1 * US_IN_MS, 2 * US_IN_MS, data);
set_helper_tfep(env, &helper, endpoint);
start_helper(env, &helper, (helper_fn_t) timeout_fault_0001_fn, 0, 0, 0, 0);

/* wait for timeout fault */
UNUSED seL4_MessageInfo_t info = api_recv(endpoint, NULL, ro);
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 100; i++) {
#ifdef CONFIG_KERNEL_MCS
test_eq(seL4_MessageInfo_get_length(info), (seL4_Word) seL4_Timeout_Length);
test_check(seL4_isTimeoutFault_tag(info));
Expand Down Expand Up @@ -976,7 +973,7 @@ static int test_timeout_fault_in_server(env_t env)

/* create the client */
create_helper_thread(env, &client);
set_helper_sched_params(env, &client, 0.1 * US_IN_S, US_IN_S, client_data);
set_helper_sched_params(env, &client, 100 * US_IN_MS, 101 * US_IN_MS, client_data);
start_helper(env, &client, (helper_fn_t) timeout_fault_client_fn, ep, 0, 0, 0);

/* Ensure the client doesn't preempt the server when the server is
Expand Down Expand Up @@ -1041,7 +1038,7 @@ static int test_timeout_fault_nested_servers(env_t env)

error = api_sched_ctrl_configure(simple_get_sched_ctrl(&env->simple, 0),
client.thread.sched_context.cptr,
0.1 * US_IN_S, 0.5 * US_IN_S, 0, client_data);
100 * US_IN_MS, 101 * US_IN_MS, 0, client_data);
test_eq(error, 0);

start_helper(env, &client, (helper_fn_t) timeout_fault_client_fn, client_proxy_ep, 0, 0, 0);
Expand Down
4 changes: 2 additions & 2 deletions apps/sel4test-tests/src/tests/fpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ int smp_test_fpu(env_t env)
/* Migrate threads to next core... */
set_helper_affinity(env, &t[i], (i + 1) % env->cores);
}
/* Lets do some calculation */
sel4test_sleep(env, 10 * NS_IN_MS);
/* Lets do some calculation with variable timing */
sel4test_sleep(env, (1 + it / 10) * NS_IN_MS);
}

/* Notify threads to return */
Expand Down
81 changes: 38 additions & 43 deletions apps/sel4test-tests/src/tests/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,55 +284,51 @@ static int test_ipc_pair(env_t env, test_func_t fa, test_func_t fb, bool inter_a
seL4_CPtr a_reply = vka_alloc_reply_leaky(vka);
seL4_CPtr b_reply = vka_alloc_reply_leaky(vka);

seL4_Word thread_a_arg0, thread_b_arg0;
seL4_CPtr thread_a_reply, thread_b_reply;

if (inter_as) {
create_helper_process(env, &thread_a);

cspacepath_t path;
vka_cspace_make_path(&env->vka, ep, &path);
thread_a_arg0 = sel4utils_copy_path_to_process(&thread_a.process, path);
assert(thread_a_arg0 != -1);

create_helper_process(env, &thread_b);
thread_b_arg0 = sel4utils_copy_path_to_process(&thread_b.process, path);
assert(thread_b_arg0 != -1);

if (config_set(CONFIG_KERNEL_MCS)) {
thread_a_reply = sel4utils_copy_cap_to_process(&thread_a.process, vka, a_reply);
thread_b_reply = sel4utils_copy_cap_to_process(&thread_b.process, vka, b_reply);
}
} else {
create_helper_thread(env, &thread_a);
create_helper_thread(env, &thread_b);
thread_a_arg0 = ep;
thread_b_arg0 = ep;
thread_a_reply = a_reply;
thread_b_reply = b_reply;
}
/* Test sending messages of varying lengths. */
/* Please excuse the awful indending here. */
for (int core_a = 0; core_a < nr_cores; core_a++) {
set_helper_affinity(env, &thread_a, core_a);
for (int core_b = 0; core_b < nr_cores; core_b++) {
set_helper_affinity(env, &thread_b, core_b);
for (int sender_prio = 98; sender_prio <= 102; sender_prio++) {
set_helper_priority(env, &thread_a, sender_prio);
for (int waiter_prio = 100; waiter_prio <= 100; waiter_prio++) {
/* Set the flag for nbwait_func that tells it whether or not it really
* should wait. */
int nbwait_should_wait = (sender_prio < waiter_prio);

set_helper_priority(env, &thread_b, waiter_prio);

for (int sender_first = 0; sender_first <= 1; sender_first++) {
ZF_LOGD("%d %s %d",
sender_prio, sender_first ? "->" : "<-", waiter_prio);
seL4_Word thread_a_arg0, thread_b_arg0;
seL4_CPtr thread_a_reply, thread_b_reply;

if (inter_as) {
create_helper_process(env, &thread_a);

cspacepath_t path;
vka_cspace_make_path(&env->vka, ep, &path);
thread_a_arg0 = sel4utils_copy_path_to_process(&thread_a.process, path);
assert(thread_a_arg0 != -1);

create_helper_process(env, &thread_b);
thread_b_arg0 = sel4utils_copy_path_to_process(&thread_b.process, path);
assert(thread_b_arg0 != -1);

if (config_set(CONFIG_KERNEL_MCS)) {
thread_a_reply = sel4utils_copy_cap_to_process(&thread_a.process, vka, a_reply);
thread_b_reply = sel4utils_copy_cap_to_process(&thread_b.process, vka, b_reply);
}
} else {
create_helper_thread(env, &thread_a);
create_helper_thread(env, &thread_b);
thread_a_arg0 = ep;
thread_b_arg0 = ep;
thread_a_reply = a_reply;
thread_b_reply = b_reply;
}

set_helper_priority(env, &thread_a, sender_prio);
set_helper_priority(env, &thread_b, waiter_prio);

set_helper_affinity(env, &thread_a, core_a);
set_helper_affinity(env, &thread_b, core_b);

/* Set the flag for nbwait_func that tells it whether or not it really
* should wait. */
int nbwait_should_wait;
nbwait_should_wait =
(sender_prio < waiter_prio);

/* Threads are enqueued at the head of the scheduling queue, so the
* thread enqueued last will be run first, for a given priority. */
if (sender_first) {
Expand All @@ -352,15 +348,14 @@ static int test_ipc_pair(env_t env, test_func_t fa, test_func_t fb, bool inter_a
res = wait_for_helper(&thread_b);
test_eq(res, SUCCESS);

cleanup_helper(env, &thread_a);
cleanup_helper(env, &thread_b);

start_number += 0x71717171;
}
}
}
}
}
cleanup_helper(env, &thread_a);
cleanup_helper(env, &thread_b);

error = cnode_delete(env, ep);
test_error_eq(error, seL4_NoError);
Expand Down
4 changes: 2 additions & 2 deletions apps/sel4test-tests/src/tests/schedcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int test_delete_tcb_sched_context(env_t env)
start_helper(env, &helper, (helper_fn_t) sched_context_0005_helper_fn, (seL4_Word) &state, 0, 0, 0);

/* let helper run */
sel4test_sleep(env, 1 * NS_IN_S);
sel4test_sleep(env, 10 * NS_IN_MS);

printf("Sleep....\n");
int prev_state = state;
Expand All @@ -193,7 +193,7 @@ int test_delete_tcb_sched_context(env_t env)

/* let it run again */
printf("Sleep....\n");
sel4test_sleep(env, 1 * NS_IN_S);
sel4test_sleep(env, 10 * NS_IN_MS);
printf("Awake\n");

/* it should not have run */
Expand Down
Loading

0 comments on commit 9367d34

Please sign in to comment.