Counter Strike : Global Offensive Source Code
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.

107 lines
2.7 KiB

  1. //========== Copyright � Valve Corporation, All rights reserved. ========
  2. #if !defined( VJOBPOOL_HDR ) && defined( _PS3 )
  3. #define VJOBPOOL_HDR
  4. #include "ps3/spu_job_shared.h"
  5. #include "cell/atomic.h"
  6. //#include "ps3/vjobutils.h"
  7. template < typename Job, uint nAlignment = 128 >
  8. class VjobPool
  9. {
  10. public:
  11. #ifndef SPU
  12. void Init( uint nJobs ) // must be integer-power-of-2
  13. {
  14. m_nJobIndexMask = nJobs - 1;
  15. Assert( !( m_nJobIndexMask & nJobs ) );
  16. uint nSizeToAllocate = sizeof( Job ) * nJobs;
  17. m_eaPool = ( Job* )MemAlloc_AllocAligned( nSizeToAllocate, nAlignment );
  18. V_memset( m_eaPool, 0, nSizeToAllocate );
  19. m_nNextJob = 0;
  20. m_nWaitSpins = 0;
  21. }
  22. void Shutdown()
  23. {
  24. // wait for all jobs to finish
  25. for ( uint i = 0; i <= m_nJobIndexMask; ++i )
  26. {
  27. volatile const uint64 * pEa = ( const uint64* ) & m_eaPool[i];
  28. while ( *pEa )
  29. {
  30. continue;
  31. }
  32. }
  33. MemAlloc_FreeAligned( m_eaPool );
  34. m_eaPool = NULL;
  35. }
  36. Job * Alloc( const CellSpursJobHeader & header ) // the job header is freed when its eaBinary is overwritten with zeroes from within the job
  37. {
  38. Job * pJob = Alloc();
  39. V_memcpy( pJob, &header, sizeof( header ) );
  40. return pJob;
  41. }
  42. #endif
  43. Job * Alloc( ); // the job header is freed when its eaBinary is overwritten with zeroes from within the job
  44. uint GetMarker()const { return m_nNextJob; }
  45. uint GetCapacity()const { return m_nJobIndexMask + 1; }
  46. int GetReserve( uint nMarker )const { return int( GetCapacity() - ( m_nNextJob - nMarker ) ); }
  47. public:
  48. uint m_nWaitSpins; // debug field
  49. protected:
  50. Job * m_eaPool;
  51. uint m_nJobIndexMask;
  52. // this is just a hint
  53. uint m_nNextJob;
  54. };
  55. template < typename Job, uint nAlignment >
  56. Job * VjobPool<Job, nAlignment>::Alloc( ) // the job header is freed when its eaBinary is overwritten with zeroes from within the job
  57. {
  58. uint nNextJob = m_nNextJob;
  59. Job * eaJob = NULL;
  60. for( ;; )
  61. {
  62. eaJob = &m_eaPool[ ( nNextJob & m_nJobIndexMask ) ];
  63. #ifdef SPU
  64. char ALIGN128 temp[128] ALIGN128_POST;
  65. // it's important to fill in and compare the first 64 bits, because that's where eaBinary is, and the first 32 bits (MSB) may be zero
  66. if( 0 == cellAtomicCompareAndSwap64( (uint64*)temp, ( uintp )eaJob, 0, ~0ull ) )
  67. {
  68. break;
  69. }
  70. ++m_nWaitSpins;
  71. #else
  72. // it's important to fill in and compare the first 64 bits, because that's where eaBinary is, and the first 32 bits (MSB) may be zero
  73. if( 0 == cellAtomicCompareAndSwap64( ( uint64* )eaJob, 0, ~0ull ) )
  74. {
  75. break;
  76. }
  77. if( ( ( ( ++nNextJob ) ^ m_nNextJob ) & m_nJobIndexMask ) == 0 )
  78. {
  79. // we've made the full circle; yield
  80. m_nWaitSpins++;
  81. sys_timer_usleep( 30 );
  82. }
  83. #endif
  84. }
  85. // this is just a hint
  86. m_nNextJob = nNextJob + 1;
  87. return eaJob;
  88. }
  89. #endif