source: trunk/FACT++/dim_v19r19/src/dim_thr.c@ 10544

Last change on this file since 10544 was 10480, checked in by tbretz, 13 years ago
New version V19r19 with some important bug fixes.
File size: 17.0 KB
Line 
1#include <signal.h>
2#define DIMLIB
3#include "dim.h"
4
5#ifndef WIN32
6
7#ifndef NOTHREADS
8#include <pthread.h>
9#include <semaphore.h>
10#ifdef solaris
11#include <synch.h>
12#endif
13#ifdef darwin
14#include <sys/types.h>
15#include <sys/stat.h>
16#endif
17
18pthread_t IO_thread = 0;
19pthread_t ALRM_thread = 0;
20pthread_t INIT_thread = 0;
21pthread_t MAIN_thread = 0;
22#ifndef darwin
23sem_t DIM_INIT_Sema;
24/*
25sem_t DIM_WAIT_Sema;
26*/
27#else
28sem_t *DIM_INIT_Semap;
29/*
30sem_t *DIM_WAIT_Semap;
31*/
32#endif
33int INIT_count = 0;
34/*
35int WAIT_count = 0;
36*/
37int DIM_THR_init_done = 0;
38
39void *dim_tcpip_thread(void *tag)
40{
41 extern int dim_tcpip_init();
42 extern void tcpip_task();
43 /*
44 int prio;
45
46 thr_getprio(thr_self(),&prio);
47 thr_setprio(thr_self(),prio+10);
48 */
49 if(tag){}
50 IO_thread = pthread_self();
51
52 dim_tcpip_init(1);
53 if(INIT_thread)
54 {
55#ifndef darwin
56 sem_post(&DIM_INIT_Sema);
57#else
58 sem_post(DIM_INIT_Semap);
59#endif
60 }
61 while(1)
62 {
63 tcpip_task();
64 /*
65#ifndef darwin
66 sem_post(&DIM_WAIT_Sema);
67#else
68 sem_post(DIM_WAIT_Semap);
69#endif
70 */
71 dim_signal_cond();
72 }
73}
74
75void *dim_dtq_thread(void *tag)
76{
77 extern int dim_dtq_init();
78 extern int dtq_task();
79 /*
80 int prio;
81
82 thr_getprio(thr_self(),&prio);
83 thr_setprio(thr_self(),prio+5);
84 */
85 if(tag){}
86 ALRM_thread = pthread_self();
87
88 dim_dtq_init(1);
89 if(INIT_thread)
90 {
91#ifndef darwin
92 sem_post(&DIM_INIT_Sema);
93#else
94 sem_post(DIM_INIT_Semap);
95#endif
96 }
97 while(1)
98 {
99 dtq_task();
100 /*
101#ifndef darwin
102 sem_post(&DIM_WAIT_Sema);
103#else
104 sem_post(DIM_WAIT_Semap);
105#endif
106 */
107 dim_signal_cond();
108 }
109}
110
111void dim_init()
112{
113 pthread_t t_id;
114 void ignore_sigpipe();
115 int ret;
116 extern int dna_init();
117/*
118#ifdef LYNXOS
119*/
120 pthread_attr_t attr;
121/*
122#endif
123*/
124 if(!DIM_THR_init_done)
125 {
126 /*
127 int prio;
128 */
129 DIM_THR_init_done = 1;
130 dna_init();
131 /*
132 thr_getprio(thr_self(),&prio);
133 thr_setprio(thr_self(),prio+3);
134 */
135 INIT_thread = pthread_self();
136 MAIN_thread = INIT_thread;
137
138#ifndef darwin
139 sem_init(&DIM_INIT_Sema, 0, INIT_count);
140 /*
141 sem_init(&DIM_WAIT_Sema, 0, WAIT_count);
142 */
143#else
144 DIM_INIT_Semap = sem_open("/Dim_INIT_Sem", O_CREAT, S_IRUSR | S_IWUSR, INIT_count);
145 /*
146 DIM_WAIT_Semap = sem_open("/Dim_WAIT_Sem", O_CREAT, S_IRUSR | S_IWUSR, WAIT_count);
147 */
148#endif
149
150 ignore_sigpipe();
151
152#if defined (LYNXOS) && !defined (__Lynx__)
153 pthread_attr_create(&attr);
154 pthread_create(&t_id, attr, dim_dtq_thread, 0);
155#else
156/*
157 pthread_create(&t_id, NULL, dim_dtq_thread, 0);
158*/
159 pthread_attr_init(&attr);
160 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
161 pthread_create(&t_id, &attr, dim_dtq_thread, 0);
162#endif
163#ifndef darwin
164 ret = sem_wait(&DIM_INIT_Sema);
165#else
166 ret = sem_wait(DIM_INIT_Semap);
167#endif
168#if defined (LYNXOS) && !defined (__Lynx__)
169 pthread_create(&t_id, attr, dim_tcpip_thread, 0);
170#else
171 pthread_create(&t_id, &attr, dim_tcpip_thread, 0);
172#endif
173#ifndef darwin
174 ret = sem_wait(&DIM_INIT_Sema);
175#else
176 ret = sem_wait(DIM_INIT_Semap);
177#endif
178 INIT_thread = 0;
179 }
180}
181
182void dim_stop()
183{
184 int i;
185 int n = 0;
186 void dim_tcpip_stop(), dim_dtq_stop();
187
188 for( i = 0; i< Curr_N_Conns; i++ )
189 {
190 if(Net_conns[i].channel != 0)
191 n++;
192 }
193 if(n)
194 return;
195 if(IO_thread)
196 pthread_cancel(IO_thread);
197 if(ALRM_thread)
198 pthread_cancel(ALRM_thread);
199 if(IO_thread)
200 pthread_join(IO_thread,0);
201 if(ALRM_thread)
202 pthread_join(ALRM_thread,0);
203#ifndef darwin
204 sem_destroy(&DIM_INIT_Sema);
205 /*
206 sem_destroy(&DIM_WAIT_Sema);
207 */
208#else
209 sem_unlink("/Dim_INIT_Sem");
210 /*
211 sem_unlink("/Dim_WAIT_Sem");
212 */
213 sem_close(DIM_INIT_Semap);
214 /*
215 sem_close(DIM_WAIT_Semap);
216 */
217#endif
218 dim_tcpip_stop();
219 dim_dtq_stop();
220 IO_thread = 0;
221 ALRM_thread = 0;
222 DIM_THR_init_done = 0;
223}
224
225long dim_start_thread(void *(*thread_ast)(void *), long tag)
226{
227 pthread_t t_id;
228 pthread_attr_t attr;
229
230#if defined (LYNXOS) && !defined (__Lynx__)
231 pthread_attr_create(&attr);
232 pthread_create(&t_id, attr, (void *)thread_ast, (void *)tag);
233#else
234 pthread_attr_init(&attr);
235 pthread_create(&t_id, &attr, thread_ast, (void *)tag);
236#endif
237 return((long)t_id);
238}
239
240int dim_stop_thread(long t_id)
241{
242 int ret;
243 ret = pthread_cancel((pthread_t)t_id);
244 dim_print_date_time();
245 printf("dim_stop_thread: this function is obsolete, it creates memory leaks\n");
246 return ret;
247}
248
249int dim_set_scheduler_class(int pclass)
250{
251#ifdef __linux__
252 int ret, prio, p;
253 struct sched_param param;
254
255 if(pclass == 0)
256 {
257 pclass = SCHED_OTHER;
258 }
259 else if(pclass == 1)
260 {
261 pclass = SCHED_FIFO;
262 }
263 else if(pclass == 2)
264 {
265 pclass = SCHED_RR;
266 }
267 prio = sched_get_priority_min(pclass);
268 ret = pthread_getschedparam(MAIN_thread, &p, &param);
269 if( (p == SCHED_OTHER) || (pclass == SCHED_OTHER) )
270 param.sched_priority = prio;
271 ret = pthread_setschedparam(MAIN_thread, pclass, &param);
272 if(ret)
273 return 0;
274 ret = pthread_getschedparam(IO_thread, &p, &param);
275 if( (p == SCHED_OTHER) || (pclass == SCHED_OTHER) )
276 param.sched_priority = prio;
277 ret = pthread_setschedparam(IO_thread, pclass, &param);
278 if(ret)
279 return 0;
280 ret = pthread_getschedparam(ALRM_thread, &p, &param);
281 if( (p == SCHED_OTHER) || (pclass == SCHED_OTHER) )
282 param.sched_priority = prio;
283 ret = pthread_setschedparam(ALRM_thread, pclass, &param);
284 if(!ret)
285 return 1;
286#endif
287 return 0;
288}
289
290int dim_get_scheduler_class(int *pclass)
291{
292#ifdef __linux__
293 int ret;
294 struct sched_param param;
295
296 ret = pthread_getschedparam(MAIN_thread, pclass, &param);
297 if(!ret)
298 return 1;
299#endif
300 return 0;
301}
302
303int dim_set_priority(int threadId, int prio)
304{
305#ifdef __linux__
306 pthread_t id = MAIN_thread;
307 int ret;
308 int pclass;
309 struct sched_param param;
310
311 if(threadId == 1)
312 id = MAIN_thread;
313 else if(threadId == 2)
314 id = IO_thread;
315 else if(threadId == 3)
316 id = ALRM_thread;
317
318 ret = pthread_getschedparam(id, &pclass, &param);
319 param.sched_priority = prio;
320 ret = pthread_setschedparam(id, pclass, &param);
321 if(!ret)
322 return 1;
323#endif
324 return 0;
325}
326
327int dim_get_priority(int threadId, int *prio)
328{
329#ifdef __linux__
330 pthread_t id=MAIN_thread;
331 int ret;
332 int pclass;
333 struct sched_param param;
334
335 if(threadId == 1)
336 id = MAIN_thread;
337 else if(threadId == 2)
338 id = IO_thread;
339 else if(threadId == 3)
340 id = ALRM_thread;
341
342 ret = pthread_getschedparam(id, &pclass, &param);
343 *prio = param.sched_priority;
344 if(!ret)
345 return 1;
346#endif
347 return 0;
348}
349
350void ignore_sigpipe()
351{
352
353 struct sigaction sig_info;
354 sigset_t set;
355 void pipe_sig_handler();
356
357 if( sigaction(SIGPIPE, 0, &sig_info) < 0 )
358 {
359 perror( "sigaction(SIGPIPE)" );
360 exit(1);
361 }
362 if(sig_info.sa_handler)
363 {
364/*
365 printf("DIM ignore_sigpipe() - Handler already defined %08X\n", sig_info.sa_handler);
366*/
367 return;
368 }
369 sigemptyset(&set);
370 sig_info.sa_handler = pipe_sig_handler;
371 sig_info.sa_mask = set;
372#ifndef LYNXOS
373 sig_info.sa_flags = SA_RESTART;
374#else
375 sig_info.sa_flags = 0;
376#endif
377
378 if( sigaction(SIGPIPE, &sig_info, 0) < 0 )
379 {
380 perror( "sigaction(SIGPIPE)" );
381 exit(1);
382 }
383}
384
385void pipe_sig_handler( int num )
386{
387 if(num){}
388/*
389 printf( "*** pipe_sig_handler called ***\n" );
390*/
391}
392
393void dim_init_threads()
394{
395 dim_init();
396}
397
398void dim_stop_threads()
399{
400 dim_stop();
401}
402
403int dim_wait(void)
404{
405 pthread_t id;
406
407 id = pthread_self();
408
409 if((id == ALRM_thread) || (id == IO_thread))
410 {
411 return(-1);
412 }
413 /*
414#ifndef darwin
415 sem_wait(&DIM_WAIT_Sema);
416#else
417 sem_wait(DIM_WAIT_Semap);
418#endif
419 */
420 dim_wait_cond();
421 return(-1);
422}
423
424/*
425static void show_ast()
426{
427sigset_t oset;
428
429 sigprocmask(SIG_SETMASK,0,&oset);
430 printf("---THREAD id = %d, mask = %x %x\n",
431 pthread_self(), oset.__sigbits[1], oset.__sigbits[0]);
432}
433*/
434
435pthread_t Dim_thr_locker = 0;
436int Dim_thr_counter = 0;
437#ifdef LYNXOS
438pthread_mutex_t Global_DIM_mutex;
439pthread_mutex_t Global_cond_mutex;
440pthread_cond_t Global_cond;
441#else
442pthread_mutex_t Global_DIM_mutex = PTHREAD_MUTEX_INITIALIZER;
443pthread_mutex_t Global_cond_mutex = PTHREAD_MUTEX_INITIALIZER;
444pthread_cond_t Global_cond = PTHREAD_COND_INITIALIZER;
445#endif
446
447void dim_lock()
448{
449 /*printf("Locking %d ", pthread_self());*/
450 if(Dim_thr_locker != pthread_self())
451 {
452/*
453#ifdef __linux__
454 pthread_testcancel();
455#endif
456*/
457 pthread_mutex_lock(&Global_DIM_mutex);
458 Dim_thr_locker=pthread_self();
459 /*printf(": Locked ");*/
460 }
461 /*printf("Counter = %d\n",Dim_thr_counter);*/
462 Dim_thr_counter++;
463}
464void dim_unlock()
465{
466 /*printf("Un-Locking %d ", pthread_self());*/
467 Dim_thr_counter--;
468 /*printf("Counter = %d ",Dim_thr_counter);*/
469 if(!Dim_thr_counter)
470 {
471 Dim_thr_locker=0;
472 pthread_mutex_unlock(&Global_DIM_mutex);
473 /*printf(": Un-Locked ");*/
474 }
475 /* printf("\n");*/
476}
477
478void dim_wait_cond()
479{
480 pthread_mutex_lock(&Global_cond_mutex);
481 pthread_cond_wait(&Global_cond, &Global_cond_mutex);
482 pthread_mutex_unlock(&Global_cond_mutex);
483}
484
485void dim_signal_cond()
486{
487 pthread_mutex_lock(&Global_cond_mutex);
488 pthread_cond_broadcast(&Global_cond);
489 pthread_mutex_unlock(&Global_cond_mutex);
490}
491
492#else
493
494void dim_init()
495{
496}
497
498void dim_init_threads()
499{
500}
501
502void dim_stop_threads()
503{
504}
505
506void dim_stop()
507{
508}
509
510int dim_wait()
511{
512 pause();
513 return(-1);
514}
515
516long dim_start_thread(void (*thread_ast)(), long tag)
517
518{
519 printf("dim_start_thread: not available\n");
520 return (long)0;
521}
522
523int dim_stop_thread(long t_id)
524{
525 printf("dim_stop_thread: not available\n");
526 return 0;
527}
528#endif
529
530#else
531#include <windows.h>
532
533DWORD IO_thread = 0;
534DWORD ALRM_thread = 0;
535DWORD MAIN_thread = 0;
536HANDLE hIO_thread;
537HANDLE hALRM_thread;
538HANDLE hMAIN_thread;
539DllExp HANDLE Global_DIM_event_auto = 0;
540DllExp HANDLE Global_DIM_mutex = 0;
541DllExp HANDLE Global_DIM_event_manual = 0;
542void dim_tcpip_stop(), dim_dtq_stop();
543
544typedef struct{
545 void (*thread_ast)();
546 long tag;
547
548}THREAD_PARAMS;
549
550#ifndef STDCALL
551long dim_start_thread(void (*thread_ast)(), long tag)
552#else
553long dim_start_thread(unsigned long (*thread_ast)(void *), void *tag)
554#endif
555{
556DWORD threadid = 0;
557HANDLE hthread;
558
559#ifndef STDCALL
560 hthread = CreateThread(
561 NULL, /* no security attributes */
562 0, /* use default stack size */
563 (void *)thread_ast, /* thread function */
564 (void *)tag, /* argument to thread function */
565 0, /* use default creation flags */
566 &threadid); /* returns the thread identifier */
567#else
568 hthread = CreateThread(
569 NULL, /* no security attributes */
570 0, /* use default stack size */
571 thread_ast, /* thread function */
572 tag, /* argument to thread function */
573 0, /* use default creation flags */
574 &threadid); /* returns the thread identifier */
575#endif
576 return (long)hthread;
577}
578
579
580int dim_stop_thread(long thread_id)
581{
582 int ret;
583
584 ret = TerminateThread((HANDLE)thread_id, 0);
585 CloseHandle((HANDLE)thread_id);
586 printf("dim_stop_thread: this function is obsolete, it creates memory leaks\n");
587 return ret;
588}
589
590
591void create_io_thread()
592{
593 int tcpip_task(void *);
594
595#ifndef STDCALL
596 hIO_thread = CreateThread(
597 NULL, /* no security attributes */
598 0, /* use default stack size */
599 (void *)tcpip_task, /* thread function */
600 0, /* argument to thread function */
601 0, /* use default creation flags */
602 &IO_thread); /* returns the thread identifier */
603#else
604 hIO_thread = CreateThread(
605 NULL, /* no security attributes */
606 0, /* use default stack size */
607 tcpip_task, /* thread function */
608 0, /* argument to thread function */
609 0, /* use default creation flags */
610 &IO_thread); /* returns the thread identifier */
611#endif
612}
613
614void create_alrm_thread()
615{
616
617 int dtq_task(void *);
618
619#ifndef STDCALL
620 hALRM_thread = CreateThread(
621 NULL,
622 0,
623 (void *)dtq_task,
624 0,
625 0,
626 &ALRM_thread);
627#else
628 hALRM_thread = CreateThread(
629 NULL,
630 0,
631 dtq_task,
632 0,
633 0,
634 &ALRM_thread);
635#endif
636}
637
638void dim_init_threads()
639{
640 static int done = 0;
641
642 if(!done)
643 {
644 hMAIN_thread = GetCurrentThread();
645 done = 1;
646 }
647}
648
649void dim_stop_threads()
650{
651 int i;
652 int n = 0;
653
654 for( i = 0; i< Curr_N_Conns; i++ )
655 {
656 if(Net_conns[i].channel != 0)
657 n++;
658 }
659 if(n)
660 return;
661 if(hIO_thread)
662 TerminateThread(hIO_thread, 0);
663 if(hALRM_thread)
664 TerminateThread(hALRM_thread, 0);
665 if(Global_DIM_mutex)
666 CloseHandle(Global_DIM_mutex);
667 if(Global_DIM_event_auto)
668 CloseHandle(Global_DIM_event_auto);
669 if(Global_DIM_event_manual)
670 CloseHandle(Global_DIM_event_manual);
671 hIO_thread = 0;
672 hALRM_thread = 0;
673 Global_DIM_mutex = 0;
674 Global_DIM_event_auto = 0;
675 Global_DIM_event_manual = 0;
676 dim_tcpip_stop();
677 dim_dtq_stop();
678}
679
680void dim_stop()
681{
682 dim_stop_threads();
683}
684
685int dim_set_scheduler_class(int pclass)
686{
687 HANDLE hProc;
688 int ret;
689 DWORD p;
690
691#ifndef PXI
692 hProc = GetCurrentProcess();
693
694 if(pclass == -1)
695 p = IDLE_PRIORITY_CLASS;
696/*
697 else if(pclass == -1)
698 p = BELOW_NORMAL_PRIORITY_CLASS;
699*/
700 else if(pclass == 0)
701 p = NORMAL_PRIORITY_CLASS;
702/*
703 else if(pclass == 1)
704 p == ABOVE_NORMAL_PRIORITY_CLASS;
705*/
706 else if(pclass == 1)
707 p = HIGH_PRIORITY_CLASS;
708 else if(pclass == 2)
709 p = REALTIME_PRIORITY_CLASS;
710 ret = SetPriorityClass(hProc, p);
711 if(ret)
712 return 1;
713 ret = GetLastError();
714 printf("ret = %x %d\n",ret, ret);
715 return 0;
716#else
717 return 0;
718#endif
719}
720
721int dim_get_scheduler_class(int *pclass)
722{
723 HANDLE hProc;
724 DWORD ret;
725
726#ifndef PXI
727 hProc = GetCurrentProcess();
728
729 ret = GetPriorityClass(hProc);
730 if(ret == 0)
731 return 0;
732 if(ret == IDLE_PRIORITY_CLASS)
733 *pclass = -1;
734/*
735 else if(ret == BELOW_NORMAL_PRIORITY_CLASS)
736 *pclass = -1;
737*/
738 else if(ret == NORMAL_PRIORITY_CLASS)
739 *pclass = 0;
740/*
741 else if(ret == ABOVE_NORMAL_PRIORITY_CLASS)
742 *pclass = 1;
743*/
744 else if(ret == HIGH_PRIORITY_CLASS)
745 *pclass = 1;
746 else if(ret == REALTIME_PRIORITY_CLASS)
747 *pclass = 2;
748 return 1;
749#else
750 *pclass = 0;
751 return 0;
752#endif
753}
754
755int dim_set_priority(int threadId, int prio)
756{
757 HANDLE id;
758 int ret, p;
759
760#ifndef PXI
761 if(threadId == 1)
762 id = hMAIN_thread;
763 else if(threadId == 2)
764 id = hIO_thread;
765 else if(threadId == 3)
766 id = hALRM_thread;
767
768 if(prio == -3)
769 p = THREAD_PRIORITY_IDLE;
770 if(prio == -2)
771 p = THREAD_PRIORITY_LOWEST;
772 if(prio == -1)
773 p = THREAD_PRIORITY_BELOW_NORMAL;
774 if(prio == 0)
775 p = THREAD_PRIORITY_NORMAL;
776 if(prio == 1)
777 p = THREAD_PRIORITY_ABOVE_NORMAL;
778 if(prio == 2)
779 p = THREAD_PRIORITY_HIGHEST;
780 if(prio == 3)
781 p = THREAD_PRIORITY_TIME_CRITICAL;
782
783 ret = SetThreadPriority(id, p);
784 if(ret)
785 return 1;
786 return 0;
787#else
788 return 0;
789#endif
790}
791
792int dim_get_priority(int threadId, int *prio)
793{
794 HANDLE id;
795 int ret, p;
796
797#ifndef PXI
798 if(threadId == 1)
799 id = hMAIN_thread;
800 else if(threadId == 2)
801 id = hIO_thread;
802 else if(threadId == 3)
803 id = hALRM_thread;
804
805 ret = GetThreadPriority(id);
806 if(ret == THREAD_PRIORITY_ERROR_RETURN)
807 return 0;
808 if(ret == THREAD_PRIORITY_IDLE)
809 p = -3;
810 if(ret == THREAD_PRIORITY_LOWEST)
811 p = -2;
812 if(ret == THREAD_PRIORITY_BELOW_NORMAL)
813 p = -1;
814 if(ret == THREAD_PRIORITY_NORMAL)
815 p = 0;
816 if(ret == THREAD_PRIORITY_ABOVE_NORMAL)
817 p = 1;
818 if(ret == THREAD_PRIORITY_HIGHEST)
819 p = 2;
820 if(ret == THREAD_PRIORITY_TIME_CRITICAL)
821 p = 3;
822 *prio = p;
823 return 1;
824#else
825 *prio = 0;
826 return 0;
827#endif
828}
829
830void dim_init()
831{
832}
833
834void dim_no_threads()
835{
836}
837
838int dim_wait()
839{
840 pause();
841 return(1);
842}
843
844void dim_lock()
845{
846 if(!Global_DIM_mutex)
847 {
848 Global_DIM_mutex = CreateMutex(NULL,FALSE,NULL);
849 }
850 WaitForSingleObject(Global_DIM_mutex, INFINITE);
851}
852
853void dim_unlock()
854{
855 ReleaseMutex(Global_DIM_mutex);
856}
857
858void dim_pause()
859{
860HANDLE handles[2];
861
862 if(!Global_DIM_event_auto)
863 {
864 Global_DIM_event_auto = CreateEvent(NULL,FALSE,FALSE,NULL);
865 Global_DIM_event_manual = CreateEvent(NULL,TRUE,FALSE,NULL);
866 }
867 else
868 {
869/*
870 WaitForSingleObject(Global_DIM_event, INFINITE);
871*/
872 handles[0] = Global_DIM_event_auto;
873 handles[1] = Global_DIM_event_manual;
874 WaitForMultipleObjects(2, handles, FALSE, INFINITE);
875 }
876}
877
878void dim_wake_up()
879{
880 if(Global_DIM_event_auto)
881 {
882 SetEvent(Global_DIM_event_auto);
883 }
884 if(Global_DIM_event_manual)
885 {
886 SetEvent(Global_DIM_event_manual);
887 ResetEvent(Global_DIM_event_manual);
888 }
889}
890
891void dim_sleep(unsigned int t)
892{
893 Sleep(t*1000);
894}
895
896void dim_win_usleep(unsigned int t)
897{
898 Sleep(t/1000);
899}
900
901#endif
Note: See TracBrowser for help on using the repository browser.