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