Пример #1
0
/* Passes all work for other threads that we've got left in our to-pass list. */
static void pass_leftover_work(MVMThreadContext *tc, WorkToPass *wtp) {
    MVMuint32 j;
    for (j = 0; j < wtp->num_target_threads; j++)
        if (wtp->target_work[j].work)
            push_work_to_thread_in_tray(tc, wtp->target_work[j].target,
                wtp->target_work[j].work);
}
Пример #2
0
/* Adds work to list of items to pass over to another thread, and if we
 * reach the pass threshold then does the passing. */
static void pass_work_item(MVMThreadContext *tc, WorkToPass *wtp, MVMCollectable **item_ptr) {
    ThreadWork *target_info = NULL;
    MVMuint32   target      = (*item_ptr)->owner;
    MVMuint32   j;
    MVMInstance *i          = tc->instance;

    /* Find any existing thread work passing list for the target. */
    if (target == 0)
        MVM_panic(MVM_exitcode_gcnursery, "Internal error: zeroed target thread ID in work pass");
    for (j = 0; j < wtp->num_target_threads; j++) {
        if (wtp->target_work[j].target == target) {
            target_info = &wtp->target_work[j];
            break;
        }
    }

    /* If there's no entry for this target, create one. */
    if (target_info == NULL) {
        wtp->num_target_threads++;
        wtp->target_work = MVM_realloc(wtp->target_work,
            wtp->num_target_threads * sizeof(ThreadWork));
        target_info = &wtp->target_work[wtp->num_target_threads - 1];
        target_info->target = target;
        target_info->work   = NULL;
    }

    /* See if there's a currently active list; create it if not. */
    if (!target_info->work) {
        target_info->work = calloc(sizeof(MVMGCPassedWork), 1);
    }

    /* Add this item to the work list. */
    target_info->work->items[target_info->work->num_items] = item_ptr;
    target_info->work->num_items++;

    /* If we've hit the limit, pass this work to the target thread. */
    if (target_info->work->num_items == MVM_GC_PASS_WORK_SIZE) {
        push_work_to_thread_in_tray(tc, target, target_info->work);
        target_info->work = NULL;
    }
}