From: Howard Chu Date: Thu, 10 Apr 2003 06:21:53 +0000 (+0000) Subject: More memory context tweaks X-Git-Tag: OPENLDAP_REL_ENG_2_2_0ALPHA~406 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=374d919fc04f5948df38f5f7095b9576c1839406;p=openldap More memory context tweaks --- diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index d81299aad4..09410a3f27 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -889,6 +889,7 @@ connection_operation( void *ctx, void *arg_v ) #endif /* SLAPD_MONITOR */ Connection *conn = op->o_conn; void *memctx; + ber_len_t memsiz; ldap_pvt_thread_mutex_lock( &num_ops_mutex ); num_ops_initiated++; @@ -915,8 +916,11 @@ connection_operation( void *ctx, void *arg_v ) * storage for most mallocs. */ #define SLAB_SIZE 1048576 + memsiz = ber_len( op->o_ber ) * 32; + if ( SLAB_SIZE > memsiz ) memsiz = SLAB_SIZE; + if ( tag == LDAP_REQ_SEARCH ) { - memctx = sl_mem_create( SLAB_SIZE, ctx ); + memctx = sl_mem_create( memsiz, ctx ); ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, memctx ); op->o_tmpmemctx = memctx; op->o_tmpmfuncs = &sl_mfuncs; @@ -1072,6 +1076,7 @@ operations_error: co_op_free: + ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, NULL ); slap_op_free( op ); no_co_op_free: diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index a494a04424..d01e525928 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -442,8 +442,6 @@ entry_id_cmp( const void *v_e1, const void *v_e2 ) return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) ); } -#ifdef SLAPD_BDB - /* This is like a ber_len */ static ber_len_t entry_lenlen(ber_len_t len) @@ -495,33 +493,22 @@ entry_getlen(unsigned char **buf) return len; } -/* Flatten an Entry into a buffer. The buffer is filled with just the - * strings/bervals of all the entry components. Each field is preceded - * by its length, encoded the way ber_put_len works. Every field is NUL - * terminated. The entire buffer size is precomputed so that a single - * malloc can be performed. The entry size is also recorded, - * to aid in entry_decode. - */ -int entry_encode(Entry *e, struct berval *bv) +/* Add up the size of the entry for a flattened buffer */ +void entry_flatsize(Entry *e, ber_len_t *psiz, ber_len_t *plen, int norm) { ber_len_t siz = sizeof(Entry); ber_len_t len, dnlen, ndnlen; int i; Attribute *a; - unsigned char *ptr; -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n", - (long) e->e_id, e->e_dn, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n", - (long) e->e_id, e->e_dn, 0 ); -#endif dnlen = e->e_name.bv_len; - ndnlen = e->e_nname.bv_len; - len = dnlen + ndnlen + 2; /* two trailing NUL bytes */ + len = dnlen + 1; /* trailing NUL byte */ len += entry_lenlen(dnlen); - len += entry_lenlen(ndnlen); + if (norm) { + ndnlen = e->e_nname.bv_len; + len += ndnlen + 1; + len += entry_lenlen(ndnlen); + } for (a=e->e_attrs; a; a=a->a_next) { /* For AttributeDesc, we only store the attr name */ siz += sizeof(Attribute); @@ -534,7 +521,7 @@ int entry_encode(Entry *e, struct berval *bv) } len += entry_lenlen(i); siz += sizeof(struct berval); /* empty berval at end */ - if (a->a_nvals != a->a_vals) { + if (norm && a->a_nvals != a->a_vals) { for (i=0; a->a_nvals[i].bv_val; i++) { siz += sizeof(struct berval); len += a->a_nvals[i].bv_len + 1; @@ -548,6 +535,37 @@ int entry_encode(Entry *e, struct berval *bv) } len += 1; /* NUL byte at end */ len += entry_lenlen(siz); + *psiz = siz; + *plen = len; +} + +/* Flatten an Entry into a buffer. The buffer is filled with just the + * strings/bervals of all the entry components. Each field is preceded + * by its length, encoded the way ber_put_len works. Every field is NUL + * terminated. The entire buffer size is precomputed so that a single + * malloc can be performed. The entry size is also recorded, + * to aid in entry_decode. + */ +int entry_encode(Entry *e, struct berval *bv) +{ + ber_len_t siz = sizeof(Entry); + ber_len_t len, dnlen, ndnlen; + int i; + Attribute *a; + unsigned char *ptr; + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n", + (long) e->e_id, e->e_dn, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n", + (long) e->e_id, e->e_dn, 0 ); +#endif + dnlen = e->e_name.bv_len; + ndnlen = e->e_nname.bv_len; + + entry_flatsize( e, &siz, &len, 1 ); + bv->bv_len = len; bv->bv_val = ch_malloc(len); ptr = (unsigned char *)bv->bv_val; @@ -724,4 +742,3 @@ int entry_decode(struct berval *bv, Entry **e) *e = x; return 0; } -#endif diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 87c10418eb..9312bb97e8 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -1195,8 +1195,6 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr ) ValuesReturnFilter *p; struct berval tmp; ber_len_t len; - BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc : - (BER_MEMREALLOC_FN *)ch_realloc; if ( vrf == NULL ) { ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx ); @@ -1214,7 +1212,7 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr ) simple_vrFilter2bv( op, p, &tmp ); fstr->bv_len += tmp.bv_len; - fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); + fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2, /*"("*/ "%s)", tmp.bv_val ); @@ -1228,8 +1226,6 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr { struct berval tmp; ber_len_t len; - BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc : - (BER_MEMREALLOC_FN *) ch_realloc; if ( vrf == NULL ) { ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx ); @@ -1306,7 +1302,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx ); fstr->bv_len += tmp.bv_len; - fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); + fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len-2], tmp.bv_len+3, /* "(attr=" */ "%s*)", @@ -1322,7 +1318,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, op->o_tmpmemctx ); fstr->bv_len += tmp.bv_len + 1; - fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); + fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len-1], tmp.bv_len+3, /* "(attr=[init]*[any*]" */ "%s*)", @@ -1337,7 +1333,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx ); fstr->bv_len += tmp.bv_len; - fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); + fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len-1], tmp.bv_len+3, /* "(attr=[init*][any*]" */ "%s)", diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index ab25abde09..235d0a447e 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -440,6 +440,8 @@ LDAP_SLAPD_F (int) entry_destroy LDAP_P((void)); LDAP_SLAPD_F (Entry *) str2entry LDAP_P(( char *s )); LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len )); +LDAP_SLAPD_F (void) entry_flatsize LDAP_P(( + Entry *e, ber_len_t *siz, ber_len_t *len, int norm )); LDAP_SLAPD_F (int) entry_decode LDAP_P(( struct berval *bv, Entry **e )); LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv )); @@ -968,6 +970,8 @@ LDAP_SLAPD_F (void *) sl_realloc LDAP_P(( void *block, ber_len_t size, void *ctx LDAP_SLAPD_F (void *) sl_calloc LDAP_P(( ber_len_t nelem, ber_len_t size, void *ctx )); LDAP_SLAPD_F (void) sl_free LDAP_P(( void *, void *ctx )); LDAP_SLAPD_F (void *) sl_mem_create LDAP_P(( ber_len_t size, void *ctx )); +LDAP_SLAPD_F (void *) sl_mark LDAP_P(( void *ctx )); +LDAP_SLAPD_F (void) sl_release LDAP_P(( void *, void *ctx )); /* * starttls.c diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 3eb6080d44..5e9503ad61 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -587,6 +587,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) computed_attr_context ctx; AttributeName *anp; #endif + void *mark = NULL; AttributeDescription *ad_entry = slap_schema.si_ad_entry; @@ -611,6 +612,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "", 0 ); #endif + mark = sl_mark( op->o_tmpmemctx ); + if ( ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) ) { #ifdef NEW_LOGGING @@ -623,6 +626,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) 0, 0, 0 ); #endif + sl_release( mark, op->o_tmpmemctx ); return( 1 ); } @@ -633,7 +637,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) ber = op->o_res_ber; else #endif - ber_init_w_nullc( ber, LBER_USE_DER ); + { + ber_len_t siz, len; + struct berval bv; + + entry_flatsize( rs->sr_entry, &siz, &len, 0 ); + bv.bv_len = siz + len; + bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx ); + + ber_init2( ber, &bv, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx ); + } #ifdef LDAP_CONNECTIONLESS if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { @@ -686,15 +700,15 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) size = i * sizeof(char *) + k; if ( size > 0 ) { char *a_flags; - e_flags = SLAP_CALLOC ( 1, i * sizeof(char *) + k ); + e_flags = sl_calloc ( 1, i * sizeof(char *) + k, op->o_tmpmemctx ); if( e_flags == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, - "send_search_entry: conn %lu SLAP_CALLOC failed\n", + "send_search_entry: conn %lu sl_calloc failed\n", op->o_connid : 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "send_search_entry: SLAP_CALLOC failed\n", 0, 0, 0 ); + "send_search_entry: sl_calloc failed\n", 0, 0, 0 ); #endif ber_free( ber, 1 ); @@ -866,7 +880,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) * Reuse previous memory - we likely need less space * for operational attributes */ - tmp = SLAP_REALLOC ( e_flags, i * sizeof(char *) + k ); + tmp = sl_realloc( e_flags, i * sizeof(char *) + k, op->o_tmpmemctx ); if ( tmp == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -1082,7 +1096,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) /* free e_flags */ if ( e_flags ) { - free( e_flags ); + sl_free( e_flags, op->o_tmpmemctx ); e_flags = NULL; } @@ -1116,6 +1130,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) #endif ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" ); + sl_release( mark, op->o_tmpmemctx ); return( 1 ); } @@ -1136,6 +1151,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) 0, 0, 0 ); #endif + sl_release( mark, op->o_tmpmemctx ); return -1; } rs->sr_nentries++; @@ -1163,7 +1179,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rc = 0; error_return:; - if ( e_flags ) free( e_flags ); + sl_release( mark, op->o_tmpmemctx ); + if ( e_flags ) sl_free( e_flags, op->o_tmpmemctx ); return( rc ); } diff --git a/servers/slapd/sl_malloc.c b/servers/slapd/sl_malloc.c index d2223a2ab2..6d81abeab8 100644 --- a/servers/slapd/sl_malloc.c +++ b/servers/slapd/sl_malloc.c @@ -91,14 +91,13 @@ sl_malloc( if (sh->h_last + size >= sh->h_end ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "sl_malloc: allocation of %lu bytes failed\n", (long)size, 0,0 ); + LDAP_LOG( OPERATION, INFO, + "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 ); #else - Debug( LDAP_DEBUG_ANY, "sl_malloc of %lu bytes failed\n", - (long) size, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, + "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 ); #endif - assert( 0 ); - exit( EXIT_FAILURE ); + return ch_malloc( size ); } new = sh->h_last; *new++ = size - sizeof(ber_len_t); @@ -129,16 +128,9 @@ sl_realloc( void *ptr, ber_len_t size, void *ctx ) if ( ptr == NULL ) return sl_malloc( size, ctx ); + /* Not our memory? */ if ( ptr < sh->h_base || ptr >= sh->h_end ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 ); -#else - Debug( LDAP_DEBUG_ANY, - "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 ); -#endif - assert( 0 ); - exit( EXIT_FAILURE ); + return ch_realloc( ptr, size ); } if ( size == 0 ) return NULL; @@ -147,9 +139,8 @@ sl_realloc( void *ptr, ber_len_t size, void *ctx ) size += pad + sizeof( ber_len_t ); size &= ~pad; - /* We always alloc a new block */ + /* Never shrink blocks, always alloc if growth needed */ if (size <= p[-1]) { - p[-1] = size; new = p; } else { new = sl_malloc( size, ctx ); @@ -164,14 +155,24 @@ sl_free( void *ptr, void *ctx ) struct slab_heap *sh = ctx; if ( ptr < sh->h_base || ptr >= sh->h_end ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 ); -#else - Debug( LDAP_DEBUG_ANY, - "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 ); -#endif - assert( 0 ); - exit( EXIT_FAILURE ); + ch_free( ptr ); } } + +void +sl_release( void *ptr, void *ctx ) +{ + struct slab_heap *sh = ctx; + + if ( ptr >= sh->h_base && ptr <= sh->h_end ) { + sh->h_last = ptr; + } +} + +void * +sl_mark( void *ctx ) +{ + struct slab_heap *sh = ctx; + + return sh->h_last; +}