]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_lwp.c
a6998701343e805d4177b98c1b0a4419460adda8
[openldap] / libraries / libldap_r / thr_lwp.c
1 /*
2  * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted only
6  * as authorized by the OpenLDAP Public License.  A copy of this
7  * license is available at http://www.OpenLDAP.org/license.html or
8  * in file LICENSE in the top-level directory of the distribution.
9  */
10
11 /* thr_lwp.c - wrappers around SunOS LWP threads */
12
13 /* BUGS:
14  * - slurpd calls the get_stack/free_stack functions. Should be fixed, so
15  *   they can become static.
16  */
17
18 #include "portable.h"
19 #include "ldap_pvt_thread.h"
20
21 #if defined( HAVE_LWP )
22
23 /*************
24  *           *
25  * SunOS LWP *
26  *           *
27  *************/
28 #include <stdio.h>
29
30 #include <ac/time.h>
31 #include <ac/socket.h>
32
33 #include "lber.h"
34 #include "ldap.h"
35 #include "ldap_log.h"
36
37 #include <lwp/lwp.h>
38 #include <lwp/stackdep.h>
39
40 #define MAX_STACK       51200
41 #define MAX_THREADS     20
42
43 struct stackinfo {
44         int             stk_inuse;
45         stkalign_t      *stk_stack;
46 };
47
48 static struct stackinfo *stacks;
49
50 stkalign_t * ldap_pvt_thread_get_stack( int *stacknop )
51 {
52         int     i;
53
54         if ( stacks == NULL ) {
55                 stacks = (struct stackinfo *) ch_calloc( 1, MAX_THREADS *
56                     sizeof(struct stackinfo) );
57         }
58
59         for ( i = 0; i < MAX_THREADS; i++ ) {
60                 if ( stacks[i].stk_inuse == 0 ) {
61                         break;
62                 }
63         }
64
65         if ( i == MAX_THREADS ) {
66                 Debug( LDAP_DEBUG_ANY,
67                     "no more stacks (max %d) - increase MAX_THREADS for more",
68                     MAX_THREADS, 0, 0 );
69                 return( NULL );
70         }
71
72         if ( stacks[i].stk_stack == NULL ) {
73                 stacks[i].stk_stack = (stkalign_t *) malloc(
74                     (MAX_STACK / sizeof(stkalign_t) + 1 )
75                     * sizeof(stkalign_t) );
76         }
77
78         *stacknop = i;
79         stacks[i].stk_inuse = 1;
80         return( stacks[i].stk_stack + MAX_STACK / sizeof(stkalign_t) );
81 }
82
83 void
84 ldap_pvt_thread_free_stack( int stackno )
85 {
86         if ( stackno < 0 || stackno > MAX_THREADS ) {
87                 Debug( LDAP_DEBUG_ANY, "free_stack of bogus stack %d",
88                     stackno, 0, 0 );
89         }
90
91         stacks[stackno].stk_inuse = 0;
92 }
93
94 static void
95 lwp_create_stack( void *(*func)(), void *arg, int stackno )
96 {
97         (*func)( arg );
98
99         ldap_pvt_thread_free_stack( stackno );
100 }
101
102 int 
103 ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
104                        ldap_pvt_thread_attr_t *attr,
105                        void *(*start_routine)( void *), void *arg)
106 {
107         stkalign_t      *stack;
108         int             stackno;
109
110         if ( (stack = ldap_pvt_thread_get_stack( &stackno )) == NULL ) {
111                 return( -1 );
112         }
113         return( lwp_create( thread, lwp_create_stack, MINPRIO, 0, 
114                            stack, 3, start_routine, arg, stackno ) );
115 }
116
117 void 
118 ldap_pvt_thread_exit( void *retval )
119 {
120         lwp_destroy( SELF );
121 }
122
123 int 
124 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
125 {
126         lwp_join( thread );
127         return 0;
128 }
129
130 int 
131 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
132 {
133         return 0;
134 }
135
136 int 
137 ldap_pvt_thread_yield( void )
138 {
139         lwp_yield( SELF );
140         return 0;
141 }
142
143 int 
144 ldap_pvt_thread_attr_init( ldap_pvt_thread_attr_t *attr )
145 {
146         *attr = 0;
147         return( 0 );
148 }
149
150 int 
151 ldap_pvt_thread_attr_destroy( ldap_pvt_thread_attr_t *attr )
152 {
153         return( 0 );
154 }
155
156 int 
157 ldap_pvt_thread_attr_setdetachstate( ldap_pvt_thread_attr_t *attr, int dstate )
158 {
159         *attr = dstate;
160         return( 0 );
161 }
162
163 int
164 ldap_pvt_thread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
165 {
166         *detachstate = *attr;
167         return( 0 );
168 }
169
170 int 
171 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond, 
172                       ldap_pvt_thread_condattr_t *attr )
173 {
174         /*
175          * lwp cv_create requires the monitor id be passed in
176          * when the cv is created, pthreads passes it when the
177          * condition is waited for.  so, we fake the creation
178          * here and actually do it when the cv is waited for
179          * later.
180          */
181
182         cond->lcv_created = 0;
183
184         return( 0 );
185 }
186
187 int 
188 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
189 {
190         return( cond->lcv_created ? cv_notify( cv->lcv_cv ) : 0 );
191 }
192
193 int 
194 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
195                       ldap_pvt_thread_mutex_t *mutex )
196 {
197         if ( ! cond->lcv_created ) {
198                 cv_create( &cond->lcv_cv, *mutex );
199                 cond->lcv_created = 1;
200         }
201
202         return( cv_wait( cond->lcv_cv ) );      
203 }
204
205 int 
206 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex,
207                        ldap_pvt_thread_mutexattr_t *attr )
208 {
209         return( mon_create( mutex ) );
210 }
211
212 int 
213 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
214 {
215         return( mon_destroy( *mutex ) );
216 }
217
218 int 
219 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
220 {
221         return( mon_enter( *mutex ) );
222 }
223
224 int 
225 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
226 {
227         return( mon_exit( *mutex ) );
228 }
229
230 int
231 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
232 {
233         return( mon_cond_enter( *mp ) );
234 }
235
236 int
237 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
238 {
239         return( cv->lcv_created ? cv_destroy( cv->lcv_cv ) : 0 );
240 }
241
242 int
243 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
244 {
245         return( cv->lcv_created ? cv_broadcast( cv->lcv_cv ) : 0 );
246 }
247
248 #endif /* HAVE_LWP */