Пример #1
0
/* 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();
}
Пример #2
0
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();
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
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();
}
Пример #7
0
// 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();
}
Пример #8
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();
}
Пример #9
0
/**
 * 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);
}
Пример #10
0
// 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);
    }
}
Пример #11
0
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();
}
Пример #12
0
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;
}
Пример #13
0
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();
}
Пример #14
0
/* 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();
}
Пример #15
0
void
FilterInstanceBase::filter_start_helper (const String &helper_uuid)
{
    start_helper (helper_uuid);
}