source: trunk/FACT++/dim_v19r15/src/dim_thr.c@ 10305

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