BOOL OSAcquireSpinLock(OSSpinLock *spinlock) { OSTestThreadCancel(); spinLock(spinlock); return TRUE; }
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; }
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()); }
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; }
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); }
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; } }
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(); }
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; }
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); }
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; }
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); }
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; }
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; }
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; }
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; }
// static functions: PIEventHandler* PIEventRegistry::GetNamedEventHandler(std::string const &rString) { SystemSpinLock spinLock(pTheRegistry->mLock); // make thread safe return(pTheRegistry->NamedEventHandler(rString)); }
BOOL OSUninterruptibleSpinLock_Acquire(OSSpinLock *spinlock) { spinLock(spinlock); return TRUE; }