static MojErr MojThreadTestFn(void* arg) { static MojThreadLocalValue<int, MojThreadLocalValueZeroCtor<int> > s_localVal; MojThreadTestArgs* targs = (MojThreadTestArgs*) arg; MojTestAssert(targs); for (int i = 0; i < MojTestNumIterations; ++i) { targs->m_atomicCounter.increment(); MojThreadGuard guard(targs->m_mutex, false); if (!guard.tryLock()) guard.lock(); ++(targs->m_counter); if (targs->m_counter == (MojTestNumThreads * MojTestNumIterations)) { MojErr err = targs->m_countCond.signal(); MojTestErrCheck(err); } } MojErr err = MojThreadYield(); MojTestErrCheck(err); MojThreadGuard guard(targs->m_mutex); while (targs->m_wait) { err = targs->m_waitCond.wait(targs->m_mutex); MojTestErrCheck(err); } guard.unlock(); int* localVal = NULL; err = s_localVal.get(localVal); MojTestErrCheck(err); MojTestAssert(localVal && *localVal == 0); for (int i = 0; i < MojTestNumIterations; ++i) { ++(*localVal); targs->m_atomicCounter.decrement(); { MojThreadReadGuard readGuard(targs->m_rwlock); MojTestAssert(targs->m_counter > 0); } MojThreadReadGuard readGuard(targs->m_rwlock, false); if (!readGuard.tryLock()) readGuard.lock(); MojTestAssert(targs->m_counter > 0); readGuard.unlock(); { MojThreadWriteGuard writeGuard(targs->m_rwlock); ++(targs->m_counter); } MojThreadWriteGuard writeGuard(targs->m_rwlock, false); if (!writeGuard.tryLock()) writeGuard.lock(); targs->m_counter -= 2; } MojTestAssert(*localVal == MojTestNumIterations); return MojErrNone; }
int MojLogTracer::indentLevel(int inc) { static MojThreadLocalValue<int, MojThreadLocalValueZeroCtor<int> > s_level; int *level = NULL; MojErr err = s_level.get(level); MojErrCatchAllNoLog(err) { return 0; } int curVal = *level; *level += inc; return curVal; }