Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.5 KiB

  1. //====== Copyright (c), Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Implements parallel job farming process
  4. //
  5. //=============================================================================
  6. #include "stdafx.h"
  7. #include "rtime.h"
  8. #include "gcparalleljobfarm.h"
  9. namespace GCSDK
  10. {
  11. bool IYieldingParallelFarmJobHandler::BYieldingExecuteParallel( int numJobsParallel, char const *pchJobName, uint nTimeoutSec )
  12. {
  13. AssertRunningJob();
  14. if ( !pchJobName )
  15. pchJobName = GJobCur().GetName();
  16. struct CParallelFarmHeapData_t
  17. {
  18. explicit CParallelFarmHeapData_t( IYieldingParallelFarmJobHandler *pHandler, int numJobsFarmLimit )
  19. {
  20. m_pHandler = pHandler;
  21. m_jobIdParent = GJobCur().GetJobID();
  22. m_numJobsFarmed = 0;
  23. m_numJobsFarmLimit = MAX( 1, numJobsFarmLimit );
  24. m_iJobSequenceCounter = 0;
  25. m_bErrorEncountered = false;
  26. m_bWorkloadCompleted = false;
  27. }
  28. IYieldingParallelFarmJobHandler *m_pHandler;
  29. JobID_t m_jobIdParent;
  30. int m_numJobsFarmLimit;
  31. int m_numJobsFarmed;
  32. int m_iJobSequenceCounter;
  33. bool m_bErrorEncountered;
  34. bool m_bWorkloadCompleted;
  35. };
  36. CParallelFarmHeapData_t *pHeapData = new CParallelFarmHeapData_t( this, numJobsParallel );
  37. class CYieldingParallelFarmJob : public CGCJob
  38. {
  39. public:
  40. CYieldingParallelFarmJob( CGCBase *pGC, CParallelFarmHeapData_t *pJobData, char const *pchJobName, uint nTimeoutSec ) : CGCJob( pGC, pchJobName )
  41. , m_pJobData( pJobData ), m_iJobSequenceCounter( pJobData->m_iJobSequenceCounter ), m_nTimeoutSec( nTimeoutSec )
  42. {
  43. }
  44. virtual bool BYieldingRunJob( void *pvStartParam )
  45. {
  46. if ( m_nTimeoutSec )
  47. SetJobTimeout( m_nTimeoutSec );
  48. bool bWorkloadCompleted = false;
  49. bool bResult = m_pJobData->m_pHandler
  50. ? m_pJobData->m_pHandler->BYieldingRunWorkload( m_iJobSequenceCounter, &bWorkloadCompleted )
  51. : false;
  52. if ( !bResult )
  53. m_pJobData->m_bErrorEncountered = true;
  54. else if ( bWorkloadCompleted )
  55. m_pJobData->m_bWorkloadCompleted = true;
  56. -- m_pJobData->m_numJobsFarmed;
  57. if ( !m_pJobData->m_bErrorEncountered && !m_pJobData->m_bWorkloadCompleted )
  58. {
  59. CYieldingParallelFarmJob *pFarmedJob = new CYieldingParallelFarmJob( m_pGC, m_pJobData, GetName(), m_nTimeoutSec );
  60. ++ m_pJobData->m_numJobsFarmed;
  61. ++ m_pJobData->m_iJobSequenceCounter;
  62. pFarmedJob->StartJobDelayed( NULL );
  63. }
  64. if ( !m_pJobData->m_numJobsFarmed )
  65. { // No more farmed jobs to wait for
  66. m_pGC->GetJobMgr().BRouteWorkItemCompletedDelayed( m_pJobData->m_jobIdParent, false );
  67. }
  68. return bResult;
  69. }
  70. protected:
  71. CParallelFarmHeapData_t *m_pJobData;
  72. int m_iJobSequenceCounter;
  73. uint m_nTimeoutSec;
  74. };
  75. for ( ; ; ++ pHeapData->m_iJobSequenceCounter )
  76. {
  77. if ( pHeapData->m_numJobsFarmed < pHeapData->m_numJobsFarmLimit )
  78. {
  79. CYieldingParallelFarmJob *pFarmedJob = new CYieldingParallelFarmJob( GGCBase(), pHeapData, pchJobName, nTimeoutSec );
  80. ++ pHeapData->m_numJobsFarmed;
  81. pFarmedJob->StartJobDelayed( NULL );
  82. }
  83. else
  84. {
  85. if ( !GJobCur().BYieldingWaitForWorkItem( pchJobName ) )
  86. {
  87. EmitError( SPEW_GC, "YieldingExecuteParallel: failed to sync with %u farmed work items.\n", pHeapData->m_numJobsFarmed );
  88. pHeapData->m_bErrorEncountered = true;
  89. pHeapData->m_pHandler = NULL; // handler itself may become invalid when the function returns
  90. return false; // leak pHeapData because work items might still be running and this can avoid a crash (this condition is abnormal)
  91. }
  92. break;
  93. }
  94. }
  95. bool bResult = pHeapData->m_bWorkloadCompleted && !pHeapData->m_bErrorEncountered;
  96. delete pHeapData;
  97. return bResult;
  98. }
  99. }