ITS#5364, thread pool efficiency:

Add ldap_pvt_thread_pool_pausing(): pause check for slapd without locking.
Make counters int instead of long; INT_MAX pending tasks is enough.
Nitpick cleanup: goto failure instead of if() to not-failure in _submit().
This commit is contained in:
Hallvard Furuseth 2008-02-10 16:15:30 +00:00
parent 68316527c4
commit 6dd87bb83f

View File

@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <ac/signal.h>
#include <ac/stdarg.h> #include <ac/stdarg.h>
#include <ac/stdlib.h> #include <ac/stdlib.h>
#include <ac/string.h> #include <ac/string.h>
@ -106,15 +107,17 @@ struct ldap_int_thread_pool_s {
ldap_int_thread_pool_state_t ltp_state; ldap_int_thread_pool_state_t ltp_state;
/* some active request needs to be the sole active request */ /* Some active task needs to be the sole active task.
int ltp_pause; * Atomic variable so ldap_pvt_thread_pool_pausing() can read it.
*/
volatile sig_atomic_t ltp_pause;
long ltp_max_count; /* max number of threads in pool, or 0 */ int ltp_max_count; /* Max number of threads in pool, or 0 */
long ltp_max_pending; /* max pending or paused requests, or 0 */ int ltp_max_pending; /* Max pending or paused requests, or 0 */
long ltp_pending_count; /* pending or paused requests */ int ltp_pending_count; /* Pending or paused requests */
long ltp_active_count; /* active, not paused requests */ int ltp_active_count; /* Active, not paused requests */
long ltp_open_count; /* number of threads */ int ltp_open_count; /* Number of threads */
long ltp_starting; /* currenlty starting threads */ int ltp_starting; /* Currenlty starting threads */
}; };
static int ldap_int_has_thread_pool = 0; static int ldap_int_has_thread_pool = 0;
@ -259,20 +262,15 @@ ldap_pvt_thread_pool_submit (
if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING
|| (pool->ltp_max_pending || (pool->ltp_max_pending
&& pool->ltp_pending_count >= pool->ltp_max_pending)) && pool->ltp_pending_count >= pool->ltp_max_pending))
{ goto failed;
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
return(-1);
}
task = LDAP_SLIST_FIRST(&pool->ltp_free_list); task = LDAP_SLIST_FIRST(&pool->ltp_free_list);
if (task) { if (task) {
LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltt_next.l); LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltt_next.l);
} else { } else {
task = (ldap_int_thread_task_t *) LDAP_MALLOC(sizeof(*task)); task = (ldap_int_thread_task_t *) LDAP_MALLOC(sizeof(*task));
if (task == NULL) { if (task == NULL)
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); goto failed;
return(-1);
}
} }
task->ltt_start_routine = start_routine; task->ltt_start_routine = start_routine;
@ -314,12 +312,12 @@ ldap_pvt_thread_pool_submit (
* back out of ltp_pending_count, free the task, * back out of ltp_pending_count, free the task,
* report the error. * report the error.
*/ */
pool->ltp_pending_count--;
LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, task, LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, task,
ldap_int_thread_task_s, ltt_next.q); ldap_int_thread_task_s, ltt_next.q);
pool->ltp_pending_count--; LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, task,
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); ltt_next.l);
LDAP_FREE(task); goto failed;
return(-1);
} }
} }
/* there is another open thread, so this /* there is another open thread, so this
@ -332,6 +330,10 @@ ldap_pvt_thread_pool_submit (
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
return(0); return(0);
failed:
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
return(-1);
} }
/* Set max #threads. value <= 0 means max supported #threads (LDAP_MAXTHR) */ /* Set max #threads. value <= 0 means max supported #threads (LDAP_MAXTHR) */
@ -461,6 +463,23 @@ ldap_pvt_thread_pool_query(
return ( count == -1 ? -1 : 0 ); return ( count == -1 ? -1 : 0 );
} }
/*
* true if pool is pausing; does not lock any mutex to check.
* 0 if not pause, 1 if pause, -1 if error or no pool.
*/
int
ldap_pvt_thread_pool_pausing( ldap_pvt_thread_pool_t *tpool )
{
int rc = -1;
struct ldap_int_thread_pool_s *pool;
if ( tpool != NULL && (pool = *tpool) != NULL ) {
rc = pool->ltp_pause;
}
return rc;
}
/* /*
* wrapper for ldap_pvt_thread_pool_query(), left around * wrapper for ldap_pvt_thread_pool_query(), left around
* for backwards compatibility * for backwards compatibility