static VALUE fiber_store(rb_context_t *next_cont) { rb_thread_t *th = GET_THREAD(); rb_context_t *cont; if (th->fiber) { GetContPtr(th->fiber, cont); cont->saved_thread = *th; } else { /* create current fiber */ cont = fiber_alloc(rb_cFiber); /* no need to allocate vm stack */ cont->type = ROOT_FIBER_CONTEXT; th->root_fiber = th->fiber = cont->self; } cont_save_machine_stack(th, cont); if (ruby_setjmp(cont->jmpbuf)) { /* restored */ GetContPtr(th->fiber, cont); return cont->value; } else { return Qundef; } }
static rb_fiber_t * root_fiber_alloc(rb_thread_t *th) { rb_fiber_t *fib; /* no need to allocate vm stack */ fib = fiber_t_alloc(fiber_alloc(rb_cFiber)); fib->cont.type = ROOT_FIBER_CONTEXT; fib->prev_fiber = fib->next_fiber = fib; return fib; }
VALUE rb_fiber_current() { rb_thread_t *th = GET_THREAD(); if (th->fiber == 0) { /* save root */ rb_context_t *cont = fiber_alloc(rb_cFiber); cont->type = ROOT_FIBER_CONTEXT; th->root_fiber = th->fiber = cont->self; } return th->fiber; }
ACL_FIBER *acl_fiber_create(void (*fn)(ACL_FIBER *, void *), void *arg, size_t size) { ACL_FIBER *fiber = fiber_alloc(fn, arg, size); __thread_fiber->count++; if (__thread_fiber->slot >= __thread_fiber->size) { __thread_fiber->size += 128; __thread_fiber->fibers = (ACL_FIBER **) acl_myrealloc( __thread_fiber->fibers, __thread_fiber->size * sizeof(ACL_FIBER *)); } fiber->slot = __thread_fiber->slot; __thread_fiber->fibers[__thread_fiber->slot++] = fiber; acl_fiber_ready(fiber); return fiber; }
static VALUE fiber_new(VALUE klass, VALUE proc) { rb_context_t *cont = fiber_alloc(klass); VALUE contval = cont->self; rb_thread_t *th = &cont->saved_thread; /* initialize */ cont->vm_stack = 0; th->stack = 0; th->stack_size = FIBER_VM_STACK_SIZE; th->stack = ALLOC_N(VALUE, th->stack_size); th->cfp = (void *)(th->stack + th->stack_size); th->cfp--; th->cfp->pc = 0; th->cfp->sp = th->stack + 1; th->cfp->bp = 0; th->cfp->lfp = th->stack; *th->cfp->lfp = 0; th->cfp->dfp = th->stack; th->cfp->self = Qnil; th->cfp->flag = 0; th->cfp->iseq = 0; th->cfp->proc = 0; th->cfp->block_iseq = 0; th->tag = 0; th->local_storage = st_init_numtable(); th->first_proc = proc; MEMCPY(&cont->jmpbuf, &th->root_jmpbuf, rb_jmpbuf_t, 1); return contval; }
VALUE rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj) { return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj)); }