From a6a6946a67202271c2434067abd0d0d15168c667 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 12 Apr 2003 04:01:40 +0000 Subject: [PATCH] New ldap_pvt_thread_pool_context() --- include/ldap_pvt_thread.h | 3 +- libraries/libldap_r/tpool.c | 89 +++++++++++++++++++-------------- servers/slapd/back-bdb/cache.c | 2 +- servers/slapd/slapi/slapi_ops.c | 2 +- 4 files changed, 54 insertions(+), 42 deletions(-) diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index d02359ad9e..ca4a2c5585 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -188,8 +188,7 @@ ldap_pvt_thread_pool_setkey LDAP_P(( ldap_pvt_thread_pool_keyfree_t *kfree )); LDAP_F( void *) -ldap_pvt_thread_pool_context LDAP_P(( - ldap_pvt_thread_pool_t *pool )); +ldap_pvt_thread_pool_context LDAP_P(( void )); LDAP_END_DECL diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index f9ecded4d5..c6eeed959c 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -41,6 +41,13 @@ typedef struct ldap_int_thread_key_s { * We don't expect to use many... */ #define MAXKEYS 32 +#define MAXTHREADS 1024 /* must be a power of 2 */ + +static struct { + ldap_pvt_thread_t id; + ldap_int_thread_key_t *ctx; +} thread_keys[MAXTHREADS]; + typedef struct ldap_int_thread_ctx_s { union { @@ -50,8 +57,6 @@ typedef struct ldap_int_thread_ctx_s { } ltc_next; ldap_pvt_thread_start_t *ltc_start_routine; void *ltc_arg; - ldap_pvt_thread_t ltc_thread_id; - ldap_int_thread_key_t *ltc_key; } ldap_int_thread_ctx_t; struct ldap_int_thread_pool_s { @@ -225,11 +230,22 @@ ldap_pvt_thread_pool_submit ( ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); if (need_thread) { - int rc = ldap_pvt_thread_create( &thr, 1, - ldap_int_thread_pool_wrapper, pool ); + int rc; + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + + rc = ldap_pvt_thread_create( &thr, 1, + ldap_int_thread_pool_wrapper, pool ); if (rc == 0) { pool->ltp_starting--; + + /* assign this thread ID to a key slot; start + * at the thread ID itself (mod MAXTHREADS) and + * look for an empty slot. + */ + for (rc = thr & (MAXTHREADS-1); thread_keys[rc].id; + rc = (rc+1) & (MAXTHREADS-1)); + thread_keys[rc].id = thr; } else { /* couldn't create thread. back out of * ltp_open_count and check for even worse things. @@ -370,7 +386,8 @@ ldap_int_thread_pool_wrapper ( struct ldap_int_thread_pool_s *pool = xpool; ldap_int_thread_ctx_t *ctx; ldap_int_thread_key_t ltc_key[MAXKEYS]; - int i; + ldap_pvt_thread_t tid; + int i, keyslot; if (pool == NULL) return NULL; @@ -379,8 +396,16 @@ ldap_int_thread_pool_wrapper ( ltc_key[i].ltk_key = NULL; } + tid = ldap_pvt_thread_self(); + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + /* store pointer to our keys */ + for (i = tid & (MAXTHREADS-1); thread_keys[i].id != tid; + i = (i+1) & (MAXTHREADS-1)); + thread_keys[i].ctx = ltc_key; + keyslot = i; + while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) { ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list); if (ctx) { @@ -416,15 +441,11 @@ ldap_int_thread_pool_wrapper ( pool->ltp_pending_count--; - ctx->ltc_key = ltc_key; - ctx->ltc_thread_id = ldap_pvt_thread_self(); - LDAP_SLIST_INSERT_HEAD(&pool->ltp_active_list, ctx, ltc_next.al); pool->ltp_active_count++; ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - ctx->ltc_start_routine(ctx, ctx->ltc_arg); - ctx->ltc_key = NULL; + ctx->ltc_start_routine(ltc_key, ctx->ltc_arg); ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); LDAP_SLIST_REMOVE(&pool->ltp_active_list, ctx, @@ -449,6 +470,9 @@ ldap_int_thread_pool_wrapper ( ltc_key[i].ltk_data ); } + thread_keys[keyslot].ctx = NULL; + thread_keys[keyslot].id = 0; + pool->ltp_open_count--; ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); @@ -462,15 +486,15 @@ int ldap_pvt_thread_pool_getkey( void **data, ldap_pvt_thread_pool_keyfree_t **kfree ) { - ldap_int_thread_ctx_t *ctx = xctx; + ldap_int_thread_key_t *ctx = xctx; int i; - if ( !ctx || !data || !ctx->ltc_key ) return EINVAL; + if ( !ctx || !data ) return EINVAL; - for ( i=0; iltc_key[i].ltk_key; i++ ) { - if ( ctx->ltc_key[i].ltk_key == key ) { - *data = ctx->ltc_key[i].ltk_data; - if ( kfree ) *kfree = ctx->ltc_key[i].ltk_free; + for ( i=0; iltc_key ) return EINVAL; + if ( !ctx || !key ) return EINVAL; for ( i=0; iltc_key[i].ltk_key || ctx->ltc_key[i].ltk_key == key ) { - ctx->ltc_key[i].ltk_key = key; - ctx->ltc_key[i].ltk_data = data; - ctx->ltc_key[i].ltk_free = kfree; + if ( !ctx[i].ltk_key || ctx[i].ltk_key == key ) { + ctx[i].ltk_key = key; + ctx[i].ltk_data = data; + ctx[i].ltk_free = kfree; return 0; } } @@ -506,28 +530,17 @@ int ldap_pvt_thread_pool_setkey( * for the application to keep track of the thread context * handles itself. */ -void *ldap_pvt_thread_pool_context( ldap_pvt_thread_pool_t *tpool ) +void *ldap_pvt_thread_pool_context( ) { - ldap_pvt_thread_pool_t pool; ldap_pvt_thread_t tid; - ldap_int_thread_ctx_t *ptr; - - pool = *tpool; - if (pool == NULL) { - return NULL; - } + int i; tid = ldap_pvt_thread_self(); - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - LDAP_SLIST_FOREACH(ptr, &pool->ltp_active_list, ltc_next.al) - if (ptr != NULL && ptr->ltc_thread_id == tid) break; - if (ptr != NULL && ptr->ltc_thread_id != tid) { - ptr = NULL; - } - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + for (i = tid & (MAXTHREADS-1); thread_keys[i].id && + thread_keys[i].id != tid; i = (i+1) & (MAXTHREADS-1)); - return ptr; + return thread_keys[i].ctx; } #endif /* LDAP_HAVE_THREAD_POOL */ diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index 7bbabf8457..eec734a565 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -1151,7 +1151,7 @@ bdb_locker_id( Operation *op, DB_ENV *env, int *locker ) if ( op ) { ctx = op->o_threadctx; } else { - ctx = ldap_pvt_thread_pool_context( &connection_pool ); + ctx = ldap_pvt_thread_pool_context(); } /* Shouldn't happen unless we're single-threaded */ diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index bc1e84cea8..0cc32804d4 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -156,7 +156,7 @@ slapiConnectionInit( c->c_pending_ops.stqh_first->o_authmech.bv_len = 0; c->c_pending_ops.stqh_first->o_time = slap_get_time(); c->c_pending_ops.stqh_first->o_do_not_cache = 1; - c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool ); + c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context(); c->c_pending_ops.stqh_first->o_tmpmemctx = NULL; c->c_pending_ops.stqh_first->o_tmpmfuncs = &ch_mfuncs; c->c_pending_ops.stqh_first->o_conn = c; -- 2.39.5