| 230 | } |
| 231 | |
| 232 | void ThreadPool::WorkerThread::run( void* arg ) |
| 233 | { |
| 234 | #ifdef TORQUE_DEBUG |
| 235 | { |
| 236 | // Set the thread's name for debugging. |
| 237 | char buffer[ 2048 ]; |
| 238 | dSprintf( buffer, sizeof( buffer ), "ThreadPool(%s) WorkerThread %i", mPool->mName.c_str(), mIndex ); |
| 239 | _setName( buffer ); |
| 240 | } |
| 241 | #endif |
| 242 | |
| 243 | #if defined(TORQUE_OS_XENON) |
| 244 | // On Xbox 360 you must explicitly assign software threads to hardware threads. |
| 245 | |
| 246 | // This will distribute job threads across the secondary CPUs leaving both |
| 247 | // primary CPU cores available to the "main" thread. This will help prevent |
| 248 | // more L2 thrashing of the main thread/core. |
| 249 | static U32 sCoreAssignment = 2; |
| 250 | XSetThreadProcessor( GetCurrentThread(), sCoreAssignment ); |
| 251 | sCoreAssignment = sCoreAssignment < 6 ? sCoreAssignment + 1 : 2; |
| 252 | #endif |
| 253 | |
| 254 | while( 1 ) |
| 255 | { |
| 256 | if( checkForStop() ) |
| 257 | { |
| 258 | #ifdef DEBUG_SPEW |
| 259 | Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' exits", getId() ); |
| 260 | #endif |
| 261 | dFetchAndAdd( mPool->mNumThreads, ( U32 ) -1 ); |
| 262 | return; |
| 263 | } |
| 264 | |
| 265 | // Mark us as potentially blocking. |
| 266 | dFetchAndAdd( mPool->mNumThreadsReady, ( U32 ) -1 ); |
| 267 | |
| 268 | bool waitForSignal = false; |
| 269 | { |
| 270 | // Try to take an item from the queue. Do |
| 271 | // this in a separate block, so we'll be |
| 272 | // releasing the item after we have finished. |
| 273 | |
| 274 | WorkItemWrapper workItem; |
| 275 | if( mPool->mWorkItemQueue.takeNext( workItem ) ) |
| 276 | { |
| 277 | // Mark us as non-blocking as this loop definitely |
| 278 | // won't wait on the semaphore. |
| 279 | dFetchAndAdd( mPool->mNumThreadsReady, 1 ); |
| 280 | |
| 281 | #ifdef DEBUG_SPEW |
| 282 | Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' takes item '0x%x'", getId(), *workItem ); |
| 283 | #endif |
| 284 | workItem->process(); |
| 285 | |
| 286 | dFetchAndAdd( mPool->mNumPendingItems, ( U32 ) -1 ); |
| 287 | } |
| 288 | else |
| 289 | waitForSignal = true; |