/* The enclosed test relies on the current thread being able to create two * threads of unequal priority, both less than the caller's own priority. For * this we need at least 3 priority levels, assuming that the current thread is * running at the highest priority. */ static int test_set_priority(struct env* env) { helper_thread_t thread1; helper_thread_t thread2; ZF_LOGD("test_set_priority starting\n"); create_helper_thread(env, &thread1); set_helper_priority(&thread1, SCHED0005_HIGHEST_PRIO); create_helper_thread(env, &thread2); set_helper_priority(&thread2, SCHED0005_HIGHEST_PRIO - 1); set_priority_step = 0; ZF_LOGD(" "); start_helper(env, &thread1, (helper_fn_t) set_priority_helper_1, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2.thread.tcb.cptr, 0, 0); start_helper(env, &thread2, (helper_fn_t) set_priority_helper_2, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2.thread.tcb.cptr, 0, 0); wait_for_helper(&thread1); wait_for_helper(&thread2); test_check(set_priority_step == 4); ZF_LOGD("\n"); cleanup_helper(env, &thread1); cleanup_helper(env, &thread2); return sel4test_get_result(); }
static int test_suspend(struct env* env) { helper_thread_t thread1; helper_thread_t thread2a; helper_thread_t thread2b; ZF_LOGD("Starting test_suspend\n"); create_helper_thread(env, &thread1); ZF_LOGD("Show me\n"); create_helper_thread(env, &thread2a); create_helper_thread(env, &thread2b); /* First set all the helper threads to have unique priorities * and then start them in order of priority. This is so when * the 'start_helper' function does an IPC to the helper * thread, it doesn't allow one of the already started helper * threads to run at all */ set_helper_priority(&thread1, 0); set_helper_priority(&thread2a, 1); set_helper_priority(&thread2b, 2); start_helper(env, &thread1, (helper_fn_t) suspend_test_helper_1, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); start_helper(env, &thread2a, (helper_fn_t) suspend_test_helper_2a, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); start_helper(env, &thread2b, (helper_fn_t) suspend_test_helper_2b, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); /* Now set their priorities to what we want */ set_helper_priority(&thread1, 100); set_helper_priority(&thread2a, 101); set_helper_priority(&thread2b, 101); suspend_test_step = 0; ZF_LOGD(" "); wait_for_helper(&thread1); wait_for_helper(&thread2b); CHECK_STEP(suspend_test_step, 6); ZF_LOGD("\n"); cleanup_helper(env, &thread1); cleanup_helper(env, &thread2a); cleanup_helper(env, &thread2b); return sel4test_get_result(); }
static int test_ipc_prios(struct env* env) { vka_t *vka = &env->vka; helper_thread_t thread0; helper_thread_t thread1; helper_thread_t thread2; helper_thread_t thread3; int result = 0; ipc_test_data_t data; memset(&data, 0, sizeof(data)); data.ep0 = vka_alloc_endpoint_leaky(vka); data.ep1 = vka_alloc_endpoint_leaky(vka); data.ep2 = vka_alloc_endpoint_leaky(vka); data.ep3 = vka_alloc_endpoint_leaky(vka); create_helper_thread(env, &thread0); set_helper_priority(&thread0, 0); create_helper_thread(env, &thread1); set_helper_priority(&thread1, 1); create_helper_thread(env, &thread2); set_helper_priority(&thread2, 2); create_helper_thread(env, &thread3); set_helper_priority(&thread3, 3); data.tcb0 = thread0.thread.tcb.cptr; data.tcb1 = thread1.thread.tcb.cptr; data.tcb2 = thread2.thread.tcb.cptr; data.tcb3 = thread3.thread.tcb.cptr; ZF_LOGD(" "); ipc_test_step = 0; start_helper(env, &thread0, (helper_fn_t) ipc_test_helper_0, (seL4_Word) &data, 0, 0, 0); start_helper(env, &thread1, (helper_fn_t) ipc_test_helper_1, (seL4_Word) &data, 0, 0, 0); start_helper(env, &thread2, (helper_fn_t) ipc_test_helper_2, (seL4_Word) &data, 0, 0, 0); start_helper(env, &thread3, (helper_fn_t) ipc_test_helper_3, (seL4_Word) &data, 0, 0, 0); result |= (int)wait_for_helper(&thread1); result |= (int)wait_for_helper(&thread3); CHECK_STEP(ipc_test_step, 10); ZF_LOGD("\n"); cleanup_helper(env, &thread0); cleanup_helper(env, &thread1); cleanup_helper(env, &thread2); cleanup_helper(env, &thread3); return result; }
int slurm_spank_user_init (spank_t sp, int ac, char **av) { char socket_name[4096]; uid_t uid; uint32_t jobid, stepid, nodeid; spank_get_item(sp, S_JOB_UID, &uid); spank_get_item(sp, S_JOB_ID, &jobid); spank_get_item(sp, S_JOB_STEPID, &stepid); spank_get_item(sp, S_JOB_NODEID, &nodeid); if (nodeid != 0) return 0; /* WARNING - If you change the file name here at all, you must update the file name in src/aixslurm/internal.c as well. Even though we have spank set the YOGRT_AIXSLURM_SOCKET variable, the pmdv4 daemon will NOT pass the variable down to the user's task. */ snprintf(socket_name, sizeof(socket_name), "/tmp/.yogrtaixslurm_%d_%u.%u", uid, jobid, stepid); spank_setenv(sp, "YOGRT_AIXSLURM_SOCKET", socket_name, 1); helper_pid = start_helper(socket_name, jobid); return 0; }
/** * Starts a helper and begins reading from it. The helper process is * restarted when it dies except when it is stopped using GNUNET_HELPER_stop() * or when the exp_cb callback is not NULL. * * @param with_control_pipe does the helper support the use of a control pipe for signalling? * @param binary_name name of the binary to run * @param binary_argv NULL-terminated list of arguments to give when starting the binary (this * argument must not be modified by the client for * the lifetime of the helper handle) * @param cb function to call if we get messages from the helper * @param exp_cb the exception callback to call. Set this to NULL if the helper * process has to be restarted automatically when it dies/crashes * @param cb_cls closure for the above callback * @return the new Handle, NULL on error */ struct GNUNET_HELPER_Handle * GNUNET_HELPER_start (int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_SERVER_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls) { struct GNUNET_HELPER_Handle *h; unsigned int c; h = GNUNET_new (struct GNUNET_HELPER_Handle); h->with_control_pipe = with_control_pipe; /* Lookup in libexec path only if we are starting gnunet helpers */ if (NULL != strstr (binary_name, "gnunet")) h->binary_name = GNUNET_OS_get_libexec_binary_path (binary_name); else h->binary_name = GNUNET_strdup (binary_name); for (c = 0; NULL != binary_argv[c]; c++); h->binary_argv = GNUNET_malloc (sizeof (char *) * (c + 1)); for (c = 0; NULL != binary_argv[c]; c++) h->binary_argv[c] = GNUNET_strdup (binary_argv[c]); h->binary_argv[c] = NULL; h->cb_cls = cb_cls; if (NULL != cb) h->mst = GNUNET_SERVER_mst_create (cb, h->cb_cls); h->exp_cb = exp_cb; h->retry_back_off = 0; start_helper (h); return h; }
static int test_full_cspace(env_t env) { int error; seL4_CPtr cnode[CONFIG_WORD_SIZE]; seL4_CPtr ep = vka_alloc_endpoint_leaky(&env->vka); seL4_Word ep_pos = 1; /* Create 32 or 64 cnodes, each resolving one bit. */ for (unsigned int i = 0; i < CONFIG_WORD_SIZE; i++) { cnode[i] = vka_alloc_cnode_object_leaky(&env->vka, 1); assert(cnode[i]); } /* Copy cnode i to alternating slots in cnode i-1. */ seL4_Word slot = 0; for (unsigned int i = 1; i < CONFIG_WORD_SIZE; i++) { error = seL4_CNode_Copy( cnode[i - 1], slot, 1, env->cspace_root, cnode[i], seL4_WordBits, seL4_AllRights); test_assert(!error); ep_pos |= (slot << i); slot ^= 1; } /* In the final cnode, put an IPC endpoint in slot 1. */ error = seL4_CNode_Copy( cnode[CONFIG_WORD_SIZE - 1], slot, 1, env->cspace_root, ep, seL4_WordBits, seL4_AllRights); test_assert(!error); /* Start a helper thread in our own cspace, to let it get set up. */ helper_thread_t t; create_helper_thread(env, &t); start_helper(env, &t, ipc_caller, ep, ep_pos, CONFIG_WORD_SIZE, 0); /* Wait for it. */ seL4_MessageInfo_t tag; seL4_Word sender_badge = 0; tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == READY_MAGIC); /* Now switch its cspace. */ error = seL4_TCB_SetSpace(t.thread.tcb.cptr, t.fault_endpoint, cnode[0], seL4_NilData, env->page_directory, seL4_NilData); test_assert(!error); /* And now wait for it to do some tests and return to us. */ tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == SUCCESS_MAGIC); cleanup_helper(env, &t); return sel4test_get_result(); }
// Called by the proxy when it is time to kick off an animation job void QQuickAnimatorController::start(const QSharedPointer<QAbstractAnimationJob> &job) { m_rootsPendingStart.insert(job); m_rootsPendingStop.remove(job); job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); start_helper(job.data()); requestSync(); }
/* * 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(); }
/** * Restart the helper process. * * @param cls handle to the helper process */ static void restart_task (void *cls) { struct GNUNET_HELPER_Handle*h = cls; h->restart_task = NULL; h->retry_back_off++; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Restarting helper with back-off %u\n", h->retry_back_off); start_helper (h); }
// All this is being executed on the GUI thread while the animator controller // is locked. void QQuickAnimatorController::start_helper(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); j->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); j->initialize(this); } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) start_helper(a); } }
static int test_all_priorities(struct env* env) { int i; helper_thread_t **threads = (helper_thread_t **) malloc(sizeof(helper_thread_t*) * NUM_PRIOS); assert(threads != NULL); for (i = 0; i < NUM_PRIOS; i++) { threads[i] = (helper_thread_t*) malloc(sizeof(helper_thread_t)); assert(threads[i]); } vka_t *vka = &env->vka; ZF_LOGD("Testing all thread priorities"); volatile seL4_Word last_prio = MAX_PRIO + 1; seL4_CPtr ep = vka_alloc_endpoint_leaky(vka); for (int prio = MIN_PRIO; prio <= MAX_PRIO; prio++) { int idx = prio - MIN_PRIO; test_check(idx >= 0 && idx < NUM_PRIOS); create_helper_thread(env, threads[idx]); set_helper_priority(threads[idx], prio); start_helper(env, threads[idx], (helper_fn_t) prio_test_func, prio, (seL4_Word) &last_prio, ep, 0); } /* Now block. */ seL4_Word sender_badge = 0; seL4_Recv(ep, &sender_badge); /* When we get woken up, last_prio should be MIN_PRIO. */ test_check(last_prio == MIN_PRIO); for (int prio = MIN_PRIO; prio <= MAX_PRIO; prio++) { int idx = prio - MIN_PRIO; cleanup_helper(env, threads[idx]); free(threads[idx]); } free(threads); return sel4test_get_result(); }
bool SocketInstance::do_transaction (Transaction &trans, bool &ret) { int cmd = -1; bool cont = false; ret = false; SCIM_DEBUG_IMENGINE(2) << " Do transaction:\n"; if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY) { while (trans.get_command (cmd)) { switch (cmd) { case SCIM_TRANS_CMD_SHOW_PREEDIT_STRING: { SCIM_DEBUG_IMENGINE(3) << " show_preedit_string ()\n"; show_preedit_string (); break; } case SCIM_TRANS_CMD_SHOW_AUX_STRING: { SCIM_DEBUG_IMENGINE(3) << " show_aux_string ()\n"; show_aux_string (); break; } case SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE: { SCIM_DEBUG_IMENGINE(3) << " show_lookup_table ()\n"; show_lookup_table (); break; } case SCIM_TRANS_CMD_HIDE_PREEDIT_STRING: { SCIM_DEBUG_IMENGINE(3) << " hide_preedit_string ()\n"; hide_preedit_string (); break; } case SCIM_TRANS_CMD_HIDE_AUX_STRING: { SCIM_DEBUG_IMENGINE(3) << " hide_aux_string ()\n"; hide_aux_string (); break; } case SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE: { SCIM_DEBUG_IMENGINE(3) << " hide_lookup_table ()\n"; hide_lookup_table (); break; } case SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET: { uint32 caret; if (trans.get_data (caret)) { SCIM_DEBUG_IMENGINE(3) << " update_preedit_caret (" << caret << ")\n"; update_preedit_caret (caret); } break; } case SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING: { WideString str; AttributeList attrs; if (trans.get_data (str) && trans.get_data (attrs)) { SCIM_DEBUG_IMENGINE(3) << " update_preedit_string ()\n"; update_preedit_string (str, attrs); } break; } case SCIM_TRANS_CMD_UPDATE_AUX_STRING: { WideString str; AttributeList attrs; if (trans.get_data (str) && trans.get_data (attrs)) { SCIM_DEBUG_IMENGINE(3) << " update_aux_string ()\n"; update_aux_string (str, attrs); } break; } case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE: { CommonLookupTable table; if (trans.get_data (table)) { SCIM_DEBUG_IMENGINE(3) << " update_lookup_table ()\n"; update_lookup_table (table); } break; } case SCIM_TRANS_CMD_COMMIT_STRING: { WideString str; if (trans.get_data (str)) { SCIM_DEBUG_IMENGINE(3) << " commit_string ()\n"; commit_string (str); } break; } case SCIM_TRANS_CMD_FORWARD_KEY_EVENT: { KeyEvent key; if (trans.get_data (key)) { SCIM_DEBUG_IMENGINE(3) << " forward_key_event ()\n"; forward_key_event (key); } break; } case SCIM_TRANS_CMD_REGISTER_PROPERTIES: { PropertyList proplist; if (trans.get_data (proplist)) { SCIM_DEBUG_IMENGINE(3) << " register_properties ()\n"; // Load icon files of these properties from remote SocketFrontEnd. for (PropertyList::iterator it = proplist.begin (); it != proplist.end (); ++it) it->set_icon (global->load_icon (it->get_icon ())); register_properties (proplist); } break; } case SCIM_TRANS_CMD_UPDATE_PROPERTY: { Property prop; if (trans.get_data (prop)) { SCIM_DEBUG_IMENGINE(3) << " update_property ()\n"; // Load the icon file of this property from remote SocketFrontEnd. prop.set_icon (global->load_icon (prop.get_icon ())); update_property (prop); } break; } case SCIM_TRANS_CMD_BEEP: { SCIM_DEBUG_IMENGINE(3) << " beep ()\n"; beep (); break; } case SCIM_TRANS_CMD_START_HELPER: { String helper_uuid; if (trans.get_data (helper_uuid)) { SCIM_DEBUG_IMENGINE(3) << " start_helper (" << helper_uuid << ")\n"; start_helper (helper_uuid); } break; } case SCIM_TRANS_CMD_STOP_HELPER: { String helper_uuid; if (trans.get_data (helper_uuid)) { SCIM_DEBUG_IMENGINE(3) << " stop_helper (" << helper_uuid << ")\n"; stop_helper (helper_uuid); } break; } case SCIM_TRANS_CMD_SEND_HELPER_EVENT: { String helper_uuid; Transaction temp_trans; if (trans.get_data (helper_uuid) && trans.get_data (temp_trans)) { SCIM_DEBUG_IMENGINE(3) << " send_helper_event (" << helper_uuid << ")\n"; send_helper_event (helper_uuid, temp_trans); } break; } case SCIM_TRANS_CMD_OK: { SCIM_DEBUG_IMENGINE(3) << " ret = true\n"; ret = true; break; } case SCIM_TRANS_CMD_GET_SURROUNDING_TEXT: { WideString text; int cursor; uint32 maxlen_before; uint32 maxlen_after; Transaction temp_trans; if (trans.get_data (maxlen_before) && trans.get_data (maxlen_after)) { global->init_transaction (temp_trans); if (get_surrounding_text (text, cursor, (int) maxlen_before, (int) maxlen_after)) { temp_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT); temp_trans.put_data (text); temp_trans.put_data ((uint32) cursor); } else { temp_trans.put_command (SCIM_TRANS_CMD_FAIL); } global->send_transaction (temp_trans); } cont = true; break; } case SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT: { uint32 offset; uint32 len; Transaction temp_trans; if (trans.get_data (offset) && trans.get_data (len)) { global->init_transaction (temp_trans); if (delete_surrounding_text ((int) offset, (int) len)) { temp_trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT); temp_trans.put_command (SCIM_TRANS_CMD_OK); } else { temp_trans.put_command (SCIM_TRANS_CMD_FAIL); } global->send_transaction (temp_trans); } cont = true; break; } default: SCIM_DEBUG_IMENGINE(3) << " Strange cmd: " << cmd << "\n";; } } } else { SCIM_DEBUG_IMENGINE(3) << " Failed to get cmd: " << cmd << "\n"; } SCIM_DEBUG_IMENGINE(2) << " End of Do transaction\n"; return cont; }
static int test_ep_recycle(env_t env) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); struct { helper_thread_t thread; seL4_CPtr badged_ep; seL4_CPtr derived_badged_ep; volatile seL4_Word done; } senders[NUM_BADGED_CLIENTS]; helper_thread_t bouncer; seL4_CPtr bounce_ep; UNUSED int error; seL4_CPtr ep; /* Create the master endpoint. */ ep = vka_alloc_endpoint_leaky(&env->vka); /* Create N badged endpoints, and derive each of them. */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { senders[i].badged_ep = get_free_slot(env); assert(senders[i].badged_ep != 0); senders[i].derived_badged_ep = get_free_slot(env); assert(senders[i].derived_badged_ep != 0); seL4_CapData_t cap_data; cap_data = seL4_CapData_Badge_new (i + 200); error = cnode_mint(env, ep, senders[i].badged_ep, seL4_AllRights, cap_data); assert(!error); error = cnode_copy(env, senders[i].badged_ep, senders[i].derived_badged_ep, seL4_AllRights); assert(!error); create_helper_thread(env, &senders[i].thread); set_helper_priority(&senders[i].thread, 100); senders[i].done = -1; } /* Create a bounce thread so we can get lower prio threads to run. */ bounce_ep = vka_alloc_endpoint_leaky(&env->vka); create_helper_thread(env, &bouncer); set_helper_priority(&bouncer, 0); start_helper(env, &bouncer, bouncer_func, bounce_ep, 0, 0, 0); for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { start_helper(env, &senders[i].thread, (helper_fn_t) call_func, senders[i].derived_badged_ep, i + 100, (seL4_Word) &senders[i].done, 0); } /* Let the sender threads run. */ seL4_Call(bounce_ep, tag); /* Receive a message from each endpoint and check the badge. */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { seL4_Word sender_badge; seL4_MessageInfo_ptr_set_length(&tag, 1); tag = seL4_Recv(ep, &sender_badge); assert(seL4_MessageInfo_get_length(tag) == 1); assert(seL4_GetMR(0) == sender_badge - 100); seL4_SetMR(0, ~seL4_GetMR(0)); seL4_Reply(tag); } /* Let the sender threads run. */ seL4_Call(bounce_ep, tag); /* Check none of the threads have failed yet. */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { assert(senders[i].done == 0); } /* Recycle each endpoint. */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { error = cnode_recycle(env, senders[i].badged_ep); assert(!error); /* Let thread run. */ seL4_Call(bounce_ep, tag); /* Check that only the intended threads have now aborted. */ for (int j = 0; j < NUM_BADGED_CLIENTS; j++) { if (j <= i) { assert(senders[j].done == 1); } else { assert(senders[j].done == 0); } } } seL4_Call(bounce_ep, tag); for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { cleanup_helper(env, &senders[i].thread); } cleanup_helper(env, &bouncer); return sel4test_get_result(); }
/* RECYCLE0001 only tests if a thread gets its IPC canceled. The IPC * can succeed even if the cap it used got deleted provided the final * capability was not recycled (thus causing an IPC cancel to happen) * This means that RECYCLE0001 will pass even if all the derived badges * are deleted, since deleting them did NOT delete the final capability * or cause a recycle so outstanding IPCs were not canceled */ static int test_ep_recycle2(env_t env) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); struct { helper_thread_t thread; seL4_CPtr sync_ep; seL4_CPtr badged_ep; seL4_CPtr derived_badged_ep; volatile seL4_Word last_status; } helpers[NUM_BADGED_CLIENTS]; seL4_CPtr ep; helper_thread_t reply_thread; UNUSED int error; /* Create the main EP we are testing */ ep = vka_alloc_endpoint_leaky(&env->vka); /* spawn a thread to keep replying to any messages on main ep */ create_helper_thread(env, &reply_thread); start_helper(env, &reply_thread, bouncer_func, ep, 0, 0, 0); /* Spawn helper threads each with their own sync ep and a badged copy of the main ep */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { helpers[i].badged_ep = get_free_slot(env); assert(helpers[i].badged_ep != 0); helpers[i].derived_badged_ep = get_free_slot(env); assert(helpers[i].derived_badged_ep != 0); helpers[i].sync_ep = vka_alloc_endpoint_leaky(&env->vka); seL4_CapData_t cap_data; cap_data = seL4_CapData_Badge_new (i + 200); error = cnode_mint(env, ep, helpers[i].badged_ep, seL4_AllRights, cap_data); assert(!error); error = cnode_copy(env, helpers[i].badged_ep, helpers[i].derived_badged_ep, seL4_AllRights); assert(!error); helpers[i].last_status = -1; create_helper_thread(env, &helpers[i].thread); start_helper(env, &helpers[i].thread, (helper_fn_t) ep_test_func, helpers[i].sync_ep, helpers[i].derived_badged_ep, (seL4_Word) &helpers[i].last_status, 0); } /* Test that every thread and endpoint is working */ for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { seL4_Call(helpers[i].sync_ep, tag); } for (int i = 0; i < NUM_BADGED_CLIENTS; i++) { test_assert(helpers[i].last_status); } /* Now start recycling endpoints and make sure the correct endpoints disappear */ for (int i = 0 ; i < NUM_BADGED_CLIENTS; i++) { /* Recycle an ep */ error = cnode_recycle(env, helpers[i].badged_ep); assert(!error); /* Now run every thread */ for (int j = 0; j < NUM_BADGED_CLIENTS; j++) { seL4_Call(helpers[j].sync_ep, tag); } for (int j = 0; j < NUM_BADGED_CLIENTS; j++) { if (j <= i) { test_assert(!helpers[j].last_status); } else { test_assert(helpers[j].last_status); } } } return sel4test_get_result(); }
void FilterInstanceBase::filter_start_helper (const String &helper_uuid) { start_helper (helper_uuid); }