Пример #1
0
// 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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
void Fiber::fiberStartingFunction(void* data) {
	Fiber* fiber = reinterpret_cast<Fiber*>(data);
	while(true) {
		fiber->m_func(fiber);
		fiber->yield();
	}
}
Пример #5
0
  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
  }
Пример #6
0
  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
  }
Пример #7
0
  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
  }
Пример #8
0
 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();
 }
Пример #9
0
// 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;
}
Пример #10
0
  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);
    }
  }
Пример #11
0
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();
}
Пример #12
0
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();
}
Пример #13
0
 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);
 }
Пример #14
0
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;
}
Пример #15
0
  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);
  }
Пример #16
0
  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
  }
Пример #17
0
  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 );
}
Пример #19
0
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;
}
Пример #20
0
 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;
 }
Пример #21
0
 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);
 }
Пример #22
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
  }
Пример #23
0
  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;
    }
}
Пример #25
0
  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
  }
Пример #26
0
  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
  }
Пример #27
0
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;
}
Пример #28
0
  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
  }
Пример #29
0
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);
}
Пример #30
0
 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();
 }