void SFXWrapAroundBuffer::write( SFXStreamPacket* const* packets, U32 num ) { AssertFatal( SFXInternal::isSFXThread(), "SFXWrapAroundBuffer::write() - not on SFX thread" ); for( U32 i = 0; i < num; ++ i ) { const SFXStreamPacket* packet = packets[ i ]; // Determine where in the buffer to copy the data to. In case we are crossing over // the wrap-around point, we need to copy in two slices. U32 offset1 = 0; U32 offset2 = 0; U32 numBytes1 = 0; U32 numBytes2 = 0; offset1 = mWriteOffset % mBufferSize; numBytes1 = packet->size; if( offset1 + numBytes1 > mBufferSize ) { // Crossing wrap-around point. numBytes1 = mBufferSize - offset1; numBytes2 = packet->size - numBytes1; } offset2 = offset1 + numBytes1; #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXWrapAroundBuffer] writing %i bytes from packet #%i at %i (stream offset: %i)", numBytes1, packet->mIndex, offset1, mWriteOffset ); #endif // Copy the packet data. _copyData( offset1, packet->data, numBytes1 ); if( numBytes2 > 0 ) { #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXWrapAroundBuffer] writing %i more bytes at %i", numBytes2, offset2 ); #endif _copyData( offset2, &packet->data[ numBytes1 ], numBytes2 ); } dFetchAndAdd( mWriteOffset, packet->size ); // Free the packet. destructSingle( packet ); } }
void UnitTest::warn(const char* msg) { Con::warnf("** Warning: %s",msg); dFetchAndAdd( _warningCount, 1 ); }
void UnitTest::fail(const char* msg) { Con::warnf("** Failed: %s",msg); dFetchAndAdd( _failureCount, 1 ); }
void ThreadPool::WorkerThread::run( void* arg ) { #ifdef TORQUE_DEBUG { // Set the thread's name for debugging. char buffer[ 2048 ]; dSprintf( buffer, sizeof( buffer ), "ThreadPool(%s) WorkerThread %i", mPool->mName.c_str(), mIndex ); _setName( buffer ); } #endif #if defined(TORQUE_OS_XENON) // On Xbox 360 you must explicitly assign software threads to hardware threads. // This will distribute job threads across the secondary CPUs leaving both // primary CPU cores available to the "main" thread. This will help prevent // more L2 thrashing of the main thread/core. static U32 sCoreAssignment = 2; XSetThreadProcessor( GetCurrentThread(), sCoreAssignment ); sCoreAssignment = sCoreAssignment < 6 ? sCoreAssignment + 1 : 2; #endif while( 1 ) { if( checkForStop() ) { #ifdef DEBUG_SPEW Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' exits", getId() ); #endif dFetchAndAdd( mPool->mNumThreads, ( U32 ) -1 ); return; } // Mark us as potentially blocking. dFetchAndAdd( mPool->mNumThreadsReady, ( U32 ) -1 ); bool waitForSignal = false; { // Try to take an item from the queue. Do // this in a separate block, so we'll be // releasing the item after we have finished. WorkItemWrapper workItem; if( mPool->mWorkItemQueue.takeNext( workItem ) ) { // Mark us as non-blocking as this loop definitely // won't wait on the semaphore. dFetchAndAdd( mPool->mNumThreadsReady, 1 ); #ifdef DEBUG_SPEW Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' takes item '0x%x'", getId(), *workItem ); #endif workItem->process(); } else waitForSignal = true; } if( waitForSignal ) { dFetchAndAdd( mPool->mNumThreadsAwake, ( U32 ) -1 ); #ifdef DEBUG_SPEW Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' going to sleep", getId() ); #endif mPool->mSemaphore.acquire(); #ifdef DEBUG_SPEW Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' waking up", getId() ); #endif dFetchAndAdd( mPool->mNumThreadsAwake, 1 ); dFetchAndAdd( mPool->mNumThreadsReady, 1 ); } } }