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