2 * Copyright (c) 1996 Regents of the University of Michigan.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of Michigan at Ann Arbor. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
14 * ldap_pvt_thread_sleep.c - allow a thread to sleep without putting
15 * the whole process (e.g. pod under lwp) to sleep.
17 * Contains platform-specific code to allow this:
19 * Under non-preemptive threads packages like SunOS lwp, tsleep() adds
20 * the thread to a list of sleepers. The lwp_scheduler process takes
21 * care of resuming suspended threads.
23 * Under a fully-preemptive threads package, like Solaris threads,
24 * tsleep just calls sleep(), and there is no scheduler thread. Life
25 * is so much simpler...
32 #include <ac/unistd.h> /* get sleep() */
34 #include "ldap_pvt_thread.h"
36 #if !defined( HAVE_LWP )
39 * Here we assume we have fully preemptive threads and that sleep()
40 * does the right thing.
43 ldap_pvt_thread_sleep(
54 ldap_pvt_thread_sleep(
63 if ( lwp_self( &mylwp ) < 0 ) {
69 mon_enter( &sglob->tsl_mon );
71 if ( sglob->tsl_list != NULL ) {
72 for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
73 if ( SAMETHREAD( t->tl_tid, mylwp )) {
74 /* We're already sleeping? */
75 t->tl_wake = now + interval;
76 mon_exit( &sglob->tsl_mon );
83 nt = (tl_t *) malloc( sizeof( tl_t ));
85 nt->tl_next = sglob->tsl_list;
86 nt->tl_wake = now + interval;
90 mon_exit( &sglob->tsl_mon );
97 * The lwp_scheduler thread periodically checks to see if any threads
98 * are due to be resumed. If there are, it resumes them. Otherwise,
99 * it computes the lesser of ( 1 second ) or ( the minimum time until
100 * a thread need to be resumed ) and puts itself to sleep for that amount
109 struct timeval interval;
112 while ( !sglob->slurpd_shutdown ) {
113 mon_enter( &sglob->tsl_mon );
117 if ( sglob->tsl_list != NULL ) {
118 for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
119 if (( t->tl_wake > 0L ) && ( t->tl_wake < now )) {
120 lwp_resume( t->tl_tid );
124 if (( t->tl_wake > now ) && ( t->tl_wake < min )) {
130 mon_exit( &sglob->tsl_mon );
132 interval.tv_usec = 0L;
134 interval.tv_sec = 1L;
136 interval.tv_sec = min;
139 lwp_sleep( &interval );
142 mon_enter( &sglob->tsl_mon );
144 for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
145 lwp_resume( t->tl_tid );
148 mon_exit( &sglob->tsl_mon );
150 free_stack( stackno );
153 #endif /* HAVE_LWP */