+/* Set number of work queues in this pool. Should not be
+ * more than the number of CPUs. */
+int
+ldap_pvt_thread_pool_queues(
+ ldap_pvt_thread_pool_t *tpool,
+ int numqs )
+{
+ struct ldap_int_thread_pool_s *pool;
+ struct ldap_int_thread_poolq_s *pq;
+ int i, rc, rem_thr, rem_pend;
+
+ if (numqs < 1 || tpool == NULL)
+ return(-1);
+
+ pool = *tpool;
+
+ if (pool == NULL)
+ return(-1);
+
+ if (numqs < pool->ltp_numqs) {
+ for (i=numqs; i<pool->ltp_numqs; i++)
+ pool->ltp_wqs[i]->ltp_max_count = 0;
+ } else if (numqs > pool->ltp_numqs) {
+ struct ldap_int_thread_poolq_s **wqs;
+ wqs = LDAP_REALLOC(pool->ltp_wqs, numqs * sizeof(struct ldap_int_thread_poolq_s *));
+ if (wqs == NULL)
+ return(-1);
+ pool->ltp_wqs = wqs;
+ for (i=pool->ltp_numqs; i<numqs; i++) {
+ char *ptr = LDAP_MALLOC(sizeof(struct ldap_int_thread_poolq_s) + CACHELINE-1);
+ if (ptr == NULL) {
+ for (; i<numqs; i++)
+ pool->ltp_wqs[i] = NULL;
+ return(-1);
+ }
+ pq = (struct ldap_int_thread_poolq_s *)(((size_t)ptr + CACHELINE-1) & ~(CACHELINE-1));
+ pq->ltp_free = ptr;
+ pool->ltp_wqs[i] = pq;
+ pq->ltp_pool = pool;
+ rc = ldap_pvt_thread_mutex_init(&pq->ltp_mutex);
+ if (rc != 0)
+ return(rc);
+ rc = ldap_pvt_thread_cond_init(&pq->ltp_cond);
+ if (rc != 0)
+ return(rc);
+ LDAP_STAILQ_INIT(&pq->ltp_pending_list);
+ pq->ltp_work_list = &pq->ltp_pending_list;
+ LDAP_SLIST_INIT(&pq->ltp_free_list);
+ }
+ }
+ rem_thr = pool->ltp_max_count % numqs;
+ rem_pend = pool->ltp_max_pending % numqs;
+ for ( i=0; i<numqs; i++ ) {
+ pq = pool->ltp_wqs[i];
+ pq->ltp_max_count = pool->ltp_max_count / numqs;
+ if ( rem_thr ) {
+ pq->ltp_max_count++;
+ rem_thr--;
+ }
+ pq->ltp_max_pending = pool->ltp_max_pending / numqs;
+ if ( rem_pend ) {
+ pq->ltp_max_pending++;
+ rem_pend--;
+ }
+ }
+ pool->ltp_numqs = numqs;
+ return 0;
+}
+