static void nile_Process_free_node (nile_Process_t *p, nile_Node_t *nd) { if (nile_Heap_push (&p->heap, nd)) { nile_Thread_free_chunk (p->thread, nile_Heap_pop_chunk (&p->heap)); nile_prefetch (p->heap); } }
static nile_Heap_t nile_Process_remove (nile_Process_t *p, nile_Thread_t *thread, nile_Heap_t heap) { nile_ProcessState_t cstate; nile_Process_t *producer = p->producer; nile_Process_t *consumer = p->consumer; nile_Deque_t input = p->input; if (p->gatee) { nile_Thread_t *liaison = &thread->threads[thread->nthreads]; nile_Lock_acq (&liaison->lock); liaison->ngated--; nile_Lock_rel (&liaison->lock); heap = nile_Process_schedule (p->gatee, thread, heap); } if (producer) producer->consumer = consumer; if (consumer) { nile_Lock_acq (&consumer->lock); while (input.n) nile_Deque_push_tail (&consumer->input, nile_Deque_pop_head (&input)); consumer->producer = producer; cstate = consumer->state; nile_Lock_rel (&consumer->lock); nile_Heap_push (&heap, p); if (cstate == NILE_BLOCKED_ON_PRODUCER) heap = nile_Process_schedule (consumer, thread, heap); } else { p->thread = thread; p->heap = heap; while (input.n) nile_Process_free_node (p, nile_Deque_pop_head (&input)); heap = p->heap; nile_Heap_push (&heap, p); if (producer && producer->state == NILE_BLOCKED_ON_CONSUMER) heap = nile_Process_schedule (producer, thread, heap); } return heap; }
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; }