Home | History | Annotate | Line # | Download | only in slapd
sl_malloc.c revision 1.1.1.1.6.2
      1  1.1.1.1.6.2  wrstuden /* sl_malloc.c - malloc routines using a per-thread slab */
      2  1.1.1.1.6.2  wrstuden /* $OpenLDAP: pkg/ldap/servers/slapd/sl_malloc.c,v 1.39.2.6 2008/02/11 23:34:15 quanah Exp $ */
      3  1.1.1.1.6.2  wrstuden /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  1.1.1.1.6.2  wrstuden  *
      5  1.1.1.1.6.2  wrstuden  * Copyright 2003-2008 The OpenLDAP Foundation.
      6  1.1.1.1.6.2  wrstuden  * All rights reserved.
      7  1.1.1.1.6.2  wrstuden  *
      8  1.1.1.1.6.2  wrstuden  * Redistribution and use in source and binary forms, with or without
      9  1.1.1.1.6.2  wrstuden  * modification, are permitted only as authorized by the OpenLDAP
     10  1.1.1.1.6.2  wrstuden  * Public License.
     11  1.1.1.1.6.2  wrstuden  *
     12  1.1.1.1.6.2  wrstuden  * A copy of this license is available in the file LICENSE in the
     13  1.1.1.1.6.2  wrstuden  * top-level directory of the distribution or, alternatively, at
     14  1.1.1.1.6.2  wrstuden  * <http://www.OpenLDAP.org/license.html>.
     15  1.1.1.1.6.2  wrstuden  */
     16  1.1.1.1.6.2  wrstuden 
     17  1.1.1.1.6.2  wrstuden #include "portable.h"
     18  1.1.1.1.6.2  wrstuden 
     19  1.1.1.1.6.2  wrstuden #include <stdio.h>
     20  1.1.1.1.6.2  wrstuden #include <ac/string.h>
     21  1.1.1.1.6.2  wrstuden 
     22  1.1.1.1.6.2  wrstuden #include "slap.h"
     23  1.1.1.1.6.2  wrstuden 
     24  1.1.1.1.6.2  wrstuden static struct slab_object * slap_replenish_sopool(struct slab_heap* sh);
     25  1.1.1.1.6.2  wrstuden #ifdef SLAPD_UNUSED
     26  1.1.1.1.6.2  wrstuden static void print_slheap(int level, void *ctx);
     27  1.1.1.1.6.2  wrstuden #endif
     28  1.1.1.1.6.2  wrstuden 
     29  1.1.1.1.6.2  wrstuden void
     30  1.1.1.1.6.2  wrstuden slap_sl_mem_destroy(
     31  1.1.1.1.6.2  wrstuden 	void *key,
     32  1.1.1.1.6.2  wrstuden 	void *data
     33  1.1.1.1.6.2  wrstuden )
     34  1.1.1.1.6.2  wrstuden {
     35  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh = data;
     36  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int)-1, pad_shift;
     37  1.1.1.1.6.2  wrstuden 	int order_start = -1, i;
     38  1.1.1.1.6.2  wrstuden 	struct slab_object *so;
     39  1.1.1.1.6.2  wrstuden 
     40  1.1.1.1.6.2  wrstuden 	if (sh->sh_stack) {
     41  1.1.1.1.6.2  wrstuden 		ber_memfree_x(sh->sh_base, NULL);
     42  1.1.1.1.6.2  wrstuden 		ber_memfree_x(sh, NULL);
     43  1.1.1.1.6.2  wrstuden 	} else {
     44  1.1.1.1.6.2  wrstuden 		pad_shift = pad - 1;
     45  1.1.1.1.6.2  wrstuden 		do {
     46  1.1.1.1.6.2  wrstuden 			order_start++;
     47  1.1.1.1.6.2  wrstuden 		} while (pad_shift >>= 1);
     48  1.1.1.1.6.2  wrstuden 
     49  1.1.1.1.6.2  wrstuden 		for (i = 0; i <= sh->sh_maxorder - order_start; i++) {
     50  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_FIRST(&sh->sh_free[i]);
     51  1.1.1.1.6.2  wrstuden 			while (so) {
     52  1.1.1.1.6.2  wrstuden 				struct slab_object *so_tmp = so;
     53  1.1.1.1.6.2  wrstuden 				so = LDAP_LIST_NEXT(so, so_link);
     54  1.1.1.1.6.2  wrstuden 				LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_tmp, so_link);
     55  1.1.1.1.6.2  wrstuden 			}
     56  1.1.1.1.6.2  wrstuden 			ch_free(sh->sh_map[i]);
     57  1.1.1.1.6.2  wrstuden 		}
     58  1.1.1.1.6.2  wrstuden 		ch_free(sh->sh_free);
     59  1.1.1.1.6.2  wrstuden 		ch_free(sh->sh_map);
     60  1.1.1.1.6.2  wrstuden 
     61  1.1.1.1.6.2  wrstuden 		so = LDAP_LIST_FIRST(&sh->sh_sopool);
     62  1.1.1.1.6.2  wrstuden 		while (so) {
     63  1.1.1.1.6.2  wrstuden 			struct slab_object *so_tmp = so;
     64  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_NEXT(so, so_link);
     65  1.1.1.1.6.2  wrstuden 			if (!so_tmp->so_blockhead) {
     66  1.1.1.1.6.2  wrstuden 				LDAP_LIST_REMOVE(so_tmp, so_link);
     67  1.1.1.1.6.2  wrstuden 			}
     68  1.1.1.1.6.2  wrstuden 		}
     69  1.1.1.1.6.2  wrstuden 		so = LDAP_LIST_FIRST(&sh->sh_sopool);
     70  1.1.1.1.6.2  wrstuden 		while (so) {
     71  1.1.1.1.6.2  wrstuden 			struct slab_object *so_tmp = so;
     72  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_NEXT(so, so_link);
     73  1.1.1.1.6.2  wrstuden 			ch_free(so_tmp);
     74  1.1.1.1.6.2  wrstuden 		}
     75  1.1.1.1.6.2  wrstuden 		ber_memfree_x(sh->sh_base, NULL);
     76  1.1.1.1.6.2  wrstuden 		ber_memfree_x(sh, NULL);
     77  1.1.1.1.6.2  wrstuden 	}
     78  1.1.1.1.6.2  wrstuden }
     79  1.1.1.1.6.2  wrstuden 
     80  1.1.1.1.6.2  wrstuden BerMemoryFunctions slap_sl_mfuncs =
     81  1.1.1.1.6.2  wrstuden 	{ slap_sl_malloc, slap_sl_calloc, slap_sl_realloc, slap_sl_free };
     82  1.1.1.1.6.2  wrstuden 
     83  1.1.1.1.6.2  wrstuden void
     84  1.1.1.1.6.2  wrstuden slap_sl_mem_init()
     85  1.1.1.1.6.2  wrstuden {
     86  1.1.1.1.6.2  wrstuden 	ber_set_option( NULL, LBER_OPT_MEMORY_FNS, &slap_sl_mfuncs );
     87  1.1.1.1.6.2  wrstuden }
     88  1.1.1.1.6.2  wrstuden 
     89  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
     90  1.1.1.1.6.2  wrstuden static struct slab_heap *slheap;
     91  1.1.1.1.6.2  wrstuden #endif
     92  1.1.1.1.6.2  wrstuden 
     93  1.1.1.1.6.2  wrstuden void *
     94  1.1.1.1.6.2  wrstuden slap_sl_mem_create(
     95  1.1.1.1.6.2  wrstuden 	ber_len_t size,
     96  1.1.1.1.6.2  wrstuden 	int stack,
     97  1.1.1.1.6.2  wrstuden 	void *ctx,
     98  1.1.1.1.6.2  wrstuden 	int new
     99  1.1.1.1.6.2  wrstuden )
    100  1.1.1.1.6.2  wrstuden {
    101  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh;
    102  1.1.1.1.6.2  wrstuden 	ber_len_t size_shift;
    103  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int)-1, pad_shift;
    104  1.1.1.1.6.2  wrstuden 	int order = -1, order_start = -1, order_end = -1;
    105  1.1.1.1.6.2  wrstuden 	int i;
    106  1.1.1.1.6.2  wrstuden 	struct slab_object *so;
    107  1.1.1.1.6.2  wrstuden 
    108  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
    109  1.1.1.1.6.2  wrstuden 	sh = slheap;
    110  1.1.1.1.6.2  wrstuden #else
    111  1.1.1.1.6.2  wrstuden 	void *sh_tmp = NULL;
    112  1.1.1.1.6.2  wrstuden 	ldap_pvt_thread_pool_getkey(
    113  1.1.1.1.6.2  wrstuden 		ctx, (void *)slap_sl_mem_init, &sh_tmp, NULL );
    114  1.1.1.1.6.2  wrstuden 	sh = sh_tmp;
    115  1.1.1.1.6.2  wrstuden #endif
    116  1.1.1.1.6.2  wrstuden 
    117  1.1.1.1.6.2  wrstuden 	if ( !new )
    118  1.1.1.1.6.2  wrstuden 		return sh;
    119  1.1.1.1.6.2  wrstuden 
    120  1.1.1.1.6.2  wrstuden 	/* round up to doubleword boundary */
    121  1.1.1.1.6.2  wrstuden 	size += pad;
    122  1.1.1.1.6.2  wrstuden 	size &= ~pad;
    123  1.1.1.1.6.2  wrstuden 
    124  1.1.1.1.6.2  wrstuden 	if (stack) {
    125  1.1.1.1.6.2  wrstuden 		if (!sh) {
    126  1.1.1.1.6.2  wrstuden 			sh = ch_malloc(sizeof(struct slab_heap));
    127  1.1.1.1.6.2  wrstuden 			sh->sh_base = ch_malloc(size);
    128  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
    129  1.1.1.1.6.2  wrstuden 			slheap = sh;
    130  1.1.1.1.6.2  wrstuden #else
    131  1.1.1.1.6.2  wrstuden 			ldap_pvt_thread_pool_setkey(ctx, (void *)slap_sl_mem_init,
    132  1.1.1.1.6.2  wrstuden 				(void *)sh, slap_sl_mem_destroy, NULL, NULL);
    133  1.1.1.1.6.2  wrstuden #endif
    134  1.1.1.1.6.2  wrstuden 		} else if ( size > (char *)sh->sh_end - (char *)sh->sh_base ) {
    135  1.1.1.1.6.2  wrstuden 			void	*newptr;
    136  1.1.1.1.6.2  wrstuden 
    137  1.1.1.1.6.2  wrstuden 			newptr = ch_realloc( sh->sh_base, size );
    138  1.1.1.1.6.2  wrstuden 			if ( newptr == NULL ) return NULL;
    139  1.1.1.1.6.2  wrstuden 			sh->sh_base = newptr;
    140  1.1.1.1.6.2  wrstuden 		}
    141  1.1.1.1.6.2  wrstuden 		sh->sh_last = sh->sh_base;
    142  1.1.1.1.6.2  wrstuden 		sh->sh_end = (char *) sh->sh_base + size;
    143  1.1.1.1.6.2  wrstuden 		sh->sh_stack = stack;
    144  1.1.1.1.6.2  wrstuden 		return sh;
    145  1.1.1.1.6.2  wrstuden 	} else {
    146  1.1.1.1.6.2  wrstuden 		size_shift = size - 1;
    147  1.1.1.1.6.2  wrstuden 		do {
    148  1.1.1.1.6.2  wrstuden 			order_end++;
    149  1.1.1.1.6.2  wrstuden 		} while (size_shift >>= 1);
    150  1.1.1.1.6.2  wrstuden 
    151  1.1.1.1.6.2  wrstuden 		pad_shift = pad - 1;
    152  1.1.1.1.6.2  wrstuden 		do {
    153  1.1.1.1.6.2  wrstuden 			order_start++;
    154  1.1.1.1.6.2  wrstuden 		} while (pad_shift >>= 1);
    155  1.1.1.1.6.2  wrstuden 
    156  1.1.1.1.6.2  wrstuden 		order = order_end - order_start + 1;
    157  1.1.1.1.6.2  wrstuden 
    158  1.1.1.1.6.2  wrstuden 		if (!sh) {
    159  1.1.1.1.6.2  wrstuden 			sh = (struct slab_heap *) ch_malloc(sizeof(struct slab_heap));
    160  1.1.1.1.6.2  wrstuden 			sh->sh_base = ch_malloc(size);
    161  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
    162  1.1.1.1.6.2  wrstuden 			slheap = sh;
    163  1.1.1.1.6.2  wrstuden #else
    164  1.1.1.1.6.2  wrstuden 			ldap_pvt_thread_pool_setkey(ctx, (void *)slap_sl_mem_init,
    165  1.1.1.1.6.2  wrstuden 				(void *)sh, slap_sl_mem_destroy, NULL, NULL);
    166  1.1.1.1.6.2  wrstuden #endif
    167  1.1.1.1.6.2  wrstuden 		} else {
    168  1.1.1.1.6.2  wrstuden 			for (i = 0; i <= sh->sh_maxorder - order_start; i++) {
    169  1.1.1.1.6.2  wrstuden 				so = LDAP_LIST_FIRST(&sh->sh_free[i]);
    170  1.1.1.1.6.2  wrstuden 				while (so) {
    171  1.1.1.1.6.2  wrstuden 					struct slab_object *so_tmp = so;
    172  1.1.1.1.6.2  wrstuden 					so = LDAP_LIST_NEXT(so, so_link);
    173  1.1.1.1.6.2  wrstuden 					LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_tmp, so_link);
    174  1.1.1.1.6.2  wrstuden 				}
    175  1.1.1.1.6.2  wrstuden 				ch_free(sh->sh_map[i]);
    176  1.1.1.1.6.2  wrstuden 			}
    177  1.1.1.1.6.2  wrstuden 			ch_free(sh->sh_free);
    178  1.1.1.1.6.2  wrstuden 			ch_free(sh->sh_map);
    179  1.1.1.1.6.2  wrstuden 
    180  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_FIRST(&sh->sh_sopool);
    181  1.1.1.1.6.2  wrstuden 			while (so) {
    182  1.1.1.1.6.2  wrstuden 				struct slab_object *so_tmp = so;
    183  1.1.1.1.6.2  wrstuden 				so = LDAP_LIST_NEXT(so, so_link);
    184  1.1.1.1.6.2  wrstuden 				if (!so_tmp->so_blockhead) {
    185  1.1.1.1.6.2  wrstuden 					LDAP_LIST_REMOVE(so_tmp, so_link);
    186  1.1.1.1.6.2  wrstuden 				}
    187  1.1.1.1.6.2  wrstuden 			}
    188  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_FIRST(&sh->sh_sopool);
    189  1.1.1.1.6.2  wrstuden 			while (so) {
    190  1.1.1.1.6.2  wrstuden 				struct slab_object *so_tmp = so;
    191  1.1.1.1.6.2  wrstuden 				so = LDAP_LIST_NEXT(so, so_link);
    192  1.1.1.1.6.2  wrstuden 				ch_free(so_tmp);
    193  1.1.1.1.6.2  wrstuden 			}
    194  1.1.1.1.6.2  wrstuden 
    195  1.1.1.1.6.2  wrstuden 			if (size > (char *)sh->sh_end - (char *)sh->sh_base) {
    196  1.1.1.1.6.2  wrstuden 				void	*newptr;
    197  1.1.1.1.6.2  wrstuden 
    198  1.1.1.1.6.2  wrstuden 				newptr = realloc( sh->sh_base, size );
    199  1.1.1.1.6.2  wrstuden 				if ( newptr == NULL ) return NULL;
    200  1.1.1.1.6.2  wrstuden 				sh->sh_base = newptr;
    201  1.1.1.1.6.2  wrstuden 			}
    202  1.1.1.1.6.2  wrstuden 		}
    203  1.1.1.1.6.2  wrstuden 		sh->sh_end = (char *)sh->sh_base + size;
    204  1.1.1.1.6.2  wrstuden 		sh->sh_maxorder = order_end;
    205  1.1.1.1.6.2  wrstuden 
    206  1.1.1.1.6.2  wrstuden 		sh->sh_free = (struct sh_freelist *)
    207  1.1.1.1.6.2  wrstuden 						ch_malloc(order * sizeof(struct sh_freelist));
    208  1.1.1.1.6.2  wrstuden 		for (i = 0; i < order; i++) {
    209  1.1.1.1.6.2  wrstuden 			LDAP_LIST_INIT(&sh->sh_free[i]);
    210  1.1.1.1.6.2  wrstuden 		}
    211  1.1.1.1.6.2  wrstuden 
    212  1.1.1.1.6.2  wrstuden 		LDAP_LIST_INIT(&sh->sh_sopool);
    213  1.1.1.1.6.2  wrstuden 
    214  1.1.1.1.6.2  wrstuden 		if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    215  1.1.1.1.6.2  wrstuden 			slap_replenish_sopool(sh);
    216  1.1.1.1.6.2  wrstuden 		}
    217  1.1.1.1.6.2  wrstuden 		so = LDAP_LIST_FIRST(&sh->sh_sopool);
    218  1.1.1.1.6.2  wrstuden 		LDAP_LIST_REMOVE(so, so_link);
    219  1.1.1.1.6.2  wrstuden 		so->so_ptr = sh->sh_base;
    220  1.1.1.1.6.2  wrstuden 
    221  1.1.1.1.6.2  wrstuden 		LDAP_LIST_INSERT_HEAD(&sh->sh_free[order-1], so, so_link);
    222  1.1.1.1.6.2  wrstuden 
    223  1.1.1.1.6.2  wrstuden 		sh->sh_map = (unsigned char **)
    224  1.1.1.1.6.2  wrstuden 					ch_malloc(order * sizeof(unsigned char *));
    225  1.1.1.1.6.2  wrstuden 		for (i = 0; i < order; i++) {
    226  1.1.1.1.6.2  wrstuden 			int shiftamt = order_start + 1 + i;
    227  1.1.1.1.6.2  wrstuden 			int nummaps = size >> shiftamt;
    228  1.1.1.1.6.2  wrstuden 			assert(nummaps);
    229  1.1.1.1.6.2  wrstuden 			nummaps >>= 3;
    230  1.1.1.1.6.2  wrstuden 			if (!nummaps) nummaps = 1;
    231  1.1.1.1.6.2  wrstuden 			sh->sh_map[i] = (unsigned char *) ch_malloc(nummaps);
    232  1.1.1.1.6.2  wrstuden 			memset(sh->sh_map[i], 0, nummaps);
    233  1.1.1.1.6.2  wrstuden 		}
    234  1.1.1.1.6.2  wrstuden 		sh->sh_stack = stack;
    235  1.1.1.1.6.2  wrstuden 		return sh;
    236  1.1.1.1.6.2  wrstuden 	}
    237  1.1.1.1.6.2  wrstuden }
    238  1.1.1.1.6.2  wrstuden 
    239  1.1.1.1.6.2  wrstuden void
    240  1.1.1.1.6.2  wrstuden slap_sl_mem_detach(
    241  1.1.1.1.6.2  wrstuden 	void *ctx,
    242  1.1.1.1.6.2  wrstuden 	void *memctx
    243  1.1.1.1.6.2  wrstuden )
    244  1.1.1.1.6.2  wrstuden {
    245  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
    246  1.1.1.1.6.2  wrstuden 	slheap = NULL;
    247  1.1.1.1.6.2  wrstuden #else
    248  1.1.1.1.6.2  wrstuden 	/* separate from context */
    249  1.1.1.1.6.2  wrstuden 	ldap_pvt_thread_pool_setkey( ctx, (void *)slap_sl_mem_init,
    250  1.1.1.1.6.2  wrstuden 		NULL, 0, NULL, NULL );
    251  1.1.1.1.6.2  wrstuden #endif
    252  1.1.1.1.6.2  wrstuden }
    253  1.1.1.1.6.2  wrstuden 
    254  1.1.1.1.6.2  wrstuden void *
    255  1.1.1.1.6.2  wrstuden slap_sl_malloc(
    256  1.1.1.1.6.2  wrstuden     ber_len_t	size,
    257  1.1.1.1.6.2  wrstuden     void *ctx
    258  1.1.1.1.6.2  wrstuden )
    259  1.1.1.1.6.2  wrstuden {
    260  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh = ctx;
    261  1.1.1.1.6.2  wrstuden 	ber_len_t size_shift;
    262  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int)-1, pad_shift;
    263  1.1.1.1.6.2  wrstuden 	int order = -1, order_start = -1;
    264  1.1.1.1.6.2  wrstuden 	struct slab_object *so_new, *so_left, *so_right;
    265  1.1.1.1.6.2  wrstuden 	ber_len_t *ptr, *newptr;
    266  1.1.1.1.6.2  wrstuden 	unsigned long diff;
    267  1.1.1.1.6.2  wrstuden 	int i, j;
    268  1.1.1.1.6.2  wrstuden 
    269  1.1.1.1.6.2  wrstuden #ifdef SLAP_NO_SL_MALLOC
    270  1.1.1.1.6.2  wrstuden 	return ber_memalloc_x( size, NULL );
    271  1.1.1.1.6.2  wrstuden #endif
    272  1.1.1.1.6.2  wrstuden 
    273  1.1.1.1.6.2  wrstuden 	/* ber_set_option calls us like this */
    274  1.1.1.1.6.2  wrstuden 	if (!ctx) return ber_memalloc_x(size, NULL);
    275  1.1.1.1.6.2  wrstuden 
    276  1.1.1.1.6.2  wrstuden 	/* round up to doubleword boundary */
    277  1.1.1.1.6.2  wrstuden 	size += sizeof(ber_len_t) + pad;
    278  1.1.1.1.6.2  wrstuden 	size &= ~pad;
    279  1.1.1.1.6.2  wrstuden 
    280  1.1.1.1.6.2  wrstuden 	if (sh->sh_stack) {
    281  1.1.1.1.6.2  wrstuden 		if ((char *)sh->sh_last + size >= (char *)sh->sh_end) {
    282  1.1.1.1.6.2  wrstuden 			Debug(LDAP_DEBUG_TRACE,
    283  1.1.1.1.6.2  wrstuden 				"slap_sl_malloc of %lu bytes failed, using ch_malloc\n",
    284  1.1.1.1.6.2  wrstuden 				(long)size, 0, 0);
    285  1.1.1.1.6.2  wrstuden 			return ch_malloc(size);
    286  1.1.1.1.6.2  wrstuden 		}
    287  1.1.1.1.6.2  wrstuden 		newptr = sh->sh_last;
    288  1.1.1.1.6.2  wrstuden 		*newptr++ = size - sizeof(ber_len_t);
    289  1.1.1.1.6.2  wrstuden 		sh->sh_last = (char *) sh->sh_last + size;
    290  1.1.1.1.6.2  wrstuden 		return( (void *)newptr );
    291  1.1.1.1.6.2  wrstuden 	} else {
    292  1.1.1.1.6.2  wrstuden 		size_shift = size - 1;
    293  1.1.1.1.6.2  wrstuden 		do {
    294  1.1.1.1.6.2  wrstuden 			order++;
    295  1.1.1.1.6.2  wrstuden 		} while (size_shift >>= 1);
    296  1.1.1.1.6.2  wrstuden 
    297  1.1.1.1.6.2  wrstuden 		pad_shift = pad - 1;
    298  1.1.1.1.6.2  wrstuden 		do {
    299  1.1.1.1.6.2  wrstuden 			order_start++;
    300  1.1.1.1.6.2  wrstuden 		} while (pad_shift >>= 1);
    301  1.1.1.1.6.2  wrstuden 
    302  1.1.1.1.6.2  wrstuden 		for (i = order; i <= sh->sh_maxorder &&
    303  1.1.1.1.6.2  wrstuden 				LDAP_LIST_EMPTY(&sh->sh_free[i-order_start]); i++);
    304  1.1.1.1.6.2  wrstuden 
    305  1.1.1.1.6.2  wrstuden 		if (i == order) {
    306  1.1.1.1.6.2  wrstuden 			so_new = LDAP_LIST_FIRST(&sh->sh_free[i-order_start]);
    307  1.1.1.1.6.2  wrstuden 			LDAP_LIST_REMOVE(so_new, so_link);
    308  1.1.1.1.6.2  wrstuden 			ptr = so_new->so_ptr;
    309  1.1.1.1.6.2  wrstuden 			diff = (unsigned long)((char*)ptr -
    310  1.1.1.1.6.2  wrstuden 					(char*)sh->sh_base) >> (order + 1);
    311  1.1.1.1.6.2  wrstuden 			sh->sh_map[order-order_start][diff>>3] |= (1 << (diff & 0x7));
    312  1.1.1.1.6.2  wrstuden 			*ptr++ = size - sizeof(ber_len_t);
    313  1.1.1.1.6.2  wrstuden 			LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_new, so_link);
    314  1.1.1.1.6.2  wrstuden 			return((void*)ptr);
    315  1.1.1.1.6.2  wrstuden 		} else if (i <= sh->sh_maxorder) {
    316  1.1.1.1.6.2  wrstuden 			for (j = i; j > order; j--) {
    317  1.1.1.1.6.2  wrstuden 				so_left = LDAP_LIST_FIRST(&sh->sh_free[j-order_start]);
    318  1.1.1.1.6.2  wrstuden 				LDAP_LIST_REMOVE(so_left, so_link);
    319  1.1.1.1.6.2  wrstuden 				if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    320  1.1.1.1.6.2  wrstuden 					slap_replenish_sopool(sh);
    321  1.1.1.1.6.2  wrstuden 				}
    322  1.1.1.1.6.2  wrstuden 				so_right = LDAP_LIST_FIRST(&sh->sh_sopool);
    323  1.1.1.1.6.2  wrstuden 				LDAP_LIST_REMOVE(so_right, so_link);
    324  1.1.1.1.6.2  wrstuden 				so_right->so_ptr = (void *)((char *)so_left->so_ptr + (1 << j));
    325  1.1.1.1.6.2  wrstuden 				if (j == order + 1) {
    326  1.1.1.1.6.2  wrstuden 					ptr = so_left->so_ptr;
    327  1.1.1.1.6.2  wrstuden 					diff = (unsigned long)((char*)ptr -
    328  1.1.1.1.6.2  wrstuden 							(char*)sh->sh_base) >> (order+1);
    329  1.1.1.1.6.2  wrstuden 					sh->sh_map[order-order_start][diff>>3] |=
    330  1.1.1.1.6.2  wrstuden 							(1 << (diff & 0x7));
    331  1.1.1.1.6.2  wrstuden 					*ptr++ = size - sizeof(ber_len_t);
    332  1.1.1.1.6.2  wrstuden 					LDAP_LIST_INSERT_HEAD(
    333  1.1.1.1.6.2  wrstuden 							&sh->sh_free[j-1-order_start], so_right, so_link);
    334  1.1.1.1.6.2  wrstuden 					LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_left, so_link);
    335  1.1.1.1.6.2  wrstuden 					return((void*)ptr);
    336  1.1.1.1.6.2  wrstuden 				} else {
    337  1.1.1.1.6.2  wrstuden 					LDAP_LIST_INSERT_HEAD(
    338  1.1.1.1.6.2  wrstuden 							&sh->sh_free[j-1-order_start], so_right, so_link);
    339  1.1.1.1.6.2  wrstuden 					LDAP_LIST_INSERT_HEAD(
    340  1.1.1.1.6.2  wrstuden 							&sh->sh_free[j-1-order_start], so_left, so_link);
    341  1.1.1.1.6.2  wrstuden 				}
    342  1.1.1.1.6.2  wrstuden 			}
    343  1.1.1.1.6.2  wrstuden 		} else {
    344  1.1.1.1.6.2  wrstuden 			Debug( LDAP_DEBUG_TRACE,
    345  1.1.1.1.6.2  wrstuden 				"slap_sl_malloc of %lu bytes failed, using ch_malloc\n",
    346  1.1.1.1.6.2  wrstuden 				(long)size, 0, 0);
    347  1.1.1.1.6.2  wrstuden 			return (void*)ch_malloc(size);
    348  1.1.1.1.6.2  wrstuden 		}
    349  1.1.1.1.6.2  wrstuden 	}
    350  1.1.1.1.6.2  wrstuden 
    351  1.1.1.1.6.2  wrstuden 	/* FIXME: missing return; guessing... */
    352  1.1.1.1.6.2  wrstuden 	return NULL;
    353  1.1.1.1.6.2  wrstuden }
    354  1.1.1.1.6.2  wrstuden 
    355  1.1.1.1.6.2  wrstuden void *
    356  1.1.1.1.6.2  wrstuden slap_sl_calloc( ber_len_t n, ber_len_t size, void *ctx )
    357  1.1.1.1.6.2  wrstuden {
    358  1.1.1.1.6.2  wrstuden 	void *newptr;
    359  1.1.1.1.6.2  wrstuden 
    360  1.1.1.1.6.2  wrstuden 	newptr = slap_sl_malloc( n*size, ctx );
    361  1.1.1.1.6.2  wrstuden 	if ( newptr ) {
    362  1.1.1.1.6.2  wrstuden 		memset( newptr, 0, n*size );
    363  1.1.1.1.6.2  wrstuden 	}
    364  1.1.1.1.6.2  wrstuden 	return newptr;
    365  1.1.1.1.6.2  wrstuden }
    366  1.1.1.1.6.2  wrstuden 
    367  1.1.1.1.6.2  wrstuden void *
    368  1.1.1.1.6.2  wrstuden slap_sl_realloc(void *ptr, ber_len_t size, void *ctx)
    369  1.1.1.1.6.2  wrstuden {
    370  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh = ctx;
    371  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int) -1;
    372  1.1.1.1.6.2  wrstuden 	ber_len_t *p = (ber_len_t *)ptr, *newptr;
    373  1.1.1.1.6.2  wrstuden 
    374  1.1.1.1.6.2  wrstuden 	if (ptr == NULL)
    375  1.1.1.1.6.2  wrstuden 		return slap_sl_malloc(size, ctx);
    376  1.1.1.1.6.2  wrstuden 
    377  1.1.1.1.6.2  wrstuden #ifdef SLAP_NO_SL_MALLOC
    378  1.1.1.1.6.2  wrstuden 	return ber_memrealloc_x( ptr, size, NULL );
    379  1.1.1.1.6.2  wrstuden #endif
    380  1.1.1.1.6.2  wrstuden 
    381  1.1.1.1.6.2  wrstuden 	/* Not our memory? */
    382  1.1.1.1.6.2  wrstuden 	if (!sh || ptr < sh->sh_base || ptr >= sh->sh_end) {
    383  1.1.1.1.6.2  wrstuden 		/* duplicate of realloc behavior, oh well */
    384  1.1.1.1.6.2  wrstuden 		newptr = ber_memrealloc_x(ptr, size, NULL);
    385  1.1.1.1.6.2  wrstuden 		if (newptr) {
    386  1.1.1.1.6.2  wrstuden 			return newptr;
    387  1.1.1.1.6.2  wrstuden 		}
    388  1.1.1.1.6.2  wrstuden 		Debug(LDAP_DEBUG_ANY, "ch_realloc of %lu bytes failed\n",
    389  1.1.1.1.6.2  wrstuden 				(long) size, 0, 0);
    390  1.1.1.1.6.2  wrstuden 		assert(0);
    391  1.1.1.1.6.2  wrstuden 		exit( EXIT_FAILURE );
    392  1.1.1.1.6.2  wrstuden 	}
    393  1.1.1.1.6.2  wrstuden 
    394  1.1.1.1.6.2  wrstuden 	if (size == 0) {
    395  1.1.1.1.6.2  wrstuden 		slap_sl_free(ptr, ctx);
    396  1.1.1.1.6.2  wrstuden 		return NULL;
    397  1.1.1.1.6.2  wrstuden 	}
    398  1.1.1.1.6.2  wrstuden 
    399  1.1.1.1.6.2  wrstuden 	if (sh->sh_stack) {
    400  1.1.1.1.6.2  wrstuden 		/* round up to doubleword boundary */
    401  1.1.1.1.6.2  wrstuden 		size += pad + sizeof( ber_len_t );
    402  1.1.1.1.6.2  wrstuden 		size &= ~pad;
    403  1.1.1.1.6.2  wrstuden 
    404  1.1.1.1.6.2  wrstuden 		/* Never shrink blocks */
    405  1.1.1.1.6.2  wrstuden 		if (size <= p[-1]) {
    406  1.1.1.1.6.2  wrstuden 			newptr = p;
    407  1.1.1.1.6.2  wrstuden 
    408  1.1.1.1.6.2  wrstuden 		/* If reallocing the last block, we can grow it */
    409  1.1.1.1.6.2  wrstuden 		} else if ((char *)ptr + p[-1] == sh->sh_last &&
    410  1.1.1.1.6.2  wrstuden 			(char *)ptr + size < (char *)sh->sh_end ) {
    411  1.1.1.1.6.2  wrstuden 			newptr = p;
    412  1.1.1.1.6.2  wrstuden 			sh->sh_last = (char *)sh->sh_last + size - p[-1];
    413  1.1.1.1.6.2  wrstuden 			p[-1] = size;
    414  1.1.1.1.6.2  wrstuden 
    415  1.1.1.1.6.2  wrstuden 		/* Nowhere to grow, need to alloc and copy */
    416  1.1.1.1.6.2  wrstuden 		} else {
    417  1.1.1.1.6.2  wrstuden 			newptr = slap_sl_malloc(size, ctx);
    418  1.1.1.1.6.2  wrstuden 			AC_MEMCPY(newptr, ptr, p[-1]);
    419  1.1.1.1.6.2  wrstuden 		}
    420  1.1.1.1.6.2  wrstuden 		return newptr;
    421  1.1.1.1.6.2  wrstuden 	} else {
    422  1.1.1.1.6.2  wrstuden 		void *newptr2;
    423  1.1.1.1.6.2  wrstuden 
    424  1.1.1.1.6.2  wrstuden 		newptr2 = slap_sl_malloc(size, ctx);
    425  1.1.1.1.6.2  wrstuden 		if (size < p[-1]) {
    426  1.1.1.1.6.2  wrstuden 			AC_MEMCPY(newptr2, ptr, size);
    427  1.1.1.1.6.2  wrstuden 		} else {
    428  1.1.1.1.6.2  wrstuden 			AC_MEMCPY(newptr2, ptr, p[-1]);
    429  1.1.1.1.6.2  wrstuden 		}
    430  1.1.1.1.6.2  wrstuden 		slap_sl_free(ptr, ctx);
    431  1.1.1.1.6.2  wrstuden 		return newptr2;
    432  1.1.1.1.6.2  wrstuden 	}
    433  1.1.1.1.6.2  wrstuden }
    434  1.1.1.1.6.2  wrstuden 
    435  1.1.1.1.6.2  wrstuden void
    436  1.1.1.1.6.2  wrstuden slap_sl_free(void *ptr, void *ctx)
    437  1.1.1.1.6.2  wrstuden {
    438  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh = ctx;
    439  1.1.1.1.6.2  wrstuden 	int size, size_shift, order_size;
    440  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int)-1, pad_shift;
    441  1.1.1.1.6.2  wrstuden 	ber_len_t *p = (ber_len_t *)ptr, *tmpp;
    442  1.1.1.1.6.2  wrstuden 	int order_start = -1, order = -1;
    443  1.1.1.1.6.2  wrstuden 	struct slab_object *so;
    444  1.1.1.1.6.2  wrstuden 	unsigned long diff;
    445  1.1.1.1.6.2  wrstuden 	int i, inserted = 0;
    446  1.1.1.1.6.2  wrstuden 
    447  1.1.1.1.6.2  wrstuden 	if (!ptr)
    448  1.1.1.1.6.2  wrstuden 		return;
    449  1.1.1.1.6.2  wrstuden 
    450  1.1.1.1.6.2  wrstuden #ifdef SLAP_NO_SL_MALLOC
    451  1.1.1.1.6.2  wrstuden 	ber_memfree_x( ptr, NULL );
    452  1.1.1.1.6.2  wrstuden 	return;
    453  1.1.1.1.6.2  wrstuden #endif
    454  1.1.1.1.6.2  wrstuden 
    455  1.1.1.1.6.2  wrstuden 	if (!sh || ptr < sh->sh_base || ptr >= sh->sh_end) {
    456  1.1.1.1.6.2  wrstuden 		ber_memfree_x(ptr, NULL);
    457  1.1.1.1.6.2  wrstuden 	} else if (sh->sh_stack && (char *)ptr + p[-1] == sh->sh_last) {
    458  1.1.1.1.6.2  wrstuden 		p--;
    459  1.1.1.1.6.2  wrstuden 		sh->sh_last = p;
    460  1.1.1.1.6.2  wrstuden 	} else if (!sh->sh_stack) {
    461  1.1.1.1.6.2  wrstuden 		size = *(--p);
    462  1.1.1.1.6.2  wrstuden 		size_shift = size + sizeof(ber_len_t) - 1;
    463  1.1.1.1.6.2  wrstuden 		do {
    464  1.1.1.1.6.2  wrstuden 			order++;
    465  1.1.1.1.6.2  wrstuden 		} while (size_shift >>= 1);
    466  1.1.1.1.6.2  wrstuden 
    467  1.1.1.1.6.2  wrstuden 		pad_shift = pad - 1;
    468  1.1.1.1.6.2  wrstuden 		do {
    469  1.1.1.1.6.2  wrstuden 			order_start++;
    470  1.1.1.1.6.2  wrstuden 		} while (pad_shift >>= 1);
    471  1.1.1.1.6.2  wrstuden 
    472  1.1.1.1.6.2  wrstuden 		for (i = order, tmpp = p; i <= sh->sh_maxorder; i++) {
    473  1.1.1.1.6.2  wrstuden 			order_size = 1 << (i+1);
    474  1.1.1.1.6.2  wrstuden 			diff = (unsigned long)((char*)tmpp - (char*)sh->sh_base) >> (i+1);
    475  1.1.1.1.6.2  wrstuden 			sh->sh_map[i-order_start][diff>>3] &= (~(1 << (diff & 0x7)));
    476  1.1.1.1.6.2  wrstuden 			if (diff == ((diff>>1)<<1)) {
    477  1.1.1.1.6.2  wrstuden 				if (!(sh->sh_map[i-order_start][(diff+1)>>3] &
    478  1.1.1.1.6.2  wrstuden 						(1<<((diff+1)&0x7)))) {
    479  1.1.1.1.6.2  wrstuden 					so = LDAP_LIST_FIRST(&sh->sh_free[i-order_start]);
    480  1.1.1.1.6.2  wrstuden 					while (so) {
    481  1.1.1.1.6.2  wrstuden 						if ((char*)so->so_ptr == (char*)tmpp) {
    482  1.1.1.1.6.2  wrstuden 							LDAP_LIST_REMOVE( so, so_link );
    483  1.1.1.1.6.2  wrstuden 						} else if ((char*)so->so_ptr ==
    484  1.1.1.1.6.2  wrstuden 								(char*)tmpp + order_size) {
    485  1.1.1.1.6.2  wrstuden 							LDAP_LIST_REMOVE(so, so_link);
    486  1.1.1.1.6.2  wrstuden 							break;
    487  1.1.1.1.6.2  wrstuden 						}
    488  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_NEXT(so, so_link);
    489  1.1.1.1.6.2  wrstuden 					}
    490  1.1.1.1.6.2  wrstuden 					if (so) {
    491  1.1.1.1.6.2  wrstuden 						if (i < sh->sh_maxorder) {
    492  1.1.1.1.6.2  wrstuden 							inserted = 1;
    493  1.1.1.1.6.2  wrstuden 							so->so_ptr = tmpp;
    494  1.1.1.1.6.2  wrstuden 							LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start+1],
    495  1.1.1.1.6.2  wrstuden 									so, so_link);
    496  1.1.1.1.6.2  wrstuden 						}
    497  1.1.1.1.6.2  wrstuden 						continue;
    498  1.1.1.1.6.2  wrstuden 					} else {
    499  1.1.1.1.6.2  wrstuden 						if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    500  1.1.1.1.6.2  wrstuden 							slap_replenish_sopool(sh);
    501  1.1.1.1.6.2  wrstuden 						}
    502  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_FIRST(&sh->sh_sopool);
    503  1.1.1.1.6.2  wrstuden 						LDAP_LIST_REMOVE(so, so_link);
    504  1.1.1.1.6.2  wrstuden 						so->so_ptr = tmpp;
    505  1.1.1.1.6.2  wrstuden 						LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start],
    506  1.1.1.1.6.2  wrstuden 								so, so_link);
    507  1.1.1.1.6.2  wrstuden 						break;
    508  1.1.1.1.6.2  wrstuden 
    509  1.1.1.1.6.2  wrstuden 						Debug(LDAP_DEBUG_TRACE, "slap_sl_free: "
    510  1.1.1.1.6.2  wrstuden 							"free object not found while bit is clear.\n",
    511  1.1.1.1.6.2  wrstuden 							0, 0, 0);
    512  1.1.1.1.6.2  wrstuden 						assert(so != NULL);
    513  1.1.1.1.6.2  wrstuden 
    514  1.1.1.1.6.2  wrstuden 					}
    515  1.1.1.1.6.2  wrstuden 				} else {
    516  1.1.1.1.6.2  wrstuden 					if (!inserted) {
    517  1.1.1.1.6.2  wrstuden 						if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    518  1.1.1.1.6.2  wrstuden 							slap_replenish_sopool(sh);
    519  1.1.1.1.6.2  wrstuden 						}
    520  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_FIRST(&sh->sh_sopool);
    521  1.1.1.1.6.2  wrstuden 						LDAP_LIST_REMOVE(so, so_link);
    522  1.1.1.1.6.2  wrstuden 						so->so_ptr = tmpp;
    523  1.1.1.1.6.2  wrstuden 						LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start],
    524  1.1.1.1.6.2  wrstuden 								so, so_link);
    525  1.1.1.1.6.2  wrstuden 					}
    526  1.1.1.1.6.2  wrstuden 					break;
    527  1.1.1.1.6.2  wrstuden 				}
    528  1.1.1.1.6.2  wrstuden 			} else {
    529  1.1.1.1.6.2  wrstuden 				if (!(sh->sh_map[i-order_start][(diff-1)>>3] &
    530  1.1.1.1.6.2  wrstuden 						(1<<((diff-1)&0x7)))) {
    531  1.1.1.1.6.2  wrstuden 					so = LDAP_LIST_FIRST(&sh->sh_free[i-order_start]);
    532  1.1.1.1.6.2  wrstuden 					while (so) {
    533  1.1.1.1.6.2  wrstuden 						if ((char*)so->so_ptr == (char*)tmpp) {
    534  1.1.1.1.6.2  wrstuden 							LDAP_LIST_REMOVE(so, so_link);
    535  1.1.1.1.6.2  wrstuden 						} else if ((char*)tmpp == (char *)so->so_ptr + order_size) {
    536  1.1.1.1.6.2  wrstuden 							LDAP_LIST_REMOVE(so, so_link);
    537  1.1.1.1.6.2  wrstuden 							tmpp = so->so_ptr;
    538  1.1.1.1.6.2  wrstuden 							break;
    539  1.1.1.1.6.2  wrstuden 						}
    540  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_NEXT(so, so_link);
    541  1.1.1.1.6.2  wrstuden 					}
    542  1.1.1.1.6.2  wrstuden 					if (so) {
    543  1.1.1.1.6.2  wrstuden 						if (i < sh->sh_maxorder) {
    544  1.1.1.1.6.2  wrstuden 							inserted = 1;
    545  1.1.1.1.6.2  wrstuden 							LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start+1],									so, so_link);
    546  1.1.1.1.6.2  wrstuden 							continue;
    547  1.1.1.1.6.2  wrstuden 						}
    548  1.1.1.1.6.2  wrstuden 					} else {
    549  1.1.1.1.6.2  wrstuden 						if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    550  1.1.1.1.6.2  wrstuden 							slap_replenish_sopool(sh);
    551  1.1.1.1.6.2  wrstuden 						}
    552  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_FIRST(&sh->sh_sopool);
    553  1.1.1.1.6.2  wrstuden 						LDAP_LIST_REMOVE(so, so_link);
    554  1.1.1.1.6.2  wrstuden 						so->so_ptr = tmpp;
    555  1.1.1.1.6.2  wrstuden 						LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start],
    556  1.1.1.1.6.2  wrstuden 								so, so_link);
    557  1.1.1.1.6.2  wrstuden 						break;
    558  1.1.1.1.6.2  wrstuden 
    559  1.1.1.1.6.2  wrstuden 						Debug(LDAP_DEBUG_TRACE, "slap_sl_free: "
    560  1.1.1.1.6.2  wrstuden 							"free object not found while bit is clear.\n",
    561  1.1.1.1.6.2  wrstuden 							0, 0, 0 );
    562  1.1.1.1.6.2  wrstuden 						assert(so != NULL);
    563  1.1.1.1.6.2  wrstuden 
    564  1.1.1.1.6.2  wrstuden 					}
    565  1.1.1.1.6.2  wrstuden 				} else {
    566  1.1.1.1.6.2  wrstuden 					if ( !inserted ) {
    567  1.1.1.1.6.2  wrstuden 						if (LDAP_LIST_EMPTY(&sh->sh_sopool)) {
    568  1.1.1.1.6.2  wrstuden 							slap_replenish_sopool(sh);
    569  1.1.1.1.6.2  wrstuden 						}
    570  1.1.1.1.6.2  wrstuden 						so = LDAP_LIST_FIRST(&sh->sh_sopool);
    571  1.1.1.1.6.2  wrstuden 						LDAP_LIST_REMOVE(so, so_link);
    572  1.1.1.1.6.2  wrstuden 						so->so_ptr = tmpp;
    573  1.1.1.1.6.2  wrstuden 						LDAP_LIST_INSERT_HEAD(&sh->sh_free[i-order_start],
    574  1.1.1.1.6.2  wrstuden 								so, so_link);
    575  1.1.1.1.6.2  wrstuden 					}
    576  1.1.1.1.6.2  wrstuden 					break;
    577  1.1.1.1.6.2  wrstuden 				}
    578  1.1.1.1.6.2  wrstuden 			}
    579  1.1.1.1.6.2  wrstuden 		}
    580  1.1.1.1.6.2  wrstuden 	}
    581  1.1.1.1.6.2  wrstuden }
    582  1.1.1.1.6.2  wrstuden 
    583  1.1.1.1.6.2  wrstuden void *
    584  1.1.1.1.6.2  wrstuden slap_sl_context( void *ptr )
    585  1.1.1.1.6.2  wrstuden {
    586  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh;
    587  1.1.1.1.6.2  wrstuden 	void *ctx, *sh_tmp;
    588  1.1.1.1.6.2  wrstuden 
    589  1.1.1.1.6.2  wrstuden 	if ( slapMode & SLAP_TOOL_MODE ) return NULL;
    590  1.1.1.1.6.2  wrstuden 
    591  1.1.1.1.6.2  wrstuden #ifdef NO_THREADS
    592  1.1.1.1.6.2  wrstuden 	sh = slheap;
    593  1.1.1.1.6.2  wrstuden #else
    594  1.1.1.1.6.2  wrstuden 	ctx = ldap_pvt_thread_pool_context();
    595  1.1.1.1.6.2  wrstuden 
    596  1.1.1.1.6.2  wrstuden 	sh_tmp = NULL;
    597  1.1.1.1.6.2  wrstuden 	ldap_pvt_thread_pool_getkey(
    598  1.1.1.1.6.2  wrstuden 		ctx, (void *)slap_sl_mem_init, &sh_tmp, NULL);
    599  1.1.1.1.6.2  wrstuden 	sh = sh_tmp;
    600  1.1.1.1.6.2  wrstuden #endif
    601  1.1.1.1.6.2  wrstuden 
    602  1.1.1.1.6.2  wrstuden 	if (sh && ptr >= sh->sh_base && ptr <= sh->sh_end) {
    603  1.1.1.1.6.2  wrstuden 		return sh;
    604  1.1.1.1.6.2  wrstuden 	}
    605  1.1.1.1.6.2  wrstuden 	return NULL;
    606  1.1.1.1.6.2  wrstuden }
    607  1.1.1.1.6.2  wrstuden 
    608  1.1.1.1.6.2  wrstuden static struct slab_object *
    609  1.1.1.1.6.2  wrstuden slap_replenish_sopool(
    610  1.1.1.1.6.2  wrstuden     struct slab_heap* sh
    611  1.1.1.1.6.2  wrstuden )
    612  1.1.1.1.6.2  wrstuden {
    613  1.1.1.1.6.2  wrstuden     struct slab_object *so_block;
    614  1.1.1.1.6.2  wrstuden     int i;
    615  1.1.1.1.6.2  wrstuden 
    616  1.1.1.1.6.2  wrstuden     so_block = (struct slab_object *)ch_malloc(
    617  1.1.1.1.6.2  wrstuden                     SLAP_SLAB_SOBLOCK * sizeof(struct slab_object));
    618  1.1.1.1.6.2  wrstuden 
    619  1.1.1.1.6.2  wrstuden     if ( so_block == NULL ) {
    620  1.1.1.1.6.2  wrstuden         return NULL;
    621  1.1.1.1.6.2  wrstuden     }
    622  1.1.1.1.6.2  wrstuden 
    623  1.1.1.1.6.2  wrstuden     so_block[0].so_blockhead = 1;
    624  1.1.1.1.6.2  wrstuden     LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, &so_block[0], so_link);
    625  1.1.1.1.6.2  wrstuden     for (i = 1; i < SLAP_SLAB_SOBLOCK; i++) {
    626  1.1.1.1.6.2  wrstuden         so_block[i].so_blockhead = 0;
    627  1.1.1.1.6.2  wrstuden         LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, &so_block[i], so_link );
    628  1.1.1.1.6.2  wrstuden     }
    629  1.1.1.1.6.2  wrstuden 
    630  1.1.1.1.6.2  wrstuden     return so_block;
    631  1.1.1.1.6.2  wrstuden }
    632  1.1.1.1.6.2  wrstuden 
    633  1.1.1.1.6.2  wrstuden #ifdef SLAPD_UNUSED
    634  1.1.1.1.6.2  wrstuden static void
    635  1.1.1.1.6.2  wrstuden print_slheap(int level, void *ctx)
    636  1.1.1.1.6.2  wrstuden {
    637  1.1.1.1.6.2  wrstuden 	struct slab_heap *sh = ctx;
    638  1.1.1.1.6.2  wrstuden 	int order_start = -1;
    639  1.1.1.1.6.2  wrstuden 	int pad = 2*sizeof(int)-1, pad_shift;
    640  1.1.1.1.6.2  wrstuden 	struct slab_object *so;
    641  1.1.1.1.6.2  wrstuden 	int i, j, once = 0;
    642  1.1.1.1.6.2  wrstuden 
    643  1.1.1.1.6.2  wrstuden 	if (!ctx) {
    644  1.1.1.1.6.2  wrstuden 		Debug(level, "NULL memctx\n", 0, 0, 0);
    645  1.1.1.1.6.2  wrstuden 		return;
    646  1.1.1.1.6.2  wrstuden 	}
    647  1.1.1.1.6.2  wrstuden 
    648  1.1.1.1.6.2  wrstuden 	pad_shift = pad - 1;
    649  1.1.1.1.6.2  wrstuden 	do {
    650  1.1.1.1.6.2  wrstuden 		order_start++;
    651  1.1.1.1.6.2  wrstuden 	} while (pad_shift >>= 1);
    652  1.1.1.1.6.2  wrstuden 
    653  1.1.1.1.6.2  wrstuden 	Debug(level, "sh->sh_maxorder=%d\n", sh->sh_maxorder, 0, 0);
    654  1.1.1.1.6.2  wrstuden 
    655  1.1.1.1.6.2  wrstuden 	for (i = order_start; i <= sh->sh_maxorder; i++) {
    656  1.1.1.1.6.2  wrstuden 		once = 0;
    657  1.1.1.1.6.2  wrstuden 		Debug(level, "order=%d\n", i, 0, 0);
    658  1.1.1.1.6.2  wrstuden 		for (j = 0; j < (1<<(sh->sh_maxorder-i))/8; j++) {
    659  1.1.1.1.6.2  wrstuden 			Debug(level, "%02x ", sh->sh_map[i-order_start][j], 0, 0);
    660  1.1.1.1.6.2  wrstuden 			once = 1;
    661  1.1.1.1.6.2  wrstuden 		}
    662  1.1.1.1.6.2  wrstuden 		if (!once) {
    663  1.1.1.1.6.2  wrstuden 			Debug(level, "%02x ", sh->sh_map[i-order_start][0], 0, 0);
    664  1.1.1.1.6.2  wrstuden 		}
    665  1.1.1.1.6.2  wrstuden 		Debug(level, "\n", 0, 0, 0);
    666  1.1.1.1.6.2  wrstuden 		Debug(level, "free list:\n", 0, 0, 0);
    667  1.1.1.1.6.2  wrstuden 		so = LDAP_LIST_FIRST(&sh->sh_free[i-order_start]);
    668  1.1.1.1.6.2  wrstuden 		while (so) {
    669  1.1.1.1.6.2  wrstuden 			Debug(level, "%lx\n", (unsigned long) so->so_ptr, 0, 0);
    670  1.1.1.1.6.2  wrstuden 			so = LDAP_LIST_NEXT(so, so_link);
    671  1.1.1.1.6.2  wrstuden 		}
    672  1.1.1.1.6.2  wrstuden 	}
    673  1.1.1.1.6.2  wrstuden }
    674  1.1.1.1.6.2  wrstuden #endif
    675