X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap_r%2Fthr_lwp.c;h=e9b16a4aff861224238a48b6759d2fb51e529200;hb=319440033f01e6939de0ec70689cd9325d7bcdee;hp=27be3a8d19250fbbe26dec02c32d5718996bc002;hpb=a0b741102d939c2fd2f6ae50e91af6904f53798f;p=openldap diff --git a/libraries/libldap_r/thr_lwp.c b/libraries/libldap_r/thr_lwp.c index 27be3a8d19..e9b16a4aff 100644 --- a/libraries/libldap_r/thr_lwp.c +++ b/libraries/libldap_r/thr_lwp.c @@ -1,5 +1,6 @@ +/* $OpenLDAP$ */ /* - * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA + * Copyright 1998-2002 The OpenLDAP Foundation, Redwood City, California, USA * All rights reserved. * * Redistribution and use in source and binary forms are permitted only @@ -16,7 +17,6 @@ */ #include "portable.h" -#include "ldap_pvt_thread.h" #if defined( HAVE_LWP ) @@ -25,14 +25,17 @@ * SunOS LWP * * * *************/ + +/* This implementation NEEDS WORK. It currently does not compile */ + #include #include #include -#include "lber.h" -#include "ldap.h" -#include "ldap_log.h" +#include "ldap-int.h" + +#include "ldap_pvt_thread.h" #include #include @@ -44,7 +47,7 @@ * Initialize LWP by spinning of a schedular */ int -ldap_pvt_thread_initialize( void ) +ldap_int_thread_initialize( void ) { thread_t tid; stkalign_t *stack; @@ -58,6 +61,14 @@ ldap_pvt_thread_initialize( void ) return 0; } +int +ldap_int_thread_destroy( void ) +{ + /* need to destory lwp_scheduler thread and clean up private + variables */ + return 0; +} + struct stackinfo { int stk_inuse; stkalign_t *stk_stack; @@ -65,13 +76,19 @@ struct stackinfo { static struct stackinfo *stacks; -stkalign_t * ldap_pvt_thread_get_stack( int *stacknop ) +static stkalign_t * ldap_int_thread_get_stack( int *stacknop ) { int i; if ( stacks == NULL ) { - stacks = (struct stackinfo *) ch_calloc( 1, MAX_THREADS * + stacks = (struct stackinfo *) LDAP_CALLOC( 1, MAX_THREADS * sizeof(struct stackinfo) ); + + if( stacks == NULL ) { + Debug( LDAP_DEBUG_ANY, "stacks allocation failed", + 0, 0, 0 ); + return NULL; + } } for ( i = 0; i < MAX_THREADS; i++ ) { @@ -88,9 +105,15 @@ stkalign_t * ldap_pvt_thread_get_stack( int *stacknop ) } if ( stacks[i].stk_stack == NULL ) { - stacks[i].stk_stack = (stkalign_t *) malloc( + stacks[i].stk_stack = (stkalign_t *) LDAP_MALLOC( (MAX_STACK / sizeof(stkalign_t) + 1 ) * sizeof(stkalign_t) ); + + if( stacks[i].stk_stack == NULL ) { + Debug( LDAP_DEBUG_ANY, "stack allocation failed", + 0, 0, 0 ); + return( NULL ); + } } *stacknop = i; @@ -98,8 +121,8 @@ stkalign_t * ldap_pvt_thread_get_stack( int *stacknop ) return( stacks[i].stk_stack + MAX_STACK / sizeof(stkalign_t) ); } -void -ldap_pvt_thread_free_stack( int stackno ) +static void +ldap_int_thread_free_stack( int stackno ) { if ( stackno < 0 || stackno > MAX_THREADS ) { Debug( LDAP_DEBUG_ANY, "free_stack of bogus stack %d\n", @@ -114,7 +137,7 @@ lwp_create_stack( void *(*func)(), void *arg, int stackno ) { (*func)( arg ); - ldap_pvt_thread_free_stack( stackno ); + ldap_int_thread_free_stack( stackno ); } int @@ -126,7 +149,7 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread, stkalign_t *stack; int stackno; - if ( (stack = ldap_pvt_thread_get_stack( &stackno )) == NULL ) { + if ( (stack = ldap_int_thread_get_stack( &stackno )) == NULL ) { return( -1 ); } return( lwp_create( thread, lwp_create_stack, MINPRIO, 0, @@ -139,6 +162,108 @@ ldap_pvt_thread_exit( void *retval ) lwp_destroy( SELF ); } +unsigned int +ldap_pvt_thread_sleep( + unsigned int interval +) +{ + thread_t mylwp; + tl_t *t, *nt; + time_t now; + + + if ( lwp_self( &mylwp ) < 0 ) { + return -1; + } + + time( &now ); + + mon_enter( &sglob->tsl_mon ); + + if ( sglob->tsl_list != NULL ) { + for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) { + if ( SAMETHREAD( t->tl_tid, mylwp )) { + /* We're already sleeping? */ + t->tl_wake = now + interval; + mon_exit( &sglob->tsl_mon ); + lwp_suspend( mylwp ); + return 0; + } + } + } + + nt = (tl_t *) LDAP_MALLOC( sizeof( tl_t )); + + if( nt == NULL ) return -1; + + nt->tl_next = sglob->tsl_list; + nt->tl_wake = now + interval; + nt->tl_tid = mylwp; + sglob->tsl_list = nt; + + mon_exit( &sglob->tsl_mon ); + + lwp_suspend( mylwp ); + return 0; +} + +/* + * The lwp_scheduler thread periodically checks to see if any threads + * are due to be resumed. If there are, it resumes them. Otherwise, + * it computes the lesser of ( 1 second ) or ( the minimum time until + * a thread need to be resumed ) and puts itself to sleep for that amount + * of time. + */ +static void +lwp_scheduler( + int stackno +) +{ + time_t now, min; + struct timeval interval; + tl_t *t; + + while ( !sglob->slurpd_shutdown ) { + mon_enter( &sglob->tsl_mon ); + + time( &now ); + min = 0L; + if ( sglob->tsl_list != NULL ) { + for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) { + if (( t->tl_wake > 0L ) && ( t->tl_wake < now )) { + lwp_resume( t->tl_tid ); + t->tl_wake = 0L; + } + + if (( t->tl_wake > now ) && ( t->tl_wake < min )) { + min = t->tl_wake; + } + } + } + + mon_exit( &sglob->tsl_mon ); + + interval.tv_usec = 0L; + if ( min == 0L ) { + interval.tv_sec = 1L; + } else { + interval.tv_sec = min; + } + + lwp_sleep( &interval ); + } + + mon_enter( &sglob->tsl_mon ); + + for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) { + lwp_resume( t->tl_tid ); + } + + mon_exit( &sglob->tsl_mon ); + + free_stack( stackno ); +} + int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { @@ -183,7 +308,7 @@ ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) int ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, - ldap_pvt_thread_mutex_t *mutex ) + ldap_int_thread_mutex_t *mutex ) { if ( ! cond->lcv_created ) { cv_create( &cond->lcv_cv, *mutex );