// constructors: FiberSection3d::FiberSection3d(int tag, int num, Fiber **fibers): SectionForceDeformation(tag, SEC_TAG_FiberSection3d), numFibers(num), sizeFibers(num), theMaterials(0), matData(0), QzBar(0.0), QyBar(0.0), Abar(0.0), yBar(0.0), zBar(0.0), sectionIntegr(0), e(3), s(0), ks(0) { if (numFibers != 0) { theMaterials = new UniaxialMaterial *[numFibers]; if (theMaterials == 0) { opserr << "FiberSection3d::FiberSection3d -- failed to allocate Material pointers\n"; exit(-1); } matData = new double [numFibers*3]; if (matData == 0) { opserr << "FiberSection3d::FiberSection3d -- failed to allocate double array for material data\n"; exit(-1); } for (int i = 0; i < numFibers; i++) { Fiber *theFiber = fibers[i]; double yLoc, zLoc, Area; theFiber->getFiberLocation(yLoc, zLoc); Area = theFiber->getArea(); QzBar += yLoc*Area; QyBar += zLoc*Area; Abar += Area; matData[i*3] = yLoc; matData[i*3+1] = zLoc; matData[i*3+2] = Area; UniaxialMaterial *theMat = theFiber->getMaterial(); theMaterials[i] = theMat->getCopy(); if (theMaterials[i] == 0) { opserr << "FiberSection3d::FiberSection3d -- failed to get copy of a Material\n"; exit(-1); } } yBar = QzBar/Abar; zBar = QyBar/Abar; } s = new Vector(sData, 3); ks = new Matrix(kData, 3, 3); sData[0] = 0.0; sData[1] = 0.0; sData[2] = 0.0; for (int i=0; i<9; i++) kData[i] = 0.0; code(0) = SECTION_RESPONSE_P; code(1) = SECTION_RESPONSE_MZ; code(2) = SECTION_RESPONSE_MY; }
Fiber* FiberManager::getFiber() { Fiber* fiber = nullptr; if (options_.fibersPoolResizePeriodMs > 0 && !fibersPoolResizerScheduled_) { fibersPoolResizer_(); fibersPoolResizerScheduled_ = true; } if (fibersPool_.empty()) { fiber = new Fiber(*this); ++fibersAllocated_; } else { fiber = &fibersPool_.front(); fibersPool_.pop_front(); assert(fibersPoolSize_ > 0); --fibersPoolSize_; } assert(fiber); if (++fibersActive_ > maxFibersActiveLastPeriod_) { maxFibersActiveLastPeriod_ = fibersActive_; } ++fiberId_; bool recordStack = (options_.recordStackEvery != 0) && (fiberId_ % options_.recordStackEvery == 0); fiber->init(recordStack); return fiber; }
int FiberSection2d::addFiber(Fiber &newFiber) { // need to create larger arrays int newSize = numFibers+1; UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; double *newMatData = new double [2 * newSize]; if (newArray == 0 || newMatData == 0) { opserr <<"FiberSection2d::addFiber -- failed to allocate Fiber pointers\n"; return -1; } // copy the old pointers and data int i; for (i = 0; i < numFibers; i++) { newArray[i] = theMaterials[i]; newMatData[2*i] = matData[2*i]; newMatData[2*i+1] = matData[2*i+1]; } // set the new pointers and data double yLoc, zLoc, Area; newFiber.getFiberLocation(yLoc, zLoc); Area = newFiber.getArea(); newMatData[numFibers*2] = yLoc; newMatData[numFibers*2+1] = Area; UniaxialMaterial *theMat = newFiber.getMaterial(); newArray[numFibers] = theMat->getCopy(); if (newArray[numFibers] == 0) { opserr <<"FiberSection2d::addFiber -- failed to get copy of a Material\n"; delete [] newMatData; return -1; } numFibers++; if (theMaterials != 0) { delete [] theMaterials; delete [] matData; } theMaterials = newArray; matData = newMatData; double Qz = 0.0; double A = 0.0; // Recompute centroid for (i = 0; i < numFibers; i++) { yLoc = -matData[2*i]; Area = matData[2*i+1]; A += Area; Qz += yLoc*Area; } yBar = Qz/A; return 0; }
void Fiber::fiberStartingFunction(void* data) { Fiber* fiber = reinterpret_cast<Fiber*>(data); while(true) { fiber->m_func(fiber); fiber->yield(); } }
Fiber* Fiber::current(STATE) { #ifdef FIBER_ENABLED Fiber* fib = state->current_fiber.get(); // Lazily allocate a root fiber. if(fib->nil_p()) { fib = state->new_object<Fiber>(G(fiber)); fib->prev_ = reinterpret_cast<Fiber*>(Qnil); fib->top_ = 0; fib->root_ = true; fib->status_ = Fiber::eRunning; fib->state_ = state; fib->stack_size_ = state->stack_size(); fib->stack_ = state->stack_start(); fib->context_ = new ucontext_t; state->om->needs_finalization(fib, (FinalizerFunction)&Fiber::finalize); state->current_fiber.set(fib); state->root_fiber.set(fib); } return fib; #else return reinterpret_cast<Fiber*>(Qnil); #endif }
Fiber* Fiber::current(STATE) { #ifdef RBX_FIBER_ENABLED Fiber* fib = state->vm()->current_fiber.get(); // Lazily allocate a root fiber. if(fib->nil_p()) { fib = state->new_object<Fiber>(G(fiber)); fib->prev(state, nil<Fiber>()); fib->locals(state, nil<LookupTable>()); fib->root_ = true; fib->status_ = Fiber::eRunning; fib->data_ = state->vm()->new_fiber_data(true); state->memory()->needs_finalization(fib, (FinalizerFunction)&Fiber::finalize); state->vm()->current_fiber.set(fib); state->vm()->root_fiber.set(fib); } return fib; #else return nil<Fiber>(); #endif }
Object* Fiber::resume(STATE, Arguments& args, CallFrame* calling_environment) { #ifdef FIBER_ENABLED if(!prev_->nil_p() || root_) return Primitives::failure(); Object* val = Qnil; if(args.total() == 1) { val = args.get_argument(0); } else if(args.total() > 1) { val = args.as_array(state); } value(state, val); Fiber* cur = Fiber::current(state); prev(state, cur); cur->sleep(calling_environment); run(); state->set_current_fiber(this); if(swapcontext(cur->ucontext(), context_) != 0) assert(0 && "fatal swapcontext() error"); // Back here when someone yields back to us! // Beware here, because the GC has probably run so GC pointers on the C++ stack // can't be accessed. cur = Fiber::current(state); return cur->value(); #else return Primitives::failure(); #endif }
void Fiber::Info::mark(Object* obj, memory::ObjectMark& mark) { auto_mark(obj, mark); Fiber* fib = force_as<Fiber>(obj); FiberData* data = fib->data(); if(!data || data->dead_p()) return; data->set_mark(); }
// constructors: FiberSection2d::FiberSection2d(int tag, int num, Fiber **fibers): SectionForceDeformation(tag, SEC_TAG_FiberSection2d), numFibers(num), theMaterials(0), matData(0), yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2) { if (numFibers != 0) { theMaterials = new UniaxialMaterial *[numFibers]; if (theMaterials == 0) { opserr << "FiberSection2d::FiberSection2d -- failed to allocate Material pointers"; exit(-1); } matData = new double [numFibers*2]; if (matData == 0) { opserr << "FiberSection2d::FiberSection2d -- failed to allocate double array for material data\n"; exit(-1); } double Qz = 0.0; double A = 0.0; for (int i = 0; i < numFibers; i++) { Fiber *theFiber = fibers[i]; double yLoc, zLoc, Area; theFiber->getFiberLocation(yLoc, zLoc); Area = theFiber->getArea(); A += Area; Qz += yLoc*Area; matData[i*2] = yLoc; matData[i*2+1] = Area; UniaxialMaterial *theMat = theFiber->getMaterial(); theMaterials[i] = theMat->getCopy(); if (theMaterials[i] == 0) { opserr << "FiberSection2d::FiberSection2d -- failed to get copy of a Material\n"; exit(-1); } } yBar = Qz/A; } s = new Vector(sData, 2); ks = new Matrix(kData, 2, 2); sData[0] = 0.0; sData[1] = 0.0; kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0; code(0) = SECTION_RESPONSE_P; code(1) = SECTION_RESPONSE_MZ; }
void Fiber::Info::mark(Object* obj, ObjectMark& mark) { auto_mark(obj, mark); Fiber* fib = (Fiber*)obj; if(CallFrame* cf = fib->call_frame()) { mark.gc->walk_call_frame(cf); } }
void Core::reschedule() { Core *currentCore = Core::current(); Fiber *currentFiber = Fiber::current(); currentCore->fReadyQueueLock.acquire(); Fiber *nextFiber = currentCore->fReadyQueue.dequeue(); currentCore->fReadyQueue.enqueue(currentFiber); nextFiber->switchTo(); currentCore->fReadyQueueLock.release(); }
void Service::Create(fiber_func func, void *data, int32_t stacksize, const char* name, Fiber** retVal) { Fiber *fb; void **stack; stacksize = (stacksize + FB_STK_ALIGN - 1) & ~(FB_STK_ALIGN - 1); #ifdef WIN32 fb = (Fiber *) VirtualAlloc(NULL, stacksize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); #else fb = (Fiber *) malloc(stacksize); #endif if (fb == NULL) return; stack = (void **) fb + stacksize / sizeof(void *) - 5; new(fb) Fiber(s_service, data); fb->m_cntxt.ip = (intptr_t) fiber_proc; fb->m_cntxt.sp = (intptr_t) stack; #if defined(x64) #ifdef _WIN32 fb->m_cntxt.Rcx = (intptr_t) func; fb->m_cntxt.Rdx = (intptr_t) fb; #else fb->m_cntxt.Rdi = (intptr_t) func; fb->m_cntxt.Rsi = (intptr_t) fb; #endif #elif defined(I386) stack[1] = (void *)func; stack[2] = fb; #elif defined(arm) fb->m_cntxt.r0 = (intptr_t) func; fb->m_cntxt.r1 = (intptr_t) fb; #endif #ifdef DEBUG s_locker.lock(); s_fibers.putTail(&fb->m_link); s_locker.unlock(); #endif if (retVal) { *retVal = fb; fb->Ref(); } fb->Ref(); fb->resume(); }
Object* Thread::locals_remove(STATE, Symbol* key) { if(state->vm() != vm()) { return locals()->remove(state, key); } Fiber* fib = state->vm()->current_fiber.get(); if(fib->nil_p() || fib->root_p()) { return locals()->remove(state, key); } if(fib->locals()->nil_p()) { return cNil; } return fib->locals()->remove(state, key); }
Fiber *Service::CreateFiber(void *(*func)(void *), void *data, int stacksize) { Fiber *fb; void **stack; stacksize = (stacksize + FB_STK_ALIGN - 1) & ~(FB_STK_ALIGN - 1); #ifdef WIN32 fb = (Fiber *) VirtualAlloc(NULL, stacksize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); #else fb = (Fiber *) malloc(stacksize); #endif if (fb == NULL) return NULL; stack = (void **) fb + stacksize / sizeof(void *) - 5; memset(fb, 0, sizeof(Fiber)); #if defined(x64) fb->m_cntxt.Rip = (unsigned long long) fiber_proc; fb->m_cntxt.Rsp = (unsigned long long) stack; #ifdef _WIN32 fb->m_cntxt.Rcx = (unsigned long long) func; fb->m_cntxt.Rdx = (unsigned long long) data; #else fb->m_cntxt.Rdi = (unsigned long long) func; fb->m_cntxt.Rsi = (unsigned long long) data; #endif #elif defined(I386) fb->m_cntxt.Eip = (unsigned long) fiber_proc; fb->m_cntxt.Esp = (unsigned long) stack; stack[1] = (void *)func; stack[2] = data; #elif defined(arm) fb->m_cntxt.r14 = (unsigned long) fiber_proc; fb->m_cntxt.r13 = (unsigned long) stack; fb->m_cntxt.r0 = (unsigned long) func; fb->m_cntxt.r1 = (unsigned long) data; #endif root->m_resume.put(fb); fb->Ref(); fb->Ref(); return fb; }
Object* Fiber::s_yield(STATE, Arguments& args) { Fiber* fiber = state->vm()->fiber(); OnStack<1> os(state, fiber); { std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex()); if(fiber->root_p()) { Exception::raise_fiber_error(state, "can't yield from root fiber"); } else if(fiber->status() == eTransfer) { Exception::raise_fiber_error(state, "can't yield from transferred fiber"); } fiber->unpack_arguments(state, args); fiber->status(eYielding); } // Being cooperative... fiber->invoke_context()->fiber()->restart(state); // Through the worm hole... fiber->suspend_and_continue(state); // We're back... return fiber->return_value(state); }
void Fiber::start_on_stack() { #ifdef FIBER_ENABLED VM* state = VM::current(); Fiber* fib = Fiber::current(state); // Affix this fiber to this thread now. fib->state_ = state; fib->starter()->send(state, NULL, G(sym_call)); // GC has run! Don't use stack vars! fib = Fiber::current(state); fib->status_ = Fiber::eDead; Fiber* dest = fib->prev(); assert(!dest->nil_p()); dest->run(); dest->value(state, Qnil); state->set_current_fiber(dest); if(setcontext(dest->ucontext()) != 0) assert(0 && "fatal swapcontext() error"); assert(0 && "fatal start_on_stack error"); #else abort(); #endif }
void Fiber::start_on_stack() { #ifdef RBX_FIBER_ENABLED VM* vm = VM::current(); State state(vm); Fiber* fib = Fiber::current(&state); // Reset the current fiber again to reset the stack limits so // we can properly detect stack overflows vm->set_current_fiber(fib); Array* result = nil<Array>(); Object* obj = fib->starter()->send(&state, NULL, state.globals().sym_call.get(), fib->value(), cNil, false); // GC has run! Don't use stack vars! fib = Fiber::current(&state); fib->status_ = Fiber::eDead; fib->dead_ = cTrue; Fiber* dest = fib->prev(); // If this fiber has already been cleaned up, just ignore this if(!dest->data()) return; assert(!dest->nil_p()); // Box this up so it's in a standard format at the point // of returning, so we can deal with it in the same way // as *args from #yield, #resume, and #transfer if(obj) { result = Array::create(&state, 1); result->set(&state, 0, obj); } else { if(state.vm()->thread_state()->raise_reason() == cException) { dest->exception(&state, state.vm()->thread_state()->current_exception()); } } dest->run(); dest->value(&state, result); state.vm()->set_current_fiber(dest); dest->data_->switch_and_orphan(&state, fib->data_); assert(0 && "fatal start_on_stack error"); #else rubinius::bug("Fibers not supported on this platform"); #endif }
void FiberPushCutter::pushCutter2(Fiber& f) { std::list<Triangle>::iterator it,it_end; // for looping over found triangles Interval* i; std::list<Triangle>* tris; CLPoint cl; if ( x_direction ) { cl.x=0; cl.y=f.p1.y; cl.z=f.p1.z; } else if (y_direction ) { cl.x=f.p1.x; cl.y=0; cl.z=f.p1.z; } tris = root->search_cutter_overlap(cutter, &cl); it_end = tris->end(); for ( it=tris->begin() ; it!=it_end ; ++it) { i = new Interval(); cutter->pushCutter(f,*i,*it); f.addInterval(*i); ++nCalls; delete i; } delete( tris ); }
bool BullCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { //std::cout << " BullCutter::generalEdgePush() \n"; bool result = false; if ( isZero_tol( (p2-p1).xyNorm() ) ) { // this would be a vertical edge return result; } if ( isZero_tol( p2.z-p1.z ) ) // this would be a horizontal edge return result; assert( fabs(p2.z-p1.z) > 0.0 ); // no horiz edges allowed hereafter // p1+t*(p2-p1) = f.p1.z+radius2 => double tplane = (f.p1.z + radius2 - p1.z ) / (p2.z-p1.z); // intersect edge with plane at z = ufp1.z Point ell_center = p1+tplane*(p2-p1); assert( isZero_tol( fabs(ell_center.z - (f.p1.z+radius2)) ) ); Point major_dir = (p2-p1); assert( major_dir.xyNorm() > 0.0 ); major_dir.z = 0; major_dir.xyNormalize(); Point minor_dir = major_dir.xyPerp(); double theta = atan( (p2.z - p1.z) / (p2-p1).xyNorm() ); double major_length = fabs( radius2/sin(theta) ) ; double minor_length = radius2; AlignedEllipse e(ell_center, major_length, minor_length, radius1, major_dir, minor_dir ); if ( e.aligned_solver( f ) ) { // now we want the offset-ellipse point to lie on the fiber Point pseudo_cc = e.ePoint1(); // pseudo cc-point on ellipse and cylinder Point pseudo_cc2 = e.ePoint2(); CCPoint cc = pseudo_cc.closestPoint(p1,p2); CCPoint cc2 = pseudo_cc2.closestPoint(p1,p2); cc.type = EDGE_POS; cc2.type = EDGE_POS; Point cl = e.oePoint1() - Point(0,0,center_height); assert( isZero_tol( fabs(cl.z - f.p1.z)) ); Point cl2 = e.oePoint2() - Point(0,0,center_height); assert( isZero_tol( fabs(cl2.z - f.p1.z)) ); double cl_t = f.tval(cl); double cl_t2 = f.tval(cl2); if ( i.update_ifCCinEdgeAndTrue( cl_t, cc, p1, p2, true ) ) result = true; if ( i.update_ifCCinEdgeAndTrue( cl_t2, cc2, p1, p2, true ) ) result = true; } //std::cout << " BullCutter::generalEdgePush() DONE result= " << result << "\n"; return result; }
Object* Thread::locals_has_key(STATE, Symbol* key) { /* * If we're not trying to set values on the current thread, * we will set thread locals anyway and not use fiber locals. */ if(state->vm() != vm()) { return locals()->has_key(state, key); } Fiber* fib = state->vm()->current_fiber.get(); if(fib->nil_p() || fib->root_p()) { return locals()->has_key(state, key); } if(try_as<LookupTable>(fib->locals())) { return fib->locals()->has_key(state, key); } return cFalse; }
Array* Thread::locals_keys(STATE) { /* * If we're not trying to set values on the current thread, * we will set thread locals anyway and not use fiber locals. */ if(state->vm() != vm()) { return locals()->all_keys(state); } Fiber* fib = state->vm()->current_fiber.get(); if(fib->nil_p() || fib->root_p()) { return locals()->all_keys(state); } if(try_as<LookupTable>(fib->locals())) { return fib->locals()->all_keys(state); } return Array::create(state, 0); }
Object* Fiber::resume(STATE, Arguments& args) { #ifdef RBX_FIBER_ENABLED if(!data()) { data(state->vm()->new_fiber_data(stack_size()->to_native())); } if(status() == Fiber::eDead || data()->dead_p()) { Exception::raise_fiber_error(state, "dead fiber called"); } if(!prev()->nil_p()) { Exception::raise_fiber_error(state, "double resume"); } if(data()->thread() && data()->thread() != state->vm()) { Exception::raise_fiber_error(state, "cross thread fiber resuming is illegal"); } Array* val = args.as_array(state); value(state, val); Fiber* cur = Fiber::current(state); prev(state, cur); cur->sleep(state); run(state); data()->switch_to(state, cur->data()); // Back here when someone yields back to us! // Beware here, because the GC has probably run so GC pointers on the C++ stack // can't be accessed. cur = Fiber::current(state); // TODO: clean up this and the following conditional. if(state->vm()->thread_interrupted_p(state)) { return NULL; } if(!cur->exception()->nil_p()) { state->raise_exception(cur->exception()); cur->exception(state, nil<Exception>()); return NULL; } Array* ret = cur->value(); if(ret->nil_p()) return cNil; switch(ret->size()) { case 0: return cNil; case 1: return ret->get(state, 0); default: return ret; } #else Exception::raise_not_implemented_error(state, "Fibers not supported on this platform"); #endif }
Fiber* Fiber::current(STATE) { #ifdef RBX_FIBER_ENABLED Fiber* fib = state->vm()->current_fiber.get(); // Lazily allocate a root fiber. if(fib->nil_p()) { fib = state->memory()->new_object<Fiber>(state, G(fiber)); fib->root(true); fib->status(Fiber::eRunning); fib->data(state->vm()->new_fiber_data(true, fib->stack_size()->to_native())); fib->data()->set_call_frame(state->vm()->call_frame()); state->memory()->native_finalizer(state, fib, (memory::FinalizerFunction)&Fiber::finalize); state->vm()->current_fiber.set(fib); state->vm()->root_fiber.set(fib); } return fib; #else Exception::raise_not_implemented_error(state, "Fibers not supported on this platform"); #endif }
void FiberPushCutter::pushCutter1(Fiber& f) { nCalls = 0; BOOST_FOREACH( const Triangle& t, surf->tris) {// test against all triangles in s Interval i; cutter->pushCutter(f,i,t); f.addInterval(i); ++nCalls; } }
Fiber* Fiber::create(STATE, Object* self, Object* callable) { #ifdef RBX_FIBER_ENABLED Fiber* fib = state->new_object<Fiber>(as<Class>(self)); fib->starter(state, callable); fib->prev(state, nil<Fiber>()); fib->locals(state, nil<LookupTable>()); fib->root_ = false; fib->status_ = Fiber::eSleeping; fib->data_ = 0; state->memory()->needs_finalization(fib, (FinalizerFunction)&Fiber::finalize); return fib; #else return static_cast<Fiber*>(Primitives::failure()); #endif }
Object* Fiber::resume(STATE, Arguments& args, CallFrame* calling_environment) { #ifdef RBX_FIBER_ENABLED if(!data_) { data_ = state->vm()->new_fiber_data(); } if(status_ == Fiber::eDead || data_->dead_p()) { Exception::fiber_error(state, "dead fiber called"); } if(!prev_->nil_p()) { Exception::fiber_error(state, "double resume"); } if(data_->thread() && data_->thread() != state->vm()) { Exception::fiber_error(state, "cross thread fiber resuming is illegal"); } Array* val = args.as_array(state); value(state, val); Fiber* cur = Fiber::current(state); prev(state, cur); cur->sleep(calling_environment); run(); state->vm()->set_current_fiber(this); data_->switch_to(state, cur->data_); // Back here when someone yields back to us! // Beware here, because the GC has probably run so GC pointers on the C++ stack // can't be accessed. cur = Fiber::current(state); state->set_call_frame(cur->call_frame()); if(!cur->exception()->nil_p()) { state->raise_exception(cur->exception()); cur->exception(state, nil<Exception>()); return 0; } Array* ret = cur->value(); if(ret->nil_p()) return cNil; switch(ret->size()) { case 0: return cNil; case 1: return ret->get(state, 0); default: return ret; } #else return Primitives::failure(); #endif }
bool MillingCutter::singleVertexPush(const Fiber& f, Interval& i, const Point& p, CCType cctyp) const { bool result = false; if ( ( p.z >= f.p1.z ) && ( p.z <= (f.p1.z+ this->getLength()) ) ) { // p.z is within cutter Point pq = p.xyClosestPoint(f.p1, f.p2); // closest point on fiber double q = (p-pq).xyNorm(); // distance in XY-plane from fiber to p double h = p.z - f.p1.z; assert( h>= 0.0); double cwidth = this->width( h ); if ( q <= cwidth ) { // we are going to hit the vertex p double ofs = sqrt( square( cwidth ) - square(q) ); // distance along fiber Point start = pq - ofs*f.dir; Point stop = pq + ofs*f.dir; CCPoint cc_tmp( p, cctyp ); i.updateUpper( f.tval(stop) , cc_tmp ); i.updateLower( f.tval(start) , cc_tmp ); result = true; } } return result; }
Fiber* Fiber::create(STATE, Object* self, Object* stack_size, Object* callable) { #ifdef RBX_FIBER_ENABLED Fiber* fib = state->memory()->new_object<Fiber>(state, as<Class>(self)); fib->starter(state, callable); if(Fixnum* size = try_as<Fixnum>(stack_size)) { state->vm()->validate_stack_size(state, size->to_native()); fib->stack_size(state, size); } state->vm()->metrics().system.fibers_created++; state->memory()->native_finalizer(state, fib, (memory::FinalizerFunction)&Fiber::finalize); return fib; #else Exception::raise_not_implemented_error(state, "Fibers not supported on this platform"); #endif }
static void fiberCallback(fcontext_transfer_t transfer) { Fiber* fiber = (Fiber*)transfer.data; ThreadData* data = (ThreadData*)g_dispatcher->threadData.get(); data->running = fiber; fiber->callback(fiber->jobIndex, fiber->userData); // Job is finished bx::atomicFetchAndSub(fiber->counter, 1); data->running = nullptr; // Delete the fiber fiber->ownerPool->deleteFiber(fiber); // Go back jump_fcontext(transfer.ctx, transfer.data); }
Value Value::SendMessage(Fiber & fiber, StringId messageId, const ArgReader & args) const { const Value * receiver = this; // Walk the parent chain looking for a method that matches the message. while (true) { // Only dynamic objects have methods. DynamicObject * dynamic = receiver->AsDynamic(); if (dynamic != NULL) { // See if the object has a method bound to that name. Value method = dynamic->FindMethod(messageId); if (!method.IsNull()) { fiber.CallBlock(*this, method, args); return Value(); } // See if the object has a primitive bound to that name. PrimitiveMethod primitive = dynamic->FindPrimitive(messageId); if (primitive != NULL) { return primitive(fiber, *this, args); } } // If we're at the root of the inheritance chain, then stop. if (receiver->Parent().IsNull()) break; receiver = &receiver->Parent(); } // If we got here, the object didn't handle the message. String messageName = fiber.GetInterpreter().FindString(messageId); String error = String::Format("Object '%s' did not handle message '%s'", AsString().CString(), messageName.CString()); fiber.Error(error); // Unhandled messages just return nil. return fiber.Nil(); }