1 #ifndef __MULTYPROCDIV_H__
2 #define __MULTYPROCDIV_H__
8 #define thrWriteToTrace0(mac_param0,mac_param1) \
9 _RPT0(mac_param0,mac_param1)
10 #define thrWriteToTrace1(mac_param0,mac_param1,mac_param2) \
11 _RPT1(mac_param0,mac_param1,mac_param2)
12 #define thrWriteToTrace2(mac_param0,mac_param1,mac_param2,mac_param3) \
13 _RPT2(mac_param0,mac_param1,mac_param2,mac_param3)
14 #define thrWriteToTrace3(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4) \
15 _RPT3(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4)
16 #define thrWriteToTrace4(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4,mac_param5) \
17 _RPT4(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4,mac_param5)
19 #define thrWriteToTrace0(mac_param0,mac_param1)
20 #define thrWriteToTrace1(mac_param0,mac_param1,mac_param2)
21 #define thrWriteToTrace2(mac_param0,mac_param1,mac_param2,mac_param3)
22 #define thrWriteToTrace3(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4)
23 #define thrWriteToTrace4(mac_param0,mac_param1,mac_param2,mac_param3,mac_param4,mac_param5)
26 #define NONE_FINISH_WORK -1
29 #define SET_CHILD_THREAD_PRIORITY(mac_handle) \
30 SetThreadPriority( mac_handle, THREAD_PRIORITY_BELOW_NORMAL )
32 #if(_WIN32_WINNT >= 0x0400)
33 #define SET_CHILD_THREAD_AFFINITY_MASK(mac_handle,mac_mask) \
34 SetThreadAffinityMask( mac_handle, mac_mask )
35 #define SET_CHILD_THREAD_IDEAL_PROCESSOR(mac_handle,mac_number) \
36 SetThreadIdealProcessor( mac_handle, (DWORD)mac_number )
38 #define SET_CHILD_THREAD_AFFINITY_MASK(mac_handle,mac_mask)
39 #define SET_CHILD_THREAD_IDEAL_PROCESSOR(mac_handle,mac_number)
42 #define COMMON_GLOBAL_VARS(mac_functionName,mac_inputStructType) \
43 CRITICAL_SECTION mac_functionName##CritSect; \
44 HANDLE mac_functionName##Event; \
45 volatile int mac_functionName##Message; \
46 HANDLE mac_functionName##ThreadHandle; \
47 mac_inputStructType mac_functionName##InputStruct
50 #define IS_THREAD_STILL_WORKING(mac_functionName) \
51 ( mac_functionName##ThreadHandle ? true : false )
53 #define INPUT_STRUCT_COMMON_PARAMS() \
59 #define ENTER_THREAD_CRITICAL_SECTION() \
60 EnterCriticalSection( criticalSection )
62 #define LEAVE_THREAD_CRITICAL_SECTION() \
63 LeaveCriticalSection( criticalSection )
65 #define childParams (thrParams[thrTaskNum])
67 #define INIT_CHILD_THREAD_PARAMS(mac_inputStructType,mac_threadMessage) \
68 mac_inputStructType* params = (mac_inputStructType*)param; \
69 int threadNum = params->threadNum; \
70 CRITICAL_SECTION* criticalSect; \
72 int* thrMessage = (int*)&mac_threadMessage; \
73 bool anotherThreadBlocksVar
75 #define BEGIN_CHILD_THREAD_FUNCTION(mac_functionName,mac_inputStructTypeForChild) \
76 DWORD mac_functionName##_child( LPVOID param ) \
78 INIT_CHILD_THREAD_PARAMS( mac_inputStructTypeForChild, \
79 mac_functionName##Message ); \
80 criticalSect = &mac_functionName##CritSect; \
81 event = mac_functionName##Event; \
82 thrWriteToTrace1( _CRT_WARN, "Thread #%d begins\n", threadNum )
84 #define BEGIN_CHILD_THREAD_CORE() \
85 InterlockedExchange( (long*)&(params->working), (long)true ); \
86 while( params->doNext ) \
88 thrWriteToTrace1( _CRT_WARN, "Thread #%d core begins\n", threadNum )
90 #define END_CHILD_THREAD_CORE() \
91 if( !params->doNext ) { \
94 thrWriteToTrace1( _CRT_WARN, "Thread #%d core ends\n", threadNum ); \
95 EnterCriticalSection( criticalSect ); \
96 params->doNext = false; \
97 anotherThreadBlocksVar = true; \
98 while( anotherThreadBlocksVar ) \
100 if( *thrMessage == NONE_FINISH_WORK ) { \
101 *thrMessage = threadNum; \
102 anotherThreadBlocksVar = false; \
105 LeaveCriticalSection( criticalSect ); \
107 EnterCriticalSection( criticalSect ); \
110 thrWriteToTrace1( _CRT_WARN, "Thread #%d sends message\n", threadNum );\
112 LeaveCriticalSection( criticalSect ); \
113 thrWriteToTrace1( _CRT_WARN, "Thread #%d suspends\n", threadNum ); \
114 SuspendThread( params->hThread ); \
116 thrWriteToTrace1( _CRT_WARN, "Thread #%d resumes\n", threadNum ); \
119 #define END_CHILD_THREAD_FUNCTION() \
120 thrWriteToTrace1( _CRT_WARN, "Thread #%d finishes\n", threadNum ); \
121 InterlockedExchange( (long*)&(params->working), (long)false ); \
125 #define EXIT_CTRL_THREAD(mac_threadHandle) \
126 thrWriteToTrace0( _CRT_WARN, "Control thread exits\n" ); \
127 if( eraseFunction ) { \
128 eraseFunction(params); \
130 CloseHandle( *event ); \
131 DeleteCriticalSection( criticalSect ); \
132 mac_threadHandle = 0; \
135 #define WAIT_SINGLE_OBJECT_CTRL() \
136 WaitForSingleObject( *event, INFINITE ); \
137 if( *thrMessage == BRAKE_WORK ) { \
139 thrWriteToTrace0( _CRT_WARN, "Control thread got exit message" ); \
140 for( j = 0; j < numProc; j ++ ) \
142 if( thrParams[j].working == true ) { \
143 thrParams[j].doNext = false; \
144 ResumeThread( hThread[j] ); \
148 for( j = 0; j < numProc; j ++ ) \
151 if( thrParams[j].working == true ) \
154 if( termRes = TerminateThread( hThread[j], 1 ) ) \
156 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, \
158 thrWriteToTrace1( _CRT_WARN, "TerminateThread returned: %s\n", \
162 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, \
164 thrWriteToTrace1( _CRT_WARN, "TerminateThread returned: %s\n", \
167 WaitForSingleObject( hThread[j], 1000 ); \
170 EXIT_CTRL_THREAD(*thisThreadHandle); \
173 #define BEGIN_CTRL_THREAD_FUNCTION(mac_functionName,mac_inputStructType,mac_inputStructTypeForChild,\
174 mac_eraseFunction,mac_beginFunction,mac_endFunction) \
175 DWORD mac_functionName##_ctrl( LPVOID param ) \
177 mac_inputStructType* params = (mac_inputStructType*)param; \
178 SYSTEM_INFO sysInfo; \
180 DWORD dwThread[32]; \
181 HANDLE hThread[32]; \
182 mac_inputStructTypeForChild thrParams[32]; \
184 CRITICAL_SECTION* criticalSect = &mac_functionName##CritSect; \
185 HANDLE* event = &mac_functionName##Event; \
186 HANDLE* thisThreadHandle = &mac_functionName##ThreadHandle; \
188 LPTHREAD_START_ROUTINE childFunction = (LPTHREAD_START_ROUTINE)mac_functionName##_child; \
190 int* thrMessage = (int*)&mac_functionName##Message; \
191 bool (*eraseFunction)( void* ) = ( bool (*)( void* ) )mac_eraseFunction; \
192 bool (*beginFunction)( void* ) = ( bool (*)( void* ) )mac_beginFunction; \
193 bool (*endFunction)( void* ) = ( bool (*)( void* ) )mac_endFunction; \
195 thrWriteToTrace0( _CRT_WARN, "Control thread begins\n" )
197 #define BEGIN_CTRL_THREAD_CORE(mac_tasksNum) \
198 tasksNum = mac_tasksNum; \
199 InitializeCriticalSection( criticalSect ); \
200 *event = CreateEvent( 0, true, false, NULL ); \
201 GetSystemInfo( &sysInfo ); \
202 numProc = sysInfo.dwNumberOfProcessors; \
203 if( numProc > 32 ) { \
204 EXIT_CTRL_THREAD( *thisThreadHandle ); \
206 if( beginFunction ) { \
207 beginFunction( params ); \
209 *thrMessage = NONE_FINISH_WORK; \
210 for( i = 0; i <= tasksNum; i ++ ) \
214 thrWriteToTrace2( _CRT_WARN, "Control thread gives task #%d to" \
215 " thread #%d\n", i, thrTaskNum )
219 #define END_CTRL_THREAD_CORE() \
220 thrParams[thrTaskNum].doNext = true; \
221 thrWriteToTrace1( _CRT_WARN, "Control thread resumes thread #%d\n", \
223 while( !ResumeThread( hThread[thrTaskNum] ) ) Sleep(0); \
226 if( i < tasksNum ) { \
227 if( i < numProc ) { \
228 thrParams[i].threadNum = i; \
229 thrParams[i].working = true; \
230 thrWriteToTrace0( _CRT_WARN, "Control thread creates child" \
232 hThread[i] = CreateThread( NULL, 0, childFunction, \
233 &(thrParams[i]), CREATE_SUSPENDED, &(dwThread[i]) ); \
234 thrParams[i].hThread = hThread[i]; \
235 thrParams[i].doNext = false; \
236 SET_CHILD_THREAD_PRIORITY( hThread[i] ); \
237 SET_CHILD_THREAD_AFFINITY_MASK( hThread[i], affMask ); \
238 SET_CHILD_THREAD_IDEAL_PROCESSOR( hThread[i], (DWORD)i ); \
242 thrWriteToTrace0( _CRT_WARN, "Control thread waits for a message\n" ); \
243 WAIT_SINGLE_OBJECT_CTRL(); \
244 EnterCriticalSection( criticalSect ); \
245 ResetEvent( *event ); \
246 thrTaskNum = *thrMessage; \
247 thrWriteToTrace1( _CRT_WARN, "Control thread got a message" \
248 " from thread #%d\n", thrTaskNum ); \
249 thrParams[thrTaskNum].doNext = true; \
250 *thrMessage = NONE_FINISH_WORK; \
251 LeaveCriticalSection( criticalSect ); \
255 thrWriteToTrace0( _CRT_WARN, "Control thread waits for finishing all" \
257 for( i = tasksNum; i < numProc; i ++ ) { \
258 thrParams[i].doNext = false; \
259 ResumeThread( hThread[i] ); \
260 WaitForSingleObject( hThread[i], INFINITE ); \
262 for( i = 0; i < numProc; i ++ ) \
264 thrWriteToTrace0( _CRT_WARN, "Control thread waits for message\n" ); \
265 WAIT_SINGLE_OBJECT_CTRL(); \
266 EnterCriticalSection( criticalSect ); \
267 ResetEvent( *event ); \
268 thrTaskNum = *thrMessage; \
269 thrWriteToTrace1( _CRT_WARN, "Control thread got last message from" \
270 " thread #%d\n", thrTaskNum ); \
271 thrParams[thrTaskNum].doNext = false; \
272 *thrMessage = NONE_FINISH_WORK; \
273 while( !ResumeThread( hThread[thrTaskNum] ) ) Sleep(0); \
274 LeaveCriticalSection( criticalSect ); \
275 WaitForSingleObject( hThread[thrTaskNum], INFINITE ); \
278 #define END_CTRL_THREAD_FUNCTION() \
279 thrWriteToTrace0( _CRT_WARN, "Control thread is getting normal finishing\n" ); \
280 if( endFunction ) { \
281 endFunction( params ); \
283 CloseHandle( *event ); \
284 DeleteCriticalSection( criticalSect ); \
285 *thisThreadHandle = 0; \
289 #define DEFINE_START_THREAD_FUNCTION(mac_functionName,mac_inputParams) \
290 extern HANDLE mac_functionName##ThreadHandle; \
291 bool mac_functionName##mac_inputParams
293 #define BEGIN_START_THREAD_FUNCTION(mac_functionName,mac_inputParams, \
294 mac_inputStructType) \
295 bool mac_functionName##mac_inputParams \
297 static bool mac_functionName##StartsFirstTime = true; \
298 bool anotherThreadBlocksVar; \
299 mac_inputStructType* params = &mac_functionName##InputStruct; \
300 HANDLE* thrHandle = &mac_functionName##ThreadHandle; \
301 LPTHREAD_START_ROUTINE threadCtrlFunction = \
302 (LPTHREAD_START_ROUTINE)mac_functionName##_ctrl; \
303 thrWriteToTrace0( _CRT_WARN, "Start function begins\n" ); \
304 if( mac_functionName##StartsFirstTime ) { \
305 mac_functionName##StartsFirstTime = false; \
306 mac_functionName##ThreadHandle = 0; \
308 if( mac_functionName##ThreadHandle ) { \
309 EnterCriticalSection( &mac_functionName##CritSect ); \
310 anotherThreadBlocksVar = true; \
311 while( anotherThreadBlocksVar ) \
313 if( mac_functionName##Message == NONE_FINISH_WORK ) { \
314 mac_functionName##Message = BRAKE_WORK; \
315 anotherThreadBlocksVar = false; \
318 LeaveCriticalSection( &mac_functionName##CritSect ); \
320 EnterCriticalSection( &mac_functionName##CritSect ); \
323 thrWriteToTrace0( _CRT_WARN, "Main thread sets break event\n" ); \
324 SetEvent( mac_functionName##Event ); \
325 LeaveCriticalSection( &mac_functionName##CritSect ); \
329 #define END_START_THREAD_FUNCTION() \
330 *thrHandle = CreateThread( NULL, 0, \
331 (LPTHREAD_START_ROUTINE)threadCtrlFunction, params, 0, 0 ); \
332 SET_CHILD_THREAD_PRIORITY( *thrHandle ); \
334 thrWriteToTrace0( _CRT_WARN, "Start function ends\n" ); \
339 #endif // if !defined __MULTYPROCDIV_H__