void NKern::MoveUserModeCallbacks(NThreadBase* aDestThread, NThreadBase* aSrcThread) { // Move all queued user-mode callbacks from the source thread to the destination thread, and // prevent any more from being queued. Used by the kernel thread code so that callbacks get // cancelled in another thread if the thread they were originally queued on dies. // Atomically remove list of callbacks and set pointer to 1 // The latter ensures any subsequent attempts to add callbacks fail TUserModeCallback* sourceListStart = (TUserModeCallback*)__e32_atomic_swp_ord_ptr(&aSrcThread->iUserModeCallbacks, (TAny*)1); __NK_ASSERT_DEBUG(((TUint)sourceListStart & 3) == 0); // check this only gets called once per thread if (sourceListStart == NULL) return; TUserModeCallback* sourceListEnd = sourceListStart; while (sourceListEnd->iNext != NULL) sourceListEnd = sourceListEnd->iNext; NKern::Lock(); TUserModeCallback* destListStart = aDestThread->iUserModeCallbacks; do { __NK_ASSERT_DEBUG(((TUint)destListStart & 3) == 0); // dest thread must not die sourceListEnd->iNext = destListStart; } while (!__e32_atomic_cas_ord_ptr(&aDestThread->iUserModeCallbacks, &destListStart, sourceListStart)); NKern::Unlock(); }
EXPORT_C void TAsyncRequest::Complete(TInt aResult) { TLinAddr signal = (TLinAddr)__e32_atomic_swp_ord_ptr(&iCompletionObject, 0); if(signal) { iResult = aResult; if(signal&1) ((TDfc*)(signal&~1))->Enque(); else NKern::FSSignal((NFastSemaphore*)signal); } }
void DPowerHandler::Done() { // private #ifdef _DEBUG_POWER __PM_ASSERT(!(iStatus & EDone)); iStatus |= EDone; #endif NKern::Lock(); __KTRACE_OPT(KPOWER,Kern::Printf("DPowerHandler::Done('%S') sem=0x%x", &iName, iSem)); NFastSemaphore* sem = (NFastSemaphore*)__e32_atomic_swp_ord_ptr(&iSem, 0); if (sem) sem->Signal(); NKern::Unlock(); }
void NKern::CancelUserModeCallbacks() { // Call any queued callbacks with the EUserModeCallbackCancel reason code, in the current // thread. TUserModeCallback* listHead = (TUserModeCallback*)__e32_atomic_swp_ord_ptr(&NCurrentThread()->iUserModeCallbacks, NULL); while (listHead) { TUserModeCallback* callback = listHead; listHead = listHead->iNext; callback->iNext = KUserModeCallbackUnqueued; __e32_memory_barrier(); callback->iFunc(callback, EUserModeCallbackCancel); } }
Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) { return __e32_atomic_swp_ord_ptr(_q_value, newValue); }