5 #endif /* HAVE_CONFIG_H */
13 #endif /* HAVE_STDLIB_H */
26 #endif /* HAVE_PTHREAD_H */
27 #ifdef HAVE_PTHREADS_H
29 #endif /* HAVE_PTHREADS_H */
32 #endif /* HAVE_UNISTD_H */
49 win
\88È
\8aO
\82Ìunix/linux/mac
\93\99\82Å
\82Íposix
51 Win
\82Å
\82Ì
\83X
\83\8c\83b
\83h
\8d\
\91¢
\83e
\83X
\83g
52 test1
\96\88\89ñbeginthread
\94ñ
\8fí
\82É
\92x
\82¢
53 test2
\96\88\89ñResumeThread/SuspendThread
\91½
\83X
\83\8c\83b
\83h
\82Å
\92x
\82¢ Sleep
\83\8b\81[
\83v
\82É
\82æ
\82é
\95s
\97v
\82È
\8bó
\89ñ
\82è
\82ª
\82ÅCPU
\95\89\89×
\8d\82\82¢
54 test3
\82¸
\82Á
\82Æ
\83X
\83\8c\83b
\83h
\89ñ
\82µ
\82Á
\82Ï
\82È
\82µ
\82â
\82â
\92x
\82¢
\93®
\8dì
\82ª
\89ö
\82µ
\82¢
\83{
\83c
55 test4
\8dÄ
\90¶
\92\86\82Ü
\82í
\82µ
\82Á
\82Ï
\82È
\82µ
\88ê
\92è
\8e\9e\8aÔ
\8cã
\83X
\83\8c\83b
\83h
\8fI
\97¹ CPU
\83X
\83\8c\83b
\83h
\90\94\82Ì
\82Æ
\82«
\92x
\82
\82È
\82é (
\83R
\83\93\83g
\83\8d\81[
\83\8b\97p
\83X
\83\8c\83b
\83h
\92Ç
\89Á
\82Ì
\95ª CPU
\83X
\83\8c\83b
\83h
\90\94\82æ
\82è
\8eÀ
\8ds
\83X
\83\8c\83b
\83h
\82ª
\91½
\82
\82È
\82é
56 test5 Event
\82Å
\83X
\83\8c\83b
\83h
\82ð
\83R
\83\93\83g
\83\8d\81[
\83\8b \91½
\83X
\83\8c\83b
\83h
\82Å
\91¬
\82¢ Sleep
\83\8b\81[
\83v
\82É
\82æ
\82é
\95s
\97v
\82È
\8bó
\89ñ
\82è
\82ª
\82È
\82¢
\82Ì
\82ÅCPU
\95\89\89×
\8f
\82È
\82¢
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83C
\83x
\83\93\83g
\91Ò
\8b@
\82ÌWaitForMulti
\82ª
\92x
\82¢
\82æ
\82¤
\82È
\81E
\81E
\81H
57 test6 test5
\82Ì
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83C
\83x
\83\93\83g
\91Ò
\8b@
\82ð_mm_pause()
\83\8b\81[
\83v
\82É
\82µ
\82½
\82à
\82Ì test5
\82æ
\82è
\91¬
\82¢
\83\81\83C
\83\93\83X
\83\8c\83b
\83h
\82Ì
\95\89\89×
\82Í
\91\9d\82¦
\82é
58 test7 test6+load_balance
\8d×
\82©
\82
\95ª
\8a\84\82µ
\82½job
\82ð
\8bó
\82¢
\82Ä
\82é
\83X
\83\8c\83b
\83h
\82É
\8a\84\82è
\93\96\82Ä
\83X
\83\8c\83b
\83h
\8aÔ
\82Ì
\8f\88\97\9d\97Ê
\82Ì
\8d·
\82ð
\8c¸
\82ç
\82· mutex
\8eg
\97p test6
\82æ
\82è
\91¬
\82¢
59 test8 test7
\82Ìmutex
\82ðCRITICAL_SECTION
\82É
\95Ï
\8dX test7
\82æ
\82è
\91¬
\82¢
60 test9 test8+reload
\88ê
\93x
\8eÀ
\8ds
\82µ
\82½
\83X
\83\8c\83b
\83h
\8a\84\82è
\93\96\82Ä
\82ð
\8bL
\98^
\82µ
\88ê
\92è
\8e\9e\8aÔ
\93¯
\8aú
\82È
\82µ
\82Å
\8eÀ
\8ds test7
\82
\82ç
\82¢
\82É
\92x
\82
\82È
\82Á
\82½
\83{
\83c
64 int compute_thread_num = 0;
65 int compute_thread_ready = 0;
67 void go_compute_thread(thread_func_t fnc, int num);
68 void terminate_compute_thread(void);
69 void begin_compute_thread(void);
70 void reset_compute_thread(void);
71 static void do_compute_null(int thread_num){}
72 static thread_func_t do_compute_func = do_compute_null;
73 static int compute_thread_job = 0, compute_thread_job_cnt = 0;
76 #if defined(MULTI_THREAD_COMPUTE) && defined(__W32__)
78 static int thread_exit = 0;
79 static HANDLE hComputeThread[MAX_THREADS - 1];
80 VOLATILE DWORD ComputeThreadID[MAX_THREADS - 1];
81 static DWORD ComputeThreadPriority = THREAD_PRIORITY_NORMAL;
82 static HANDLE hEventTcv[MAX_THREADS - 1];
83 static ALIGN uint8 thread_finish_all[MAX_THREADS]; // byte*16=64bit*2=128bit
84 static ALIGN uint8 thread_finish[MAX_THREADS]; // byte*16=64bit*2=128bit
85 CRITICAL_SECTION critThread;
87 void set_compute_thread_priority(DWORD var)
89 ComputeThreadPriority = var;
92 #if (USE_X86_EXT_INTRIN >= 3)
93 #define THREAD_WAIT_MAIN _mm_pause(); // SSE2
94 #define THREAD_WAIT_SUB Sleep(0);
96 #define THREAD_WAIT_MAIN Sleep(0);
97 #define THREAD_WAIT_SUB Sleep(0);
98 //
\91¼
\82Ì
\83X
\83\8c\83b
\83h
\82É
\8f\88\97\9d\82ð
\93n
\82·(
\8dÅ
\8f¬
\8e\9e\8aÔ)
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\95\89\89×
\91\9d\89Á
99 // OS
\83f
\83t
\83H
\83\8b\83g
\82Å
\82Í1~15
\82Ì
\8ew
\92è
\8e\9e 15.6ms
102 static void compute_thread_core(int thread_num)
104 if(compute_thread_job <= compute_thread_ready){
105 if(thread_num < compute_thread_job)
106 do_compute_func(thread_num);
108 #if 1 // load_balance //
\8bó
\82¢
\82Ä
\82é
\83X
\83\8c\83b
\83h
\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
111 EnterCriticalSection(&critThread); // single thread ~
112 job_num = (compute_thread_job_cnt++);
113 LeaveCriticalSection(&critThread); // ~ single thread
114 if(job_num >= compute_thread_job) break;
115 do_compute_func(job_num);
117 #else // normal //
\83X
\83\8c\83b
\83h
\82É
\8bÏ
\93\99\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
119 for (i = thread_num; i < compute_thread_job; i += compute_thread_ready)
125 static void WINAPI ComputeThread(void *arglist)
127 const int thread_num = (int)arglist;
130 WaitForSingleObject(hEventTcv[thread_num], INFINITE); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83C
\83x
\83\93\83g
\91Ò
\8b@
131 if(thread_exit) break;
132 compute_thread_core(thread_num + 1); // 1~15
133 ResetEvent(hEventTcv[thread_num]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83C
\83x
\83\93\83g
\83\8a\83Z
\83b
\83g
134 thread_finish[thread_num] = 1; //
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83t
\83\89\83O
\83Z
\83b
\83g
139 static inline void compute_thread_wait(void)
141 // (MAX_THREADS == 16)
142 #if (USE_X86_EXT_INTRIN >= 6)
143 // byte*8
\82ð128bit
\92P
\88Ê
\82Å
\94ä
\8ar
144 __m128i vec = _mm_load_si128((__m128i *)thread_finish_all);
145 while(!_mm_testc_si128(_mm_load_si128((__m128i *)thread_finish), vec)) // SSE4.1 !(finish == finish_all)
148 // byte*8
\82ð64bit
\92P
\88Ê
\82Å
\94ä
\8ar
149 uint64 *ptr1 = (uint64 *)&thread_finish, *ptr2 = (uint64 *)&thread_finish_all;
150 while(ptr1[0] != ptr2[0] || ptr1[1] != ptr2[1])
155 void go_compute_thread(thread_func_t fnc, int num)
157 const int thread = compute_thread_ready - 1;
160 do_compute_func = fnc;
161 compute_thread_job = num;
162 compute_thread_job_cnt = 0;
163 #if (USE_X86_EXT_INTRIN >= 3) && (MAX_THREADS == 16)
164 _mm_store_si128((__m128i *)thread_finish, _mm_setzero_si128()); //
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83t
\83\89\83O
\83\8a\83Z
\83b
\83g
165 for(i = 0; i < thread; i++)
166 SetEvent(hEventTcv[i]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83C
\83x
\83\93\83g
\83Z
\83b
\83g (
\8dÄ
\8aJ)
168 for(i = 0; i < thread; i++){
169 thread_finish[i] = 0; //
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83t
\83\89\83O
\83\8a\83Z
\83b
\83g
170 SetEvent(hEventTcv[i]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83C
\83x
\83\93\83g
\83Z
\83b
\83g (
\8dÄ
\8aJ)
173 compute_thread_core(0);
174 compute_thread_wait(); //
\91S
\83X
\83\8c\83b
\83h
\8fI
\97¹
\91Ò
\8b@
177 static void init_compute_thread_param(void)
179 static int thread_init = 0;
184 for(i = 0; i < (MAX_THREADS - 1); i++){
185 hComputeThread[i] = NULL;
187 memset(thread_finish, 0, MAX_THREADS);
188 memset(thread_finish_all, 0, MAX_THREADS);
189 InitializeCriticalSection(&critThread);
190 compute_thread_ready = 0;
191 thread_init = 1; // set init flag
194 static int check_compute_thread(void)
198 for(i = 0; i < (MAX_THREADS - 1); i++){
199 if(hComputeThread[i] != NULL)
203 terminate_compute_thread();
204 compute_thread_ready = 0;
205 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : already thread exsist.");
211 void terminate_compute_thread(void)
217 compute_thread_job = 0; //
\83f
\83b
\83h
\83\8d\83b
\83N
\91Î
\8dô
218 for(i = 0; i < (MAX_THREADS - 1); i++){
219 if(hComputeThread[i] == NULL)
221 SetEvent(hEventTcv[i]);
222 switch(WaitForSingleObject(hComputeThread[i], 10)) {
226 status = WaitForSingleObject(hComputeThread[i], 1000);
227 if(status == WAIT_TIMEOUT)
228 TerminateThread(hComputeThread[i], 0);
231 TerminateThread(hComputeThread[i], 0);
234 CloseHandle(hComputeThread[i]);
235 hComputeThread[i] = NULL;
237 for(i = 0; i < (MAX_THREADS - 1); i++){
238 if(hEventTcv[i] != NULL){
239 CloseHandle(hEventTcv[i]);
243 memset(thread_finish, 0, MAX_THREADS);
244 memset(thread_finish_all, 0, MAX_THREADS);
245 DeleteCriticalSection(&critThread);
246 compute_thread_ready = 0;
248 uninit_compute_data_midi_thread();
251 // load ini, load config , init_playmidi()...
\82Ì
\8cã
\82É
\82·
\82é
252 void begin_compute_thread(void)
254 int i, pnum, error = 0;
255 SYSTEM_INFO sys_info;
257 GetSystemInfo(&sys_info);
258 pnum = sys_info.dwNumberOfProcessors;
259 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "NumberOfProcessors : %d", pnum);
261 init_compute_thread_param(); // init thread param
262 if(check_compute_thread()) // check thread exist
264 if(compute_thread_num < 2){ // check thread num
265 compute_thread_num = 0;
266 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "SetComputeThread : OFF");
268 if(compute_thread_num > MAX_THREADS){ // check thread num
269 compute_thread_num = MAX_THREADS;
270 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "ERROR ComputeThread : Limit MAX_THREADS:%d", MAX_THREADS);
272 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "SetComputeThread : %d", compute_thread_num);
274 if(compute_thread_num == 0) // check multi thread
276 // beginthread after CreateEvent
277 InitializeCriticalSection(&critThread);
278 for(i = 0; i < (compute_thread_num - 1); i++){
279 hEventTcv[i] = CreateEvent(NULL,FALSE,FALSE,NULL); // reset manual
280 thread_finish_all[i] = 1; // 1byte full bit
281 if(hEventTcv[i] == NULL){
283 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "ERROR ComputeThread: CreateEvent(%d) error.", i);
286 hComputeThread[i] = crt_beginthreadex(
289 (LPTHREAD_START_ROUTINE)ComputeThread,
290 (LPVOID)i, /* void *arglist = thread_num */
291 0, /* initflag = NULL or CREATE_SUSPENDED */
292 &(ComputeThreadID[i])
294 if(hComputeThread[i] == NULL){
296 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "ERROR ComputeThread : beginthread(%d) error.", i);
301 terminate_compute_thread();
302 compute_thread_ready = 0;
303 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "SetComputeThread : OFF");
306 compute_thread_ready = compute_thread_num;
307 switch(ComputeThreadPriority){
308 case THREAD_PRIORITY_LOWEST:
309 case THREAD_PRIORITY_BELOW_NORMAL:
310 case THREAD_PRIORITY_NORMAL:
311 case THREAD_PRIORITY_ABOVE_NORMAL:
312 case THREAD_PRIORITY_HIGHEST:
313 case THREAD_PRIORITY_TIME_CRITICAL:
314 for(i = 0; i < (compute_thread_ready - 1); i++)
315 if(!SetThreadPriority(hComputeThread[i], ComputeThreadPriority)){
316 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "ERROR ComputeThread : Invalid priority");
320 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "ERROR ComputeThread : Invalid priority");
323 init_compute_data_midi_thread();
327 void reset_compute_thread(void)
329 if(compute_thread_num == compute_thread_ready)
331 terminate_compute_thread();
332 begin_compute_thread();
336 #elif 0 // defined(MULTI_THREAD_COMPUTE) && (defined(HAVE_PTHREAD_H) || defined(HAVE_PTHREADS_H)) && defined(HAVE_PTHREAD_CREATE)
338 \88ê
\89\9e\93®
\82¢
\82Ä
\82Í
\82¢
\82é
\82ª
\94ñ
\8fí
\82É
\92x
\82¢
\81E
\81ECPU
\8eg
\97p
\97¦
\82ª
\91S
\91R
\8fã
\82ª
\82ç
\82È
\82¢
\81E
\81E
339 cond_wait/cond_signal
\82ª
\92x
\82¢
\82Ì
\82Å
\82Í
\81E
\81E
\81H
340 Linux
\82Å
\82Í
\8d\82\91¬
\82È
\83X
\83\8c\83b
\83h
\8b@
\94\
\82Í
\82È
\82¢
\82Ì
\82©
\81H
\91¼
\82É
\89½
\82©
\82 \82é
\82Ì
\82©
\81H
342 \8eg
\97p
\82·
\82é
\8fê
\8d\87\82Í
\8ae
\83t
\83@
\83\93\83N
\83V
\83\87\83\93\82Ì
\8ed
\97l
\82ð
\8am
\94F
\82µ
\82½
\8fã
\82Å
\93®
\8dì
\83e
\83X
\83g
\82·
\82é
343 \8eQ
\8dl
\82É
\82µ
\82½
\82Ì
\82Í PTHREADS-WIN32 RELEASE 2.8.0 (2006-12-22)
\82Å POSIX
\82»
\82Ì
\82à
\82Ì
\82Å
\82Í
\82È
\82¢
\82Ì
\82Å
\81E
\81E
344 Win
\90ê
\97p
\95\94\95ª
\82ðPTHREAD
\83t
\83@
\83\93\83N
\83V
\83\87\83\93\82É
\92u
\82«
\8a·
\82¦
\82½
\82à
\82Ì
346 CRITICAL_SECTION
\82Ípthread_mutex_ , EVENT
\82Ípthread_cond_
\93\99\82Å
\91ã
\91Ö
348 pthread_create()
\88È
\91O
\82©
\82ç
\8eg
\97p
\82µ
\82Ä
\82é
\82Ì
\82Å
\82½
\82Ô
\82ñOK
349 pthread_join()
\88È
\91O
\82©
\82ç
\8eg
\97p
\82µ
\82Ä
\82é
\82Ì
\82Å
\82½
\82Ô
\82ñOK
350 pthread_????
\83X
\83\8c\83b
\83h
\82ª
\82 \82é/
\82È
\82µ
\82Ì
\8fó
\91Ô
\8eæ
\93¾
\95s
\96¾ (
\82È
\82
\82Ä
\82à
\93®
\82
351 pthread_mutex_init()
\88ø
\90\94\82ª
\82 \82â
\82µ
\82¢
\8b¤
\97L
\83t
\83\89\83O
\81H
\81H
352 pthread_mutex_destroy() CloseHandle()
\82Æ
\93¯
\82¶
353 pthread_mutex_lock() WaitForSingleObject()
\82Æ
\93¯
\82¶
354 pthread_mutex_unlock() ReleaseMutex()
\82Æ
\93¯
\82¶
355 pthread_cond_init()
\88ø
\90\94\82ª
\82 \82â
\82µ
\82¢
\8b¤
\97L
\83t
\83\89\83O
\81H
\81H
356 pthread_cond_destroy() CloseHandle()
\82Æ
\93¯
\82¶
357 pthread_cond_wait() WaitForSingleObject()
\82Æ
\93¯
\82¶
\81H
\81H CPU
\8e\9e\8aÔ
\8fÁ
\94ï
\82·
\82é
\82Ì
\82©
\82Ç
\82¤
\82©
\81H mutex_lock
\82ª
\95K
\97v
\82ç
\82µ
\82¢
358 pthread_cond_signal() SetEvent()
\82Æ
\93¯
\82¶
\81H
\81H
359 pthread_???? ResetEvent()
\91\8a\93\96\82Ì
\82à
\82Ì
\96³
\82¢
\81H
\83V
\83O
\83i
\83\8b\82Í
\8e©
\93®
\83\8a\83Z
\83b
\83g
\81H
362 static int thread_exit = 0;
363 static pthread_t handle_thread[MAX_THREADS - 1];
364 pthread_cond_t cond_thread[MAX_THREADS - 1];
365 static ALIGN int8 thread_finish_all[MAX_THREADS]; // byte*16=64bit*2=128bit
366 static ALIGN int8 thread_finish[MAX_THREADS]; // byte*16=64bit*2=128bit
367 pthread_mutex_t mutex_job;
368 pthread_mutex_t mutex_thread[MAX_THREADS];
370 #if (USE_X86_EXT_INTRIN >= 3)
371 #define THREAD_WAIT_MAIN _mm_pause(); // SSE2
373 #define THREAD_WAIT_MAIN usleep(0);
376 static void compute_thread_core(int thread_num)
378 if(compute_thread_job <= compute_thread_ready){
379 if(thread_num < compute_thread_job)
380 do_compute_func(thread_num);
382 #if 1 // load_balancer //
\8bó
\82¢
\82Ä
\82é
\83X
\83\8c\83b
\83h
\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
385 pthread_mutex_lock(&mutex_job); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\8eæ
\93¾
386 job_num = (compute_thread_job_cnt++);
387 pthread_mutex_unlock(&mutex_job); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\89ð
\95ú
388 if(job_num >= compute_thread_job) break;
389 do_compute_func(job_num);
391 #else // normal //
\83X
\83\8c\83b
\83h
\82É
\8bÏ
\93\99\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
393 for (i = thread_num; i < compute_thread_job; i += compute_thread_ready)
399 static void *ComputeThread(void *arglist)
401 const int thread_num = (int)arglist;
404 // pthread_mutex_lock(&mutex_thread[thread_num]); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\8eæ
\93¾
405 pthread_cond_wait(&cond_thread[thread_num], &mutex_thread[thread_num]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83V
\83O
\83i
\83\8b\91Ò
\8b@ .
\83V
\83O
\83i
\83\8b\8cã
\91Ò
\8b@
\8fó
\91Ô
\82É
\96ß
\82é
\81H
406 // pthread_mutex_unlock(&mutex_thread[thread_num]);
407 if(thread_exit) break;
408 compute_thread_core(thread_num + 1); // 1~15
409 //
\83\8d\83b
\83N
\97p
\82Ì
\83V
\83O
\83i
\83\8b\82È
\82¢
\81H cond_wait
\82Í
\8e©
\93®
\83\8a\83Z
\83b
\83g
\81H
410 thread_finish[thread_num] = 1;
415 static inline void compute_thread_wait(void)
417 // (MAX_THREADS == 16)
418 #if (USE_X86_EXT_INTRIN >= 6)
419 // byte*8
\82ð128bit
\92P
\88Ê
\82Å
\94ä
\8ar
420 __m128i vec = _mm_load_si128((__m128i *)thread_finish_all);
421 while(!_mm_testc_si128(_mm_load_si128((__m128i *)thread_finish), vec)) // SSE4.1 !(finish == finish_all)
423 #else // byte*8
\82ð64bit
\92P
\88Ê
\82Å
\94ä
\8ar
424 uint64 *ptr1 = (uint64 *)&thread_finish, *ptr2 = (uint64 *)&thread_finish_all;
425 while(ptr1[0] != ptr2[0] || ptr1[1] != ptr2[1])
430 void go_compute_thread(thread_func_t fnc, int num)
432 const int thread = compute_thread_ready - 1;
435 do_compute_func = fnc;
436 compute_thread_job = num;
437 compute_thread_job_cnt = 0;
438 #if (USE_X86_EXT_INTRIN >= 3) && (MAX_THREADS == 16)
439 _mm_store_si128((__m128i *)thread_finish, _mm_setzero_si128()); //
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83t
\83\89\83O
\83\8a\83Z
\83b
\83g
440 for(i = 0; i < thread; i++){
441 pthread_mutex_lock(&mutex_thread[i]); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\8eæ
\93¾
442 pthread_cond_signal(&cond_thread[i]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83V
\83O
\83i
\83\8b\83Z
\83b
\83g (
\8dÄ
\8aJ)
443 pthread_mutex_unlock(&mutex_thread[i]); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\89ð
\95ú
446 for (i = 0; i < thread; i++) {
447 thread_finish[i] = 0; //
\83X
\83\8c\83b
\83h
\8fI
\97¹
\83t
\83\89\83O
\83\8a\83Z
\83b
\83g
448 pthread_mutex_lock(&mutex_thread[i]); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\8eæ
\93¾
449 pthread_cond_signal(&cond_thread[i]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83V
\83O
\83i
\83\8b\83Z
\83b
\83g (
\8dÄ
\8aJ)
450 pthread_mutex_unlock(&mutex_thread[i]); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\89ð
\95ú
453 compute_thread_core(0); // thread 0
454 compute_thread_wait(); //
\91S
\83X
\83\8c\83b
\83h
\8fI
\97¹
\91Ò
\8b@
457 static void init_compute_thread_param(void)
459 static int thread_init = 0;
464 //for (i = 0; i < (MAX_THREADS - 1); i++){
465 // //
\83n
\83\93\83h
\83\8b\82©
\82È
\82É
\82©
\82Ì
\8f\89\8aú
\89»
467 memset(thread_finish, 0, MAX_THREADS);
468 memset(thread_finish_all, 0, MAX_THREADS);
469 compute_thread_ready = 0;
470 thread_init = 1; // set init flag
473 static int check_compute_thread(void)
477 //
\82±
\82±
\82Å
\83X
\83\8c\83b
\83h
\82ª
\8ec
\82Á
\82Ä
\82é
\82±
\82Æ
\82Í
\82È
\82¢
\82Í
\82¸
478 //for (i = 0; i < (MAX_THREADS - 1); i++) {
479 // if () //
\83X
\83\8c\83b
\83h
\82ª
\82 \82é
\82Ì
\8fð
\8c\8f \83n
\83\93\83h
\83\8b\82©
\82È
\82É
\82©
\82Ì
\83`
\83F
\83b
\83N
\81H
483 // terminate_compute_thread();
484 // compute_thread_ready = 0;
485 // ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : already thread exist.");
491 void terminate_compute_thread(void)
496 compute_thread_job = 0; //
\83f
\83b
\83h
\83\8d\83b
\83N
\91Î
\8dô
497 for(i = 0; i < (MAX_THREADS - 1); i++){
498 //if() //
\83X
\83\8c\83b
\83h
\82ª
\82È
\82¢
\82Ì
\8fð
\8c\8f
500 pthread_mutex_lock(&mutex_thread[i]);
501 pthread_cond_signal(&cond_thread[i]); //
\83X
\83\8c\83b
\83h
\8aJ
\8en
\83V
\83O
\83i
\83\8b\83Z
\83b
\83g (
\8dÄ
\8aJ)
502 pthread_mutex_unlock(&mutex_thread[i]);
503 pthread_join(handle_thread[i], NULL);
504 handle_thread[i] = NULL;
506 for(i = 0; i < (MAX_THREADS - 1); i++){
507 pthread_mutex_destroy(&mutex_thread[i]);
508 pthread_cond_destroy(&cond_thread[i]);
510 pthread_mutex_destroy(&mutex_job);
511 memset(thread_finish, 0, MAX_THREADS);
512 memset(thread_finish_all, 0, MAX_THREADS);
513 compute_thread_ready = 0;
515 uninit_compute_data_midi_thread();
518 // load ini, load config , init_playmidi()...
\82Ì
\8cã
\82É
\82·
\82é
519 void begin_compute_thread(void)
523 init_compute_thread_param(); // init thread param
524 if (check_compute_thread()) // check thread exist
526 if (compute_thread_num > MAX_THREADS) // check thread num
527 compute_thread_num = MAX_THREADS;
528 else if (compute_thread_num < 2) // check thread num
529 compute_thread_num = 0;
530 if (compute_thread_num == 0) // check multi thread
532 if(pthread_mutex_init(&mutex_job, NULL)){
533 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : pthread_mutex_init mutex_job error.");
535 }else for(i = 0; i < (compute_thread_num - 1); i++){
536 if(pthread_mutex_init(&mutex_thread[i], NULL)){
537 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : pthread_mutex_init %d error.", i);
541 if(pthread_cond_init(&cond_thread[i], NULL)){ // attr
\82Í
\8b¤
\97L
\90Ý
\92è
\81H
542 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : pthread_cond_init %d error.", i);
546 thread_finish_all[i] = 1;
547 if(pthread_create(&handle_thread[i], NULL, (void*)ComputeThread, (void*)i)){
548 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : pthread_create %d error.", i);
554 terminate_compute_thread();
555 compute_thread_ready = 0;
556 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "SetComputeThread : OFF");
559 compute_thread_ready = compute_thread_num;
560 init_compute_data_midi_thread();
564 void reset_compute_thread(void)
566 if (compute_thread_num == compute_thread_ready)
568 terminate_compute_thread();
569 begin_compute_thread();
572 #elif defined(MULTI_THREAD_COMPUTE) && (defined(HAVE_PTHREAD_H) || defined(HAVE_PTHREADS_H)) && defined(HAVE_PTHREAD_CREATE)
574 \88ê
\89\9e\93®
\82¢
\82Ä
\82Í
\82¢
\82é
\82ª
\81E
\81E
\92x
\82¢
\82æ
\82¤
\82È
\81E
\81E
\81H
576 \96\88\89ñpthread_create/pthread_join
577 load_balancer (mutex) // CRITICAL_SECTION
\82ª
\82È
\82¢
\81H
\82Ì
\82Åmutex
\8eg
\97p
580 static pthread_t handle_thread[MAX_THREADS - 1];
581 pthread_mutex_t mutex_job;
583 static void compute_thread_core(int thread_num)
585 if(compute_thread_job <= compute_thread_ready){
586 if(thread_num < compute_thread_job)
587 do_compute_func(thread_num);
589 #if 1 // load_balancer //
\8bó
\82¢
\82Ä
\82é
\83X
\83\8c\83b
\83h
\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
592 pthread_mutex_lock(&mutex_job); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\8eæ
\93¾
593 job_num = (compute_thread_job_cnt++);
594 pthread_mutex_unlock(&mutex_job); //
\83~
\83\85\81[
\83e
\83b
\83N
\83X
\89ð
\95ú
595 if(job_num >= compute_thread_job) break;
596 do_compute_func(job_num);
598 #else // normal //
\83X
\83\8c\83b
\83h
\82É
\8bÏ
\93\99\82É
\83W
\83\87\83u
\8a\84\82è
\93\96\82Ä
600 for (i = thread_num; i < compute_thread_job; i += compute_thread_ready)
606 static void *ComputeThread(void *arglist)
608 compute_thread_core((int)arglist + 1); // 1~15
612 void go_compute_thread(thread_func_t fnc, int num)
616 do_compute_func = fnc;
617 compute_thread_job = num;
618 compute_thread_job_cnt = 0;
619 for (i = 0; i < (compute_thread_ready - 1); i++)
620 pthread_create(&handle_thread[i], NULL, (void*)ComputeThread, (void*)i);
621 compute_thread_core(0);
622 for (i = 0; i < (compute_thread_ready - 1); i++)
623 pthread_join(handle_thread[i], NULL);
626 static void init_compute_thread_param(void)
628 static int thread_init = 0;
633 compute_thread_ready = 0;
634 thread_init = 1; // set init flag
637 void terminate_compute_thread(void)
639 pthread_mutex_destroy(&mutex_job);
640 compute_thread_ready = 0;
641 uninit_compute_data_midi_thread();
644 // load ini, load config , init_playmidi()...
\82Ì
\8cã
\82É
\82·
\82é
645 void begin_compute_thread(void)
649 init_compute_thread_param(); // init thread param
650 if (compute_thread_num > MAX_THREADS) // check thread num
651 compute_thread_num = MAX_THREADS;
652 else if (compute_thread_num < 2) // check thread num
653 compute_thread_num = 0;
654 if (compute_thread_num == 0) // check multi thread
656 if(pthread_mutex_init(&mutex_job, NULL)){
657 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR ComputeThread : pthread_mutex_init thread_core error.");
661 terminate_compute_thread();
662 compute_thread_ready = 0;
663 ctl->cmsg(CMSG_INFO, VERB_NORMAL, "SetComputeThread : OFF");
666 compute_thread_ready = compute_thread_num;
667 init_compute_data_midi_thread();
671 void reset_compute_thread(void)
673 if (compute_thread_num == compute_thread_ready)
675 terminate_compute_thread();
676 begin_compute_thread();
678 #endif /* MULTI_THREAD_COMPUTE */