Esempio n. 1
0
static void
nile_Process_handle_out_of_input (nile_Process_t *p, nile_Buffer_t *out)
{
    nile_Thread_t *thread = nile_Process_deactivate (p, out);

    if (nile_Process_block_on_producer (p))
        return;
    else if (p->producer)
        thread->private_heap = nile_Process_schedule (p->producer, thread, thread->private_heap);
    else if (p->input.n)
        thread->private_heap = nile_Process_schedule (p, thread, thread->private_heap);
    else if (p->epilogue) {
        nile_Process_activate (p, thread);
        out = nile_Buffer (p);
        if (!out)
            return (void) nile_Process_deactivate (p, NULL);
        out = p->epilogue (p, out);
        if (!out)
            return;
        thread = nile_Process_deactivate (p, out);
        thread->private_heap = nile_Process_remove (p, thread, thread->private_heap);
    }
    else
        thread->private_heap = nile_Process_remove (p, thread, thread->private_heap);
}
Esempio n. 2
0
static void
nile_Process_run (nile_Process_t *p, nile_Thread_t *thread)
{
    nile_Buffer_t *out;

    nile_prefetch (p->input.head);
    if (p->input.n > 1)
        nile_prefetch (p->input.head->next);

    nile_Process_activate (p, thread);
    out = nile_Buffer (p);
    if (!out)
        return (void) nile_Process_deactivate (p, NULL);
    if (nile_Process_quota_hit (p->consumer))
        out->tag = NILE_TAG_QUOTA_HIT;

    if (p->prologue) {
        out = p->prologue (p, out);
        if (!out)
            return;
        p->prologue = NULL;
    }

    while (p->input.head) {
        out = p->body (p, NODE_TO_BUFFER (p->input.head), out);
        if (!out)
            return;
        nile_Process_pop_input (p);
        if (out->tag == NILE_TAG_OOM)
            return (void) nile_Process_deactivate (p, NULL);
        if (out->tag == NILE_TAG_QUOTA_HIT)
            return nile_Process_handle_backpressure (p, out);
    }
    nile_Process_handle_out_of_input (p, out);
}
Esempio n. 3
0
File: nile.c Progetto: nhemsley/nile
void
nile_print_leaks (nile_Process_t *init)
{
    int i;
    int n = 0;
    nile_Thread_t *t = nile_Process_deactivate (init, NULL);
    nile_Block_t *block = (nile_Block_t *) (t->threads + t->nthreads + 1);
    nile_Block_t *EOB   = (nile_Block_t *) (t->memory + t->nbytes - sizeof (*block) + 1);
    int nblocks = EOB - block; // minus the init block
    for (i = 0; i < t->nthreads + 1; i++)
        n += nile_Heap_size (t->threads[i].private_heap) +
             nile_Heap_size (t->threads[i].public_heap);
    if (n != nblocks) {
        fprintf (stderr, "# blocks not in a heap: %d\n", nblocks - n);
        for (; block < EOB; block++) {
            nile_Node_t *nd = (nile_Node_t *) block;
            if (nd == &init->node)
                continue;
            if (nd->type == NILE_BUFFER_TYPE)
                fprintf (stderr, "LEAKED BUFFER : %p\n", nd);
            else if (nd->type == NILE_PROCESS_TYPE)
                fprintf (stderr, "LEAKED PROCESS: %p\n", nd);
        }
    }
    nile_Process_activate (init, t);
}
Esempio n. 4
0
File: nile.c Progetto: NV/nile
void
nile_sync (nile_Process_t *init)
{
    int i;
    nile_Process_t *p;
    nile_Thread_t *liaison = nile_Process_deactivate (init, NULL);
    nile_Thread_t *worker = &liaison->threads[0];

    nile_Thread_transfer_heaps (liaison, worker);
    for (i = 1; i < liaison->nthreads; i++)
        liaison->threads[i].sync = 1;

    if ((p = (nile_Process_t *) nile_Thread_steal_from_q (worker)))
        nile_Thread_work (worker, p);
    while (worker->status == NILE_STATUS_OK) {
        p = (nile_Process_t *) nile_Thread_steal (worker, nile_Thread_steal_from_q);
        if (p)
            nile_Thread_work (worker, p);
        else if (nile_Sleep_is_quiescent (worker->sleep))
            break;
        else
            nile_Sleep_doze (1000);
    }

    for (i = 1; i < liaison->nthreads; i++)
        liaison->threads[i].sync = 0;
    nile_Thread_transfer_heaps (worker, liaison);
    nile_Process_activate (init, liaison);
}
Esempio n. 5
0
nile_Buffer_t *
nile_Process_swap (nile_Process_t *p, nile_Process_t *sub, nile_Buffer_t *out)
{
    nile_Thread_t *thread = nile_Process_deactivate (p, out);
    if (sub) {
        nile_Process_t *consumer = p->consumer;
        p->consumer = NULL;
        nile_Process_pipe (p, sub, consumer, NILE_NULL);
    }
    p->body = NULL;
    if (!nile_Process_block_on_producer (p))
        thread->private_heap = nile_Process_remove (p, thread, thread->private_heap);
    return NULL;
}
Esempio n. 6
0
File: nile.c Progetto: nhemsley/nile
char *
nile_shutdown (nile_Process_t *init)
{
    int i;
    nile_Thread_t *t = nile_Process_deactivate (init, NULL);
    for (i = 0; i < t->nthreads + 1; i++)
        t->threads[i].status = NILE_STATUS_SHUTTING_DOWN;
    for (i = 0; i < t->nthreads; i++)
        nile_Sleep_issue_wakeup (t->sleep);
    for (i = 1; i < t->nthreads; i++)
        nile_OSThread_join (&t->threads[i].osthread);
    nile_Sleep_fini (t->sleep);
    return t->memory;
}
Esempio n. 7
0
static void
nile_Process_handle_backpressure (nile_Process_t *p, nile_Buffer_t *out)
{
    nile_ProcessState_t cstate;
    nile_Process_t *consumer = p->consumer;
    nile_Thread_t *thread = nile_Process_deactivate (p, out);

    nile_Lock_acq (&consumer->lock);
        p->state = NILE_BLOCKED_ON_CONSUMER;
        cstate = consumer->state;
    nile_Lock_rel (&consumer->lock);

    if (cstate == NILE_BLOCKED_ON_PRODUCER)
        thread->private_heap = nile_Process_schedule (consumer, thread, thread->private_heap);
}
Esempio n. 8
0
File: nile.c Progetto: nhemsley/nile
nile_Process_t *
nile_startup (char *memory, int nbytes, int nthreads)
{
    int i;
    nile_Process_t *init;
    nile_Sleep_t *sleep;
    nile_Thread_t *threads;
    nile_Block_t *block, *EOB;
    nile_Process_t boot;

#ifdef NILE_DISABLE_THREADS
    nthreads = 1;
#endif

    if ((size_t) nbytes < CACHE_LINE_SIZE + sizeof (*sleep) + sizeof (*threads) * (nthreads + 1))
        return NULL;

    sleep = (nile_Sleep_t *)
        (((size_t) memory + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1));
    nile_Sleep_init (sleep, nthreads);

    threads = (nile_Thread_t *) (sleep + 1);
    for (i = 0; i < nthreads + 1; i++)
        nile_Thread (i, threads, nthreads, sleep, memory, nbytes);

    block = (nile_Block_t *) (threads + nthreads + 1);
    EOB   = (nile_Block_t *) (memory + nbytes - sizeof (*block) + 1);
    while (block < EOB)
        for (i = 1; i < nthreads + 1 && block < EOB; i++, block++)
            nile_Heap_push (&threads[i].public_heap, block);

    for (i = 1; i < nthreads; i++)
        nile_OSThread_spawn (&threads[i].osthread, nile_Thread_main, &threads[i]);

    nile_Process_activate (&boot, &threads[nthreads]);
    init = nile_Process (&boot, 0, 0, NULL, NULL, NULL);
    nile_Process_deactivate (&boot, NULL);
    if (init)
        nile_Process_activate (init, &threads[nthreads]);
    return init;
}
Esempio n. 9
0
File: nile.c Progetto: nhemsley/nile
void
nile_sync (nile_Process_t *init)
{
    int i;
    nile_Process_t *p;
    nile_Thread_t *liaison = nile_Process_deactivate (init, NULL);
    nile_Thread_t *worker = &liaison->threads[0];

    nile_Thread_transfer_heaps (liaison, worker);
    for (i = 1; i < liaison->nthreads; i++)
        liaison->threads[i].sync = 1;

    if ((p = nile_Thread_steal_from_q (worker)))
        nile_Thread_work (worker, p);
    while (worker->status == NILE_STATUS_OK &&
           (p = nile_Thread_steal (worker, nile_Thread_steal_from_q)))
        nile_Thread_work (worker, p);
    nile_Sleep_wait_for_quiecent (liaison->sleep);

    for (i = 1; i < liaison->nthreads; i++)
        liaison->threads[i].sync = 0;
    nile_Thread_transfer_heaps (worker, liaison);
    nile_Process_activate (init, liaison);
}