single thread tick loop maxtick: tick number after which to stop processing, or -1 to process until all components report EOI
| 1414 | // single thread tick loop |
| 1415 | // maxtick: tick number after which to stop processing, or -1 to process until all components report EOI |
| 1416 | long long cComponentManager::runSingleThreaded(long long maxtick) |
| 1417 | { |
| 1418 | if (!ready) return 0; |
| 1419 | SMILE_MSG(2,"starting single thread processing loop"); |
| 1420 | |
| 1421 | #ifdef __WINDOWS |
| 1422 | // set priority of current thread here... |
| 1423 | SetThreadPriority(GetCurrentThread(), threadPriority); |
| 1424 | #endif |
| 1425 | |
| 1426 | bool exitOuterTickLoop = false; |
| 1427 | long long tickNr = -1; |
| 1428 | bool firstTickAfterEOIReset = false; |
| 1429 | |
| 1430 | do { // outer tick loop |
| 1431 | long lastNRun = -1; |
| 1432 | |
| 1433 | while (true) { // inner tick loop |
| 1434 | tickNr++; |
| 1435 | |
| 1436 | // perform tick for all components |
| 1437 | SMILE_DBG(4,"<------- TICK # %lld ---------->", tickNr); |
| 1438 | |
| 1439 | long tickResultCounts[NUM_TICK_RESULTS]; |
| 1440 | tick(-1, tickNr, lastNRun, tickResultCounts); |
| 1441 | |
| 1442 | long nRun = tickResultCounts[TICK_SUCCESS]; |
| 1443 | long nWaiting = tickResultCounts[TICK_EXT_SOURCE_NOT_AVAIL] + tickResultCounts[TICK_EXT_DEST_NO_SPACE]; |
| 1444 | lastNRun = nRun; |
| 1445 | |
| 1446 | if (execDebug) { |
| 1447 | SMILE_MSG(3, "after tick(): nRun == %i, tickNr = %i", nRun, tickNr); |
| 1448 | } |
| 1449 | |
| 1450 | bool exitTickLoop = false; |
| 1451 | if (nRun > 0) { |
| 1452 | // at least one component performed work, continue tick loop |
| 1453 | } else { |
| 1454 | // No component performed work. There are currently two ways for components to defer EOI and report to |
| 1455 | // the component manager that they might have more data to process in the future. |
| 1456 | // 1. cSmileComponent::notifyEmptyTickloop. Components are expected to sleep in this method and thus |
| 1457 | // potentially block other components from running. |
| 1458 | // 2. cSmileComponent::signalDataAvailable. Uses a single conditional variable shared by all components |
| 1459 | // to signal the availability of data. The tick loop is only blocked if no other component performed any |
| 1460 | // work. This mechanism should be used by all new components. |
| 1461 | |
| 1462 | // check if any component is waiting for more data |
| 1463 | // this function will block or sleep in components that are waiting |
| 1464 | int nWaiting2 = componentOnEmptyTickloop(-1, tickNr); |
| 1465 | if (nWaiting2 > 0) { |
| 1466 | // at least one component is waiting for data, continue tick loop |
| 1467 | SMILE_DBG(4,"%i component(s) could not run because they were waiting for data. Continuing tick loop now.", nWaiting2); |
| 1468 | } else { |
| 1469 | if (nWaiting > 0) { |
| 1470 | // at least one component is waiting for data, block, then continue tick loop |
| 1471 | SMILE_DBG(4,"%i component(s) could not run because they are waiting for data. Blocking until new data is available.", nWaiting); |
| 1472 | smileCondWait(dataAvailableCond); |
| 1473 | } else { |
nothing calls this directly
no test coverage detected