Beispiel #1
0
BOOL
OSAcquireSpinLock(OSSpinLock *spinlock)
{
   OSTestThreadCancel();
   spinLock(spinlock);
   return TRUE;
}
Beispiel #2
0
static MsgStore *
allocMsg(MsgMgrPrimRef self)
{
  EBBRC rc;
  MsgStore *msg;  
  spinLock(&self->freelistlock);
  msg = self->freelist;
  if (msg != NULL) {
    self->freelist = msg->next; 
    spinUnlock(&self->freelistlock);
    msg->home = MyEL();
    // lrt_printf("%s:%s found free message\n", __FILE__, __func__);
    return msg ;
  }
  spinUnlock(&self->freelistlock);

  // lrt_printf("%s:%s freelist empty, allocating new msg\n", __FILE__, __func__);

  // need to allocate another message 
  rc = EBBPrimMalloc(sizeof(*msg), &msg, EBB_MEM_DEFAULT);
  LRT_RCAssert(rc);

  msg->home = MyEL();

  return msg;
}
Beispiel #3
0
void Cache::unrefHierarchy(
        const std::string& name,
        const HierarchyReader::Slots& touched)
{
    if (touched.empty()) return;

    std::lock_guard<std::mutex> topLock(m_hierarchyMutex);
    HierarchyCache& selected(m_hierarchyCache[name]);
    std::lock_guard<std::mutex> selectedLock(selected.mutex);

    auto& slots(selected.slots);
    auto& order(selected.order);
    auto& refs(selected.refs);

    for (const HierarchyReader::Slot* s : touched)
    {
        assert(refs.at(s) >= 1);
        --refs.at(s);

        if (slots.count(s))
        {
            order.splice(order.begin(), order, slots.at(s));
        }
        else
        {
            auto it(slots.insert(std::make_pair(s, order.end())).first);
            order.push_front(s);
            it->second = order.begin();

            m_hierarchyBytes += s->t->size();
        }
    }

    const auto begin(m_hierarchyBytes);
    while (
            m_hierarchyBytes > m_maxHierarchyBytes &&
            order.size() &&
            !refs[order.back()])
    {
        const HierarchyReader::Slot* s(order.back());
        order.pop_back();

        SpinGuard spinLock(s->spinner);
        m_hierarchyBytes -= s->t->size();
        s->t.reset();
        slots.erase(s);
    }
    const auto end(m_hierarchyBytes);

    if (begin != end)
    {
        std::cout <<
            "\tHB " << begin << " -> " << end <<
            "\tHier: " << (m_hierarchyBytes / 1024 / 1024) << "MB" <<
            "\tFetches: " << touched.size() << std::endl;
    }

    assert(order.size() == slots.size());
}
Beispiel #4
0
struct ZObjInstance *
__get_cur_error()
{
	unsigned long thread_id = cur_thread;
	spinLock(&spin_lk);
	struct RBNode *stack = rbSearch(stack_tree, &thread_id);
	spinUnlock(&spin_lk);
	assert(to_stack(stack)->cur_error != NULL);
	return to_stack(stack)->cur_error;
}
Beispiel #5
0
void
__throw(struct ZObjInstance *e)
{
	unsigned long thread_id = cur_thread;
	spinLock(&spin_lk);
	struct RBNode *stack = rbSearch(stack_tree, &thread_id);
	spinUnlock(&spin_lk);
	to_stack(stack)->cur_error = e;
	longjmp(to_stack(stack)->stack_top->jb, 1);
}
Beispiel #6
0
void PIEventRegistry::BroadcastEvent(PIEvent const &rEvent)
{
	ValidateSystemRegistry();
	SystemSpinLock	spinLock(pTheRegistry->mLock);	// make thread safe
	// send all registered objects the event
	std::map<PIEventHandler*, std::string const *>::iterator	iter = pTheRegistry->mHandlers.begin();
	while (iter != pTheRegistry->mHandlers.end()) {
		iter->first->ProcessEvent(&rEvent, static_cast<PIEventHandler*>(0));
		++iter;
	}
}
Beispiel #7
0
void PIEventRegistry::RegisterEvents(PIEventHandler &rEventHandler)
{
	SystemSpinLock	spinLock(mLock);	// make thread safe
#if _DEBUG || defined (DEBUG)
	// if the event handler has a name, ensure it's unique
	if (rEventHandler.GetName().length() != 0)
		assert(NamedEventHandler(rEventHandler.GetName()) == 0);
#endif
	// add it to the list, or update it's name if it's already in the list
	mHandlers[&rEventHandler] = &rEventHandler.GetName();
}
Beispiel #8
0
static MsgStore *
MsgMgrPrim_dequeueMsgHead(MsgMgrPrimRef target)
{
  MsgStore *msg;
  spinLock(&target->msgqueuelock);
  msg = target->msgqueue;
  if (msg != NULL) {
    target->msgqueue = msg->next;
  }
  spinUnlock(&target->msgqueuelock);
  return msg;
}
Beispiel #9
0
void
__pop_jmp_point()
{
	unsigned long thread_id = cur_thread;
	spinLock(&spin_lk);
	struct RBNode *stack = rbSearch(stack_tree, &thread_id);
	spinUnlock(&spin_lk);
	struct stack_node *node = to_stack(stack)->stack_top;
	assert(node != NULL);
	to_stack(stack)->stack_top = node->prev;
	free(node);
}	
Beispiel #10
0
void *
__push_jmp_point()
{
	unsigned long thread_id = cur_thread;
	spinLock(&spin_lk);
	rbInsert(&stack_tree, &thread_id);
	spinUnlock(&spin_lk);
	struct RBNode *stack = rbSearch(stack_tree, &thread_id);
	struct stack_node *new_node = malloc(sizeof(struct stack_node));
	assert(new_node != NULL);
	new_node->prev = to_stack(stack)->stack_top;
	to_stack(stack)->stack_top = new_node;
	return new_node->jb;
}
Beispiel #11
0
static void
freeMsg(MsgMgrPrimRef self, MsgStore *msg)
{
  EBBRC rc;
  MsgMgrPrimRef target; 

  rc = MsgMgrPrim_findTarget(self, msg->home, &target);
  LRT_RCAssert(rc);

  spinLock(&target->freelistlock);
  msg->next = target->freelist;
  target->freelist = msg;
  spinUnlock(&target->freelistlock);
}
Beispiel #12
0
static EBBRC
MsgMgrPrim_enqueueMsg(MsgMgrPrimRef target, MsgStore *msg)
{
  uintptr_t queueempty = 1;
  spinLock(&target->msgqueuelock);
  if (target->msgqueue != NULL) {
    queueempty = 0;
  }
  msg->next = target->msgqueue;
  target->msgqueue = msg;
  spinUnlock(&target->msgqueuelock);
  if (queueempty) {
    COBJ_EBBCALL(theEventMgrPrimId, dispatchIPI, target->eventLoc);
  }
  return EBBRC_OK;
}
Beispiel #13
0
void PIEventRegistry::ValidateSystemRegistry()
{
	// if there's already a registry, just return
	if (pTheRegistry.get())
		return;
	SpinLockFlag	lock;			// important that we're threadsafe!
	SystemSpinLock	spinLock(lock);
	PIEventRegistry *pRegistry = new PIEventRegistry();
	// if ever this routine is added to, the assignment to
	// the global has to be the last thing we do, 'cause the
	// check for pTheRegistry's existance is not thread-safed.
	// It's not threadsafe so that calling this isn't unduly
	// expensive, but it means that the assignment of the
	// registry pointer has to be atomic, and the last thing
	// we do.  (wow, a comment longer than the routine. sigh.)
	pTheRegistry = pRegistry;
}
Beispiel #14
0
void PIEventRegistry::SendEvent(PIEvent const &rEvent, PIEventHandler *pDestination, PIEventHandler *pOrigin)
{
	ValidateSystemRegistry();
#if _DEBUG || defined (DEBUG)
	{
	// this part needs to be thread-safed, but the call to the destination's code does not.
	// and since this only gets checked in debug mode, the lock only happens in debug mode.
		SystemSpinLock	spinLock(pTheRegistry->mLock);	// make thread safe
		// in debug mode, ensure the destination is valid
		assert(pTheRegistry->mHandlers.find(pDestination) != pTheRegistry->mHandlers.end());
		if (pOrigin) {
		// and if there's an origin, make sure it's valid, too
			assert(pTheRegistry->mHandlers.find(pOrigin) != pTheRegistry->mHandlers.end());
		}
	}
#endif
	pDestination->ProcessEvent(&rEvent, pOrigin);
}
void CAGCEventDef::Terminate()
{
  TCSimpleLock spinLock(s_nInitSync);
  TCObjectLock<TCSimpleLock> lock(&spinLock);
  if (!s_bInitialized)
    return;

  // Free each BSTR in the name map
  for (XNameMapIt it = s_pNameMap->begin(); it != s_pNameMap->end(); ++it)
  {
    const XEventDef* itFind = find(it->second);
    assert(itFind != end());
    if (!HIWORD(reinterpret_cast<DWORD>(itFind->m_pszName)))
      SysFreeString(const_cast<BSTR>(it->first));
  }
  delete s_pNameMap;
  s_pNameMap = NULL;
  s_bInitialized = false;
}
Beispiel #16
0
PIEventRegistry::~PIEventRegistry()
{
	try {
		// OK, this is way paranoid, but you never know...
		assert(pTheRegistry.get() == this);

		SystemSpinLock	spinLock(pTheRegistry->mLock);	// make thread safe
		// the desructing flag is used so the Unregsiter method won't
		// block on the already-held (above) spinlock
		mDestructing = true;
		// make sure nobody still thinks they're registered...
		// yes, this looks odd, but it is correct.  Unregister
		// removes the item from the list...
		while (mHandlers.begin() != mHandlers.end()) {
			mHandlers.begin()->first->UnregisterEvents();
		}
		// clear the system registry pointer
		//	pTheRegistry = 0;
	} catch (std::exception x) {
		// never throw from a destructor (except bus errors and junk like that)
	}
}
void CAGCEventDef::Initialize()
{
  TCSimpleLock spinLock(s_nInitSync);
  TCObjectLock<TCSimpleLock> lock(&spinLock);
  if (s_bInitialized)
    return;

  // Map all of the event names to ID's
  s_pNameMap = new XNameMap;
  for (const XEventDef* it = begin(); end() != it; ++it)
  {
    if (HIWORD(reinterpret_cast<DWORD>(it->m_pszName)))
      (*s_pNameMap)[it->m_pszName] = it->m_id;
    else
    {
      BSTR bstrName;
      ZSucceeded(GetString(it->m_pszName, &bstrName));
      (*s_pNameMap)[bstrName] = it->m_id;
    }
  }
  s_bInitialized = true;
}
Beispiel #18
0
// static functions:
PIEventHandler* PIEventRegistry::GetNamedEventHandler(std::string const &rString)
{
	SystemSpinLock	spinLock(pTheRegistry->mLock);	// make thread safe
	return(pTheRegistry->NamedEventHandler(rString));
}
Beispiel #19
0
BOOL
OSUninterruptibleSpinLock_Acquire(OSSpinLock *spinlock)
{
   spinLock(spinlock);
   return TRUE;
}