source: trunk/FACT++/dim/src/dim_thr.c@ 13408

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