]> git.sur5r.net Git - openldap/blob - libraries/liblthread/thread.c
Add basic NT thread support.
[openldap] / libraries / liblthread / thread.c
1 /* thread.c - glue routines to provide a consistent thread interface */
2
3 #include "portable.h"
4
5 #include <lthread.h>
6
7 #if defined( HAVE_PTHREADS )
8
9 #ifndef HAVE_PTHREAD_KILL
10 /***********************************************************************
11  *                                                                     *
12  * pthreads package with DCE - no mapping to do (except to create a    *
13  * pthread_kill() routine)                                             *
14  *                                                                     *
15  ***********************************************************************/
16
17 /* ARGSUSED */
18 void
19 pthread_kill( pthread_t tid, int sig )
20 {
21         kill( getpid(), sig );
22 }
23 #endif /* HAVE_PTHREAD_KILL */
24
25 #elif defined( HAVE_MACH_CTHREADS )
26
27 /***********************************************************************
28  *                                                                     *
29  * under NEXTSTEP or OPENSTEP use CThreads                             *
30  * lukeh@xedoc.com.au                                                  *
31  *                                                                     *
32  ***********************************************************************/
33
34 int
35 pthread_attr_init( pthread_attr_t *attr )
36 {
37         *attr = 0;
38         return( 0 );
39 }
40
41 int
42 pthread_attr_destroy( pthread_attr_t *attr )
43 {
44         return( 0 );
45 }
46
47 int
48 pthread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
49 {
50         *detachstate = *attr;
51         return( 0 );
52 }
53
54 int
55 pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )
56 {
57         *attr = detachstate;
58         return( 0 );
59 }
60
61 /* ARGSUSED */
62 int
63 pthread_create(
64     pthread_t           *tid,
65     pthread_attr_t      *attr,
66     VFP                 func,
67     void                *arg
68 )
69 {
70         *tid = cthread_fork(func, arg);
71          return ( *tid == NULL ? -1 : 0 );
72 }
73
74 void
75 pthread_yield( void )
76 {
77         cthread_yield();
78 }
79
80 void
81 pthread_exit( any_t a )
82 {
83         cthread_exit( a );
84 }
85
86 void
87 pthread_join( pthread_t tid, int *pStatus )
88 {
89         int status;
90         status = (int) cthread_join ( tid );
91         if (pStatus != NULL)
92                 {
93                 *pStatus = status;
94                 }
95 }
96
97 /* ARGSUSED */
98 void
99 pthread_kill( pthread_t tid, int sig )
100 {
101         return;
102 }
103
104 /* ARGSUSED */
105 int
106 pthread_mutex_init( pthread_mutex_t *mp, pthread_mutexattr_t *attr )
107 {
108         mutex_init( mp );
109         mp->name = NULL;
110         return ( 0 );
111 }
112
113 int
114 pthread_mutex_destroy( pthread_mutex_t *mp )
115 {
116         mutex_clear( mp );
117         return ( 0 );
118 }
119
120 int
121 pthread_mutex_lock( pthread_mutex_t *mp )
122 {
123         mutex_lock( mp );
124         return ( 0 );
125 }
126
127 int
128 pthread_mutex_unlock( pthread_mutex_t *mp )
129 {
130         mutex_unlock( mp );
131         return ( 0 );
132 }
133
134 int
135 pthread_mutex_trylock( pthread_mutex_t *mp )
136 {
137         return mutex_try_lock( mp );
138 }
139
140 int
141 pthread_cond_init( pthread_cond_t *cv, pthread_condattr_t *attr )
142 {
143         condition_init( cv );
144         return( 0 );
145 }
146
147 int
148 pthread_cond_destroy( pthread_cond_t *cv )
149 {
150         condition_clear( cv );
151         return( 0 );
152 }
153
154 int
155 pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mp )
156 {
157         condition_wait( cv, mp );
158         return( 0 );
159 }
160
161 int
162 pthread_cond_signal( pthread_cond_t *cv )
163 {
164         condition_signal( cv );
165         return( 0 );
166 }
167
168 int
169 pthread_cond_broadcast( pthread_cond_t *cv )
170 {
171         condition_broadcast( cv );
172         return( 0 );
173 }
174
175 #elif defined( HAVE_THR )
176
177 /*******************
178  *                 *
179  * Solaris Threads *
180  *                 *
181  *******************/
182
183 int
184 pthread_attr_init( pthread_attr_t *attr )
185 {
186         *attr = 0;
187         return( 0 );
188 }
189
190 int
191 pthread_attr_destroy( pthread_attr_t *attr )
192 {
193         *attr = 0;
194         return( 0 );
195 }
196
197 int
198 pthread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
199 {
200         *detachstate = *attr;
201         return( 0 );
202 }
203
204 int
205 pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )
206 {
207         *attr = detachstate;
208         return( 0 );
209 }
210
211 /* ARGSUSED */
212 int
213 pthread_create(
214     pthread_t           *tid,
215     pthread_attr_t      *attr,
216     VFP                 func,
217     void                *arg
218 )
219 {
220         return( thr_create( NULL, 0, func, arg, *attr, tid ) );
221 }
222
223 void
224 pthread_yield( void )
225 {
226         thr_yield();
227 }
228
229 void
230 pthread_exit()
231 {
232         thr_exit( NULL );
233 }
234
235 void
236 pthread_join( pthread_t tid, int *status )
237 {
238         thr_join( tid, NULL, (void **) status );
239 }
240
241 void
242 pthread_kill( pthread_t tid, int sig )
243 {
244         thr_kill( tid, sig );
245 }
246
247 /* ARGSUSED */
248 int
249 pthread_mutex_init( pthread_mutex_t *mp, pthread_mutexattr_t *attr )
250 {
251         return( mutex_init( mp, attr ? *attr : USYNC_THREAD, NULL ) );
252 }
253
254 int
255 pthread_mutex_destroy( pthread_mutex_t *mp )
256 {
257         return( mutex_destroy( mp ) );
258 }
259
260 int
261 pthread_mutex_lock( pthread_mutex_t *mp )
262 {
263         return( mutex_lock( mp ) );
264 }
265
266 int
267 pthread_mutex_unlock( pthread_mutex_t *mp )
268 {
269         return( mutex_unlock( mp ) );
270 }
271
272 int
273 pthread_mutex_trylock( pthread_mutex_t *mp )
274 {
275         return( mutex_trylock( mp ) );
276 }
277
278 int
279 pthread_cond_init( pthread_cond_t *cv, pthread_condattr_t *attr )
280 {
281         return( cond_init( cv, attr ? *attr : USYNC_THREAD, NULL ) );
282 }
283
284 int
285 pthread_cond_destroy( pthread_cond_t *cv )
286 {
287         return( cond_destroy( cv ) );
288 }
289
290 int
291 pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mp )
292 {
293         return( cond_wait( cv, mp ) );
294 }
295
296 int
297 pthread_cond_signal( pthread_cond_t *cv )
298 {
299         return( cond_signal( cv ) );
300 }
301
302 int
303 pthread_cond_broadcast( pthread_cond_t *cv )
304 {
305         return( cond_broadcast( cv ) );
306 }
307
308 #elif defined( HAVE_LWP )
309
310 /*************
311  *           *
312  * SunOS LWP *
313  *           *
314  *************/
315
316 int
317 pthread_attr_init( pthread_attr_t *attr )
318 {
319         *attr = 0;
320         return( 0 );
321 }
322
323 int
324 pthread_attr_destroy( pthread_attr_t *attr )
325 {
326         return( 0 );
327 }
328
329 int
330 pthread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
331 {
332         *detachstate = *attr;
333         return( 0 );
334 }
335
336 int
337 pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )
338 {
339         *attr = detachstate;
340         return( 0 );
341 }
342
343 static void
344 lwp_create_stack( VFP func, void *arg, int stackno )
345 {
346         (*func)( arg );
347
348         free_stack( stackno );
349 }
350
351 /* ARGSUSED */
352 int
353 pthread_create(
354     pthread_t           *tid,
355     pthread_attr_t      *attr,
356     VFP                 func,
357     void                *arg
358 )
359 {
360         stkalign_t      *stack;
361         int             stackno;
362
363         if ( (stack = get_stack( &stackno )) == NULL ) {
364                 return( -1 );
365         }
366         return( lwp_create( tid, lwp_create_stack, MINPRIO, 0, stack, 3, func,
367             arg, stackno ) );
368 }
369
370 void
371 pthread_yield( void )
372 {
373         lwp_yield( SELF );
374 }
375
376 void
377 pthread_exit()
378 {
379         lwp_destroy( SELF );
380 }
381
382 void
383 pthread_join( pthread_t tid, int *status )
384 {
385         lwp_join( tid );
386 }
387
388 /* ARGSUSED */
389 void
390 pthread_kill( pthread_t tid, int sig )
391 {
392         return;
393 }
394
395 /* ARGSUSED */
396 int
397 pthread_mutex_init( pthread_mutex_t *mp, pthread_mutexattr_t *attr )
398 {
399         return( mon_create( mp ) );
400 }
401
402 int
403 pthread_mutex_destroy( pthread_mutex_t *mp )
404 {
405         return( mon_destroy( *mp ) );
406 }
407
408 int
409 pthread_mutex_lock( pthread_mutex_t *mp )
410 {
411         return( mon_enter( *mp ) );
412 }
413
414 int
415 pthread_mutex_unlock( pthread_mutex_t *mp )
416 {
417         return( mon_exit( *mp ) );
418 }
419
420 int
421 pthread_mutex_trylock( pthread_mutex_t *mp )
422 {
423         return( mon_cond_enter( *mp ) );
424 }
425
426 int
427 pthread_cond_init( pthread_cond_t *cv, pthread_condattr_t *attr )
428 {
429         /*
430          * lwp cv_create requires the monitor id be passed in
431          * when the cv is created, pthreads passes it when the
432          * condition is waited for.  so, we fake the creation
433          * here and actually do it when the cv is waited for
434          * later.
435          */
436
437         cv->lcv_created = 0;
438
439         return( 0 );
440 }
441
442 int
443 pthread_cond_destroy( pthread_cond_t *cv )
444 {
445         return( cv->lcv_created ? cv_destroy( cv->lcv_cv ) : 0 );
446 }
447
448 int
449 pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mp )
450 {
451         if ( ! cv->lcv_created ) {
452                 cv_create( &cv->lcv_cv, *mp );
453                 cv->lcv_created = 1;
454         }
455
456         return( cv_wait( cv->lcv_cv ) );
457 }
458
459 int
460 pthread_cond_signal( pthread_cond_t *cv )
461 {
462         return( cv->lcv_created ? cv_notify( cv->lcv_cv ) : 0 );
463 }
464
465 int
466 pthread_cond_broadcast( pthread_cond_t *cv )
467 {
468         return( cv->lcv_created ? cv_broadcast( cv->lcv_cv ) : 0 );
469 }
470
471
472 #elif defined( HAVE_NT_MULTITHREADS )
473
474 #include <process.h>
475 #include <winsock2.h>
476
477 int
478 pthread_attr_init( pthread_attr_t *attr )
479 {
480         *attr = 0;
481         return( 0 );
482 }
483
484 int
485 pthread_attr_destroy( pthread_attr_t *attr )
486 {
487         return( 0 );
488 }
489
490 int
491 pthread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
492 {
493         *detachstate = *attr;
494         return( 0 );
495 }
496
497 int
498 pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )
499 {
500         *attr = detachstate;
501         return( 0 );
502 }
503
504 int
505 pthread_create(
506     pthread_t           *tid,
507     pthread_attr_t      *attr,
508     VFP                 func,
509     void                *arg
510 )
511 {
512         *tid = (pthread_t)_beginthread( (void *) func, 0, arg );
513          return ( (unsigned long)*tid == -1 ? -1 : 0 );
514 }
515
516 void
517 pthread_yield()
518 {
519
520 }
521
522 void
523 pthread_exit( void )
524 {
525         _endthread( );
526 }
527
528 void
529 pthread_join( pthread_t tid, int *pStatus )
530 {
531         DWORD status;
532         status = WaitForSingleObject( tid, INFINITE );
533         if ( pStatus != NULL)
534         {
535                 if ( status != WAIT_FAILED )
536                         *pStatus = 0;
537                 else
538                         *pStatus = WAIT_ABANDONED;
539         }
540 }
541
542
543 void
544 pthread_kill( pthread_t tid, int sig )
545 {
546         return;
547 }
548
549
550 int
551 pthread_mutex_init( pthread_mutex_t *mp, pthread_mutexattr_t *attr )
552 {
553         *mp = CreateMutex( NULL, 0, NULL );
554         return ( 0 );
555 }
556
557 int
558 pthread_mutex_destroy( pthread_mutex_t *mp )
559 {
560         CloseHandle( *mp );
561         return ( 0 );
562 }
563
564 int
565 pthread_mutex_lock( pthread_mutex_t *mp )
566 {
567         WaitForSingleObject( *mp, INFINITE );
568         return ( 0 );
569 }
570
571 int
572 pthread_mutex_unlock( pthread_mutex_t *mp )
573 {
574         ReleaseMutex( *mp );
575         return ( 0 );
576 }
577
578 int
579 pthread_mutex_trylock( pthread_mutex_t *mp )
580 {
581         DWORD status;
582
583         status = WaitForSingleObject( *mp, 0 );
584         if ( (status == WAIT_FAILED) || (status == WAIT_TIMEOUT) )
585                 return 0;
586         else
587                 return 1;
588 }
589
590 int
591 pthread_cond_init( pthread_cond_t *cv, pthread_condattr_t *attr )
592 {
593         *cv = CreateEvent( NULL, FALSE, FALSE, NULL );
594         return( 0 );
595 }
596
597 int
598 pthread_cond_destroy( pthread_cond_t *cv )
599 {
600         CloseHandle( *cv );
601         return( 0 );
602 }
603
604 int
605 pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mp )
606 {
607         ReleaseMutex( *mp );
608         WaitForSingleObject( *cv, INFINITE );
609         WaitForSingleObject( *mp, INFINITE );
610         return( 0 );
611 }
612
613 int
614 pthread_cond_signal( pthread_cond_t *cv )
615 {
616         SetEvent( *cv );
617         return( 0 );
618 }
619
620 int
621 pthread_cond_broadcast( pthread_cond_t *cv )
622 {
623         SetEvent( *cv );
624         return( 0 );
625 }
626
627 #else
628
629 /***********************************************************************
630  *                                                                     *
631  * no threads package defined for this system - fake ok returns from   *
632  * all threads routines (making it single-threaded).                   *
633  *                                                                     *
634  ***********************************************************************/
635
636 /* ARGSUSED */
637 int
638 pthread_attr_init( pthread_attr_t *attr )
639 {
640         return( 0 );
641 }
642
643 /* ARGSUSED */
644 int
645 pthread_attr_destroy( pthread_attr_t *attr )
646 {
647         return( 0 );
648 }
649
650 /* ARGSUSED */
651 int
652 pthread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
653 {
654         return( 0 );
655 }
656
657 /* ARGSUSED */
658 int
659 pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )
660 {
661         return( 0 );
662 }
663
664 /* ARGSUSED */
665 int
666 pthread_create(
667     pthread_t           *tid,
668     pthread_attr_t      *attr,
669     VFP                 func,
670     void                *arg
671 )
672 {
673         (*func)( arg );
674
675         return( 0 );
676 }
677
678 void
679 pthread_yield( void )
680 {
681         return;
682 }
683
684 void
685 pthread_exit()
686 {
687         return;
688 }
689
690 /* ARGSUSED */
691 void
692 pthread_kill( pthread_t tid, int sig )
693 {
694         return;
695 }
696
697 void
698 pthread_join( pthread_t tid, int *status )
699 {
700         return;
701 }
702
703 /* ARGSUSED */
704 int
705 pthread_mutex_init( pthread_mutex_t *mp, pthread_mutexattr_t *attr )
706 {
707         return( 0 );
708 }
709
710 /* ARGSUSED */
711 int
712 pthread_mutex_destroy( pthread_mutex_t *mp )
713 {
714         return( 0 );
715 }
716
717 /* ARGSUSED */
718 int
719 pthread_mutex_lock( pthread_mutex_t *mp )
720 {
721         return( 0 );
722 }
723
724 /* ARGSUSED */
725 int
726 pthread_mutex_unlock( pthread_mutex_t *mp )
727 {
728         return( 0 );
729 }
730
731 /* ARGSUSED */
732 int
733 pthread_mutex_trylock( pthread_mutex_t *mp )
734 {
735         return( 0 );
736 }
737
738 /* ARGSUSED */
739 int
740 pthread_cond_init( pthread_cond_t *cv, pthread_condattr_t *attr )
741 {
742         return( 0 );
743 }
744
745 /* ARGSUSED */
746 int
747 pthread_cond_destroy( pthread_cond_t *cv )
748 {
749         return( 0 );
750 }
751
752 /* ARGSUSED */
753 int
754 pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mp )
755 {
756         return( 0 );
757 }
758
759 /* ARGSUSED */
760 int
761 pthread_cond_signal( pthread_cond_t *cv )
762 {
763         return( 0 );
764 }
765
766 /* ARGSUSED */
767 int
768 pthread_cond_broadcast( pthread_cond_t *cv )
769 {
770         return( 0 );
771 }
772
773 #endif /* no threads package */