libgomp_lithe_sched_t *libgomp_lithe_sched_alloc() { /* Allocate all the scheduler data together. */ struct sched_data { libgomp_lithe_sched_t sched; libgomp_lithe_context_t main_context; struct lithe_fork_join_vc_mgmt vc_mgmt[]; }; /* Use a zombie list to reuse old schedulers if available, otherwise, create * a new one. */ struct sched_data *s = wfl_remove(&sched_zombie_list); if (!s) { s = parlib_aligned_alloc(PGSIZE, sizeof(*s) + sizeof(struct lithe_fork_join_vc_mgmt) * max_vcores()); s->sched.sched.vc_mgmt = &s->vc_mgmt[0]; s->sched.sched.sched.funcs = &libgomp_lithe_sched_funcs; } /* Initialize some libgomp specific fields before initializing the generic * underlying fjs. */ s->sched.refcnt = 1; s->main_context.completed = false; lithe_fork_join_sched_init(&s->sched.sched, &s->main_context.context); return &s->sched; }
/* This function allocates a sigdata struct for use when running signal * handlers inside a 2LS. The sigdata struct returned is pre-initialized with * the 'stack' field pointing to a valid stack. Space is allocated for both * the sigdata struct and the stack in a single mmap call. The sigdata struct * just sits at the bottom of the stack, and its 'stack' field points just * above it. */ struct sigdata *alloc_sigdata() { struct sigdata *data = wfl_remove(&sigdata_list); if (data == NULL) { void *stack = mmap(0, SIGNAL_STACK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_POPULATE|MAP_ANONYMOUS, -1, 0); assert(stack != MAP_FAILED); data = stack + SIGNAL_STACK_SIZE - sizeof(struct sigdata); data->stack = data; } return data; }
static libgomp_lithe_context_t *__ctx_alloc(size_t stacksize) { libgomp_lithe_context_t *ctx = wfl_remove(&context_zombie_list); if (!ctx) { int offset = ROUNDUP(sizeof(libgomp_lithe_context_t), ARCH_CL_SIZE); offset += rand_r(&rseed(0)) % max_vcores() * ARCH_CL_SIZE; stacksize = ROUNDUP(stacksize + offset, PGSIZE); void *stackbot = mmap( 0, stacksize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); if (stackbot == MAP_FAILED) abort(); ctx = stackbot + stacksize - offset; ctx->context.stack_offset = offset; ctx->context.context.stack.bottom = stackbot; ctx->context.context.stack.size = stacksize - offset; } return ctx; }