threadmisc.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. static inline bool CriticalSectionCreate(CRITSECT_HANDLE *CritSection)
  2. {
  3. #ifdef _WIN_ALL
  4. InitializeCriticalSection(CritSection);
  5. return true;
  6. #elif defined(_UNIX)
  7. return pthread_mutex_init(CritSection,NULL)==0;
  8. #endif
  9. }
  10. static inline void CriticalSectionDelete(CRITSECT_HANDLE *CritSection)
  11. {
  12. #ifdef _WIN_ALL
  13. DeleteCriticalSection(CritSection);
  14. #elif defined(_UNIX)
  15. pthread_mutex_destroy(CritSection);
  16. #endif
  17. }
  18. static inline void CriticalSectionStart(CRITSECT_HANDLE *CritSection)
  19. {
  20. #ifdef _WIN_ALL
  21. EnterCriticalSection(CritSection);
  22. #elif defined(_UNIX)
  23. pthread_mutex_lock(CritSection);
  24. #endif
  25. }
  26. static inline void CriticalSectionEnd(CRITSECT_HANDLE *CritSection)
  27. {
  28. #ifdef _WIN_ALL
  29. LeaveCriticalSection(CritSection);
  30. #elif defined(_UNIX)
  31. pthread_mutex_unlock(CritSection);
  32. #endif
  33. }
  34. static THREAD_HANDLE ThreadCreate(NATIVE_THREAD_PTR Proc,void *Data)
  35. {
  36. #ifdef _UNIX
  37. /*
  38. pthread_attr_t attr;
  39. pthread_attr_init(&attr);
  40. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  41. */
  42. pthread_t pt;
  43. int Code=pthread_create(&pt,NULL/*&attr*/,Proc,Data);
  44. if (Code!=0)
  45. {
  46. wchar Msg[100];
  47. swprintf(Msg,ASIZE(Msg),L"\npthread_create failed, code %d\n",Code);
  48. ErrHandler.GeneralErrMsg(Msg);
  49. ErrHandler.SysErrMsg();
  50. ErrHandler.Exit(RARX_FATAL);
  51. }
  52. return pt;
  53. #else
  54. DWORD ThreadId;
  55. HANDLE hThread=CreateThread(NULL,0x10000,Proc,Data,0,&ThreadId);
  56. if (hThread==NULL)
  57. {
  58. ErrHandler.GeneralErrMsg(L"CreateThread failed");
  59. ErrHandler.SysErrMsg();
  60. ErrHandler.Exit(RARX_FATAL);
  61. }
  62. return hThread;
  63. #endif
  64. }
  65. static void ThreadClose(THREAD_HANDLE hThread)
  66. {
  67. #ifdef _UNIX
  68. pthread_join(hThread,NULL);
  69. #else
  70. CloseHandle(hThread);
  71. #endif
  72. }
  73. #ifdef _WIN_ALL
  74. static void CWaitForSingleObject(HANDLE hHandle)
  75. {
  76. DWORD rc=WaitForSingleObject(hHandle,INFINITE);
  77. if (rc==WAIT_FAILED)
  78. {
  79. ErrHandler.GeneralErrMsg(L"\nWaitForMultipleObjects error %d, GetLastError %d",rc,GetLastError());
  80. ErrHandler.Exit(RARX_FATAL);
  81. }
  82. }
  83. #endif
  84. #ifdef _UNIX
  85. static void cpthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
  86. {
  87. int rc=pthread_cond_wait(cond,mutex);
  88. if (rc!=0)
  89. {
  90. ErrHandler.GeneralErrMsg(L"\npthread_cond_wait error %d",rc);
  91. ErrHandler.Exit(RARX_FATAL);
  92. }
  93. }
  94. #endif
  95. uint GetNumberOfCPU()
  96. {
  97. #ifndef RAR_SMP
  98. return 1;
  99. #else
  100. #ifdef _UNIX
  101. #ifdef _SC_NPROCESSORS_ONLN
  102. uint Count=(uint)sysconf(_SC_NPROCESSORS_ONLN);
  103. return Count<1 ? 1:Count;
  104. #elif defined(_APPLE)
  105. uint Count;
  106. size_t Size=sizeof(Count);
  107. return sysctlbyname("hw.ncpu",&Count,&Size,NULL,0)==0 ? Count:1;
  108. #endif
  109. #else // !_UNIX
  110. DWORD_PTR ProcessMask;
  111. DWORD_PTR SystemMask;
  112. if (!GetProcessAffinityMask(GetCurrentProcess(),&ProcessMask,&SystemMask))
  113. return 1;
  114. uint Count=0;
  115. for (DWORD_PTR Mask=1;Mask!=0;Mask<<=1)
  116. if ((ProcessMask & Mask)!=0)
  117. Count++;
  118. return Count<1 ? 1:Count;
  119. #endif
  120. #endif // RAR_SMP
  121. }
  122. uint GetNumberOfThreads()
  123. {
  124. uint NumCPU=GetNumberOfCPU();
  125. if (NumCPU<1)
  126. return 1;
  127. if (NumCPU>MaxPoolThreads)
  128. return MaxPoolThreads;
  129. return NumCPU;
  130. }