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

Last change on this file since 12832 was 12585, checked in by tbretz, 13 years ago
Updated to v19r26.
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 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
446int Global_cond_counter = 0;
447int Global_cond_waiters = 0;
448
449void dim_lock()
450{
451 /*printf("Locking %d ", pthread_self());*/
452 if(Dim_thr_locker != pthread_self())
453 {
454/*
455#ifdef __linux__
456 pthread_testcancel();
457#endif
458*/
459 pthread_mutex_lock(&Global_DIM_mutex);
460 Dim_thr_locker=pthread_self();
461 /*printf(": Locked ");*/
462 }
463 /*printf("Counter = %d\n",Dim_thr_counter);*/
464 Dim_thr_counter++;
465}
466void dim_unlock()
467{
468 /*printf("Un-Locking %d ", pthread_self());*/
469 Dim_thr_counter--;
470 /*printf("Counter = %d ",Dim_thr_counter);*/
471 if(!Dim_thr_counter)
472 {
473 Dim_thr_locker=0;
474 pthread_mutex_unlock(&Global_DIM_mutex);
475 /*printf(": Un-Locked ");*/
476 }
477 /* printf("\n");*/
478}
479
480void dim_wait_cond()
481{
482 pthread_mutex_lock(&Global_cond_mutex);
483 Global_cond_waiters++;
484 if(!Global_cond_counter)
485 {
486 pthread_cond_wait(&Global_cond, &Global_cond_mutex);
487 }
488 Global_cond_waiters--;
489 if(!Global_cond_waiters)
490 Global_cond_counter--;
491 pthread_mutex_unlock(&Global_cond_mutex);
492}
493
494void dim_signal_cond()
495{
496 pthread_mutex_lock(&Global_cond_mutex);
497 if(!Global_cond_waiters)
498 {
499 Global_cond_counter = 1;
500 }
501 else
502 {
503 Global_cond_counter++;
504 pthread_cond_broadcast(&Global_cond);
505 }
506 pthread_mutex_unlock(&Global_cond_mutex);
507}
508
509#else
510
511void dim_init()
512{
513}
514
515void dim_init_threads()
516{
517}
518
519void dim_stop_threads()
520{
521}
522
523void dim_stop()
524{
525}
526
527int dim_wait()
528{
529 pause();
530 return(-1);
531}
532
533long dim_start_thread(void (*thread_ast)(), long tag)
534
535{
536 printf("dim_start_thread: not available\n");
537 return (long)0;
538}
539
540int dim_stop_thread(long t_id)
541{
542 printf("dim_stop_thread: not available\n");
543 return 0;
544}
545#endif
546
547#else
548#include <windows.h>
549
550DWORD IO_thread = 0;
551DWORD ALRM_thread = 0;
552DWORD MAIN_thread = 0;
553HANDLE hIO_thread;
554HANDLE hALRM_thread;
555HANDLE hMAIN_thread;
556DllExp HANDLE Global_DIM_event_auto = 0;
557DllExp HANDLE Global_DIM_mutex = 0;
558DllExp HANDLE Global_DIM_event_manual = 0;
559void dim_tcpip_stop(), dim_dtq_stop();
560
561typedef struct{
562 void (*thread_ast)();
563 long tag;
564
565}THREAD_PARAMS;
566
567#ifndef STDCALL
568long dim_start_thread(void (*thread_ast)(), long tag)
569#else
570long dim_start_thread(unsigned long (*thread_ast)(void *), void *tag)
571#endif
572{
573DWORD threadid = 0;
574HANDLE hthread;
575
576#ifndef STDCALL
577 hthread = CreateThread(
578 NULL, /* no security attributes */
579 0, /* use default stack size */
580 (void *)thread_ast, /* thread function */
581 (void *)tag, /* argument to thread function */
582 0, /* use default creation flags */
583 &threadid); /* returns the thread identifier */
584#else
585 hthread = CreateThread(
586 NULL, /* no security attributes */
587 0, /* use default stack size */
588 thread_ast, /* thread function */
589 tag, /* argument to thread function */
590 0, /* use default creation flags */
591 &threadid); /* returns the thread identifier */
592#endif
593 return (long)hthread;
594}
595
596
597int dim_stop_thread(long thread_id)
598{
599 int ret;
600
601 ret = TerminateThread((HANDLE)thread_id, 0);
602 CloseHandle((HANDLE)thread_id);
603 printf("dim_stop_thread: this function is obsolete, it creates memory leaks\n");
604 return ret;
605}
606
607
608void create_io_thread()
609{
610 int tcpip_task(void *);
611
612#ifndef STDCALL
613 hIO_thread = CreateThread(
614 NULL, /* no security attributes */
615 0, /* use default stack size */
616 (void *)tcpip_task, /* thread function */
617 0, /* argument to thread function */
618 0, /* use default creation flags */
619 &IO_thread); /* returns the thread identifier */
620#else
621 hIO_thread = CreateThread(
622 NULL, /* no security attributes */
623 0, /* use default stack size */
624 tcpip_task, /* thread function */
625 0, /* argument to thread function */
626 0, /* use default creation flags */
627 &IO_thread); /* returns the thread identifier */
628#endif
629}
630
631void create_alrm_thread()
632{
633
634 int dtq_task(void *);
635
636#ifndef STDCALL
637 hALRM_thread = CreateThread(
638 NULL,
639 0,
640 (void *)dtq_task,
641 0,
642 0,
643 &ALRM_thread);
644#else
645 hALRM_thread = CreateThread(
646 NULL,
647 0,
648 dtq_task,
649 0,
650 0,
651 &ALRM_thread);
652#endif
653}
654
655void dim_init_threads()
656{
657 static int done = 0;
658
659 if(!done)
660 {
661 hMAIN_thread = GetCurrentThread();
662 done = 1;
663 }
664}
665
666void dim_stop_threads()
667{
668 int i;
669 int n = 0;
670
671 for( i = 0; i< Curr_N_Conns; i++ )
672 {
673 if(Net_conns[i].channel != 0)
674 n++;
675 }
676 if(n)
677 return;
678 if(hIO_thread)
679 TerminateThread(hIO_thread, 0);
680 if(hALRM_thread)
681 TerminateThread(hALRM_thread, 0);
682 if(Global_DIM_mutex)
683 CloseHandle(Global_DIM_mutex);
684 if(Global_DIM_event_auto)
685 CloseHandle(Global_DIM_event_auto);
686 if(Global_DIM_event_manual)
687 CloseHandle(Global_DIM_event_manual);
688 hIO_thread = 0;
689 hALRM_thread = 0;
690 Global_DIM_mutex = 0;
691 Global_DIM_event_auto = 0;
692 Global_DIM_event_manual = 0;
693 dim_tcpip_stop();
694 dim_dtq_stop();
695}
696
697void dim_stop()
698{
699 dim_stop_threads();
700}
701
702int dim_set_scheduler_class(int pclass)
703{
704 HANDLE hProc;
705 int ret;
706 DWORD p;
707
708#ifndef PXI
709 hProc = GetCurrentProcess();
710
711 if(pclass == -1)
712 p = IDLE_PRIORITY_CLASS;
713/*
714 else if(pclass == -1)
715 p = BELOW_NORMAL_PRIORITY_CLASS;
716*/
717 else if(pclass == 0)
718 p = NORMAL_PRIORITY_CLASS;
719/*
720 else if(pclass == 1)
721 p == ABOVE_NORMAL_PRIORITY_CLASS;
722*/
723 else if(pclass == 1)
724 p = HIGH_PRIORITY_CLASS;
725 else if(pclass == 2)
726 p = REALTIME_PRIORITY_CLASS;
727 ret = SetPriorityClass(hProc, p);
728 if(ret)
729 return 1;
730 ret = GetLastError();
731 printf("ret = %x %d\n",ret, ret);
732 return 0;
733#else
734 return 0;
735#endif
736}
737
738int dim_get_scheduler_class(int *pclass)
739{
740 HANDLE hProc;
741 DWORD ret;
742
743#ifndef PXI
744 hProc = GetCurrentProcess();
745
746 ret = GetPriorityClass(hProc);
747 if(ret == 0)
748 return 0;
749 if(ret == IDLE_PRIORITY_CLASS)
750 *pclass = -1;
751/*
752 else if(ret == BELOW_NORMAL_PRIORITY_CLASS)
753 *pclass = -1;
754*/
755 else if(ret == NORMAL_PRIORITY_CLASS)
756 *pclass = 0;
757/*
758 else if(ret == ABOVE_NORMAL_PRIORITY_CLASS)
759 *pclass = 1;
760*/
761 else if(ret == HIGH_PRIORITY_CLASS)
762 *pclass = 1;
763 else if(ret == REALTIME_PRIORITY_CLASS)
764 *pclass = 2;
765 return 1;
766#else
767 *pclass = 0;
768 return 0;
769#endif
770}
771
772int dim_set_priority(int threadId, int prio)
773{
774 HANDLE id;
775 int ret, p;
776
777#ifndef PXI
778 if(threadId == 1)
779 id = hMAIN_thread;
780 else if(threadId == 2)
781 id = hIO_thread;
782 else if(threadId == 3)
783 id = hALRM_thread;
784
785 if(prio == -3)
786 p = THREAD_PRIORITY_IDLE;
787 if(prio == -2)
788 p = THREAD_PRIORITY_LOWEST;
789 if(prio == -1)
790 p = THREAD_PRIORITY_BELOW_NORMAL;
791 if(prio == 0)
792 p = THREAD_PRIORITY_NORMAL;
793 if(prio == 1)
794 p = THREAD_PRIORITY_ABOVE_NORMAL;
795 if(prio == 2)
796 p = THREAD_PRIORITY_HIGHEST;
797 if(prio == 3)
798 p = THREAD_PRIORITY_TIME_CRITICAL;
799
800 ret = SetThreadPriority(id, p);
801 if(ret)
802 return 1;
803 return 0;
804#else
805 return 0;
806#endif
807}
808
809int dim_get_priority(int threadId, int *prio)
810{
811 HANDLE id;
812 int ret, p;
813
814#ifndef PXI
815 if(threadId == 1)
816 id = hMAIN_thread;
817 else if(threadId == 2)
818 id = hIO_thread;
819 else if(threadId == 3)
820 id = hALRM_thread;
821
822 ret = GetThreadPriority(id);
823 if(ret == THREAD_PRIORITY_ERROR_RETURN)
824 return 0;
825 if(ret == THREAD_PRIORITY_IDLE)
826 p = -3;
827 if(ret == THREAD_PRIORITY_LOWEST)
828 p = -2;
829 if(ret == THREAD_PRIORITY_BELOW_NORMAL)
830 p = -1;
831 if(ret == THREAD_PRIORITY_NORMAL)
832 p = 0;
833 if(ret == THREAD_PRIORITY_ABOVE_NORMAL)
834 p = 1;
835 if(ret == THREAD_PRIORITY_HIGHEST)
836 p = 2;
837 if(ret == THREAD_PRIORITY_TIME_CRITICAL)
838 p = 3;
839 *prio = p;
840 return 1;
841#else
842 *prio = 0;
843 return 0;
844#endif
845}
846
847void dim_init()
848{
849}
850
851void dim_no_threads()
852{
853}
854
855int dim_wait()
856{
857 pause();
858 return(1);
859}
860
861void dim_lock()
862{
863 if(!Global_DIM_mutex)
864 {
865 Global_DIM_mutex = CreateMutex(NULL,FALSE,NULL);
866 }
867 WaitForSingleObject(Global_DIM_mutex, INFINITE);
868}
869
870void dim_unlock()
871{
872 ReleaseMutex(Global_DIM_mutex);
873}
874
875void dim_pause()
876{
877HANDLE handles[2];
878
879 if(!Global_DIM_event_auto)
880 {
881 Global_DIM_event_auto = CreateEvent(NULL,FALSE,FALSE,NULL);
882 Global_DIM_event_manual = CreateEvent(NULL,TRUE,FALSE,NULL);
883 }
884 else
885 {
886/*
887 WaitForSingleObject(Global_DIM_event, INFINITE);
888*/
889 handles[0] = Global_DIM_event_auto;
890 handles[1] = Global_DIM_event_manual;
891 WaitForMultipleObjects(2, handles, FALSE, INFINITE);
892 }
893}
894
895void dim_wake_up()
896{
897 if(Global_DIM_event_auto)
898 {
899 SetEvent(Global_DIM_event_auto);
900 }
901 if(Global_DIM_event_manual)
902 {
903 SetEvent(Global_DIM_event_manual);
904 ResetEvent(Global_DIM_event_manual);
905 }
906}
907
908void dim_sleep(unsigned int t)
909{
910 Sleep(t*1000);
911}
912
913void dim_win_usleep(unsigned int t)
914{
915 Sleep(t/1000);
916}
917
918#endif
Note: See TracBrowser for help on using the repository browser.