More memory context tweaks

This commit is contained in:
Howard Chu 2003-04-10 06:21:53 +00:00
parent 42e7845d81
commit 374d919fc0
6 changed files with 114 additions and 74 deletions

View File

@ -889,6 +889,7 @@ connection_operation( void *ctx, void *arg_v )
#endif /* SLAPD_MONITOR */ #endif /* SLAPD_MONITOR */
Connection *conn = op->o_conn; Connection *conn = op->o_conn;
void *memctx; void *memctx;
ber_len_t memsiz;
ldap_pvt_thread_mutex_lock( &num_ops_mutex ); ldap_pvt_thread_mutex_lock( &num_ops_mutex );
num_ops_initiated++; num_ops_initiated++;
@ -915,8 +916,11 @@ connection_operation( void *ctx, void *arg_v )
* storage for most mallocs. * storage for most mallocs.
*/ */
#define SLAB_SIZE 1048576 #define SLAB_SIZE 1048576
memsiz = ber_len( op->o_ber ) * 32;
if ( SLAB_SIZE > memsiz ) memsiz = SLAB_SIZE;
if ( tag == LDAP_REQ_SEARCH ) { 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 ); ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, memctx );
op->o_tmpmemctx = memctx; op->o_tmpmemctx = memctx;
op->o_tmpmfuncs = &sl_mfuncs; op->o_tmpmfuncs = &sl_mfuncs;
@ -1072,6 +1076,7 @@ operations_error:
co_op_free: co_op_free:
ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, NULL );
slap_op_free( op ); slap_op_free( op );
no_co_op_free: no_co_op_free:

View File

@ -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) ); 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 */ /* This is like a ber_len */
static ber_len_t static ber_len_t
entry_lenlen(ber_len_t len) entry_lenlen(ber_len_t len)
@ -495,6 +493,52 @@ entry_getlen(unsigned char **buf)
return len; return len;
} }
/* 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;
dnlen = e->e_name.bv_len;
len = dnlen + 1; /* trailing NUL byte */
len += entry_lenlen(dnlen);
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);
len += a->a_desc->ad_cname.bv_len+1;
len += entry_lenlen(a->a_desc->ad_cname.bv_len);
for (i=0; a->a_vals[i].bv_val; i++) {
siz += sizeof(struct berval);
len += a->a_vals[i].bv_len + 1;
len += entry_lenlen(a->a_vals[i].bv_len);
}
len += entry_lenlen(i);
siz += sizeof(struct berval); /* empty berval at end */
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;
len += entry_lenlen(a->a_nvals[i].bv_len);
}
len += entry_lenlen(i); /* i nvals */
siz += sizeof(struct berval);
} else {
len += entry_lenlen(0); /* 0 nvals */
}
}
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 /* Flatten an Entry into a buffer. The buffer is filled with just the
* strings/bervals of all the entry components. Each field is preceded * 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 * by its length, encoded the way ber_put_len works. Every field is NUL
@ -519,35 +563,9 @@ int entry_encode(Entry *e, struct berval *bv)
#endif #endif
dnlen = e->e_name.bv_len; dnlen = e->e_name.bv_len;
ndnlen = e->e_nname.bv_len; ndnlen = e->e_nname.bv_len;
len = dnlen + ndnlen + 2; /* two trailing NUL bytes */
len += entry_lenlen(dnlen); entry_flatsize( e, &siz, &len, 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);
len += a->a_desc->ad_cname.bv_len+1;
len += entry_lenlen(a->a_desc->ad_cname.bv_len);
for (i=0; a->a_vals[i].bv_val; i++) {
siz += sizeof(struct berval);
len += a->a_vals[i].bv_len + 1;
len += entry_lenlen(a->a_vals[i].bv_len);
}
len += entry_lenlen(i);
siz += sizeof(struct berval); /* empty berval at end */
if (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;
len += entry_lenlen(a->a_nvals[i].bv_len);
}
len += entry_lenlen(i); /* i nvals */
siz += sizeof(struct berval);
} else {
len += entry_lenlen(0); /* 0 nvals */
}
}
len += 1; /* NUL byte at end */
len += entry_lenlen(siz);
bv->bv_len = len; bv->bv_len = len;
bv->bv_val = ch_malloc(len); bv->bv_val = ch_malloc(len);
ptr = (unsigned char *)bv->bv_val; ptr = (unsigned char *)bv->bv_val;
@ -724,4 +742,3 @@ int entry_decode(struct berval *bv, Entry **e)
*e = x; *e = x;
return 0; return 0;
} }
#endif

View File

@ -1195,8 +1195,6 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
ValuesReturnFilter *p; ValuesReturnFilter *p;
struct berval tmp; struct berval tmp;
ber_len_t len; ber_len_t len;
BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
(BER_MEMREALLOC_FN *)ch_realloc;
if ( vrf == NULL ) { if ( vrf == NULL ) {
ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx ); 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 ); simple_vrFilter2bv( op, p, &tmp );
fstr->bv_len += tmp.bv_len; 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, snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
/*"("*/ "%s)", tmp.bv_val ); /*"("*/ "%s)", tmp.bv_val );
@ -1228,8 +1226,6 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
{ {
struct berval tmp; struct berval tmp;
ber_len_t len; ber_len_t len;
BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
(BER_MEMREALLOC_FN *) ch_realloc;
if ( vrf == NULL ) { if ( vrf == NULL ) {
ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx ); 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 ); filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len; 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, snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
/* "(attr=" */ "%s*)", /* "(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 ); filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len + 1; 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, snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
/* "(attr=[init]*[any*]" */ "%s*)", /* "(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 ); filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len; 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, snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
/* "(attr=[init*][any*]" */ "%s)", /* "(attr=[init*][any*]" */ "%s)",

View File

@ -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 (Entry *) str2entry LDAP_P(( char *s ));
LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len )); 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_decode LDAP_P(( struct berval *bv, Entry **e ));
LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv )); 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_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_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_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 * starttls.c

View File

@ -587,6 +587,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
computed_attr_context ctx; computed_attr_context ctx;
AttributeName *anp; AttributeName *anp;
#endif #endif
void *mark = NULL;
AttributeDescription *ad_entry = slap_schema.si_ad_entry; 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 ); rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "", 0 );
#endif #endif
mark = sl_mark( op->o_tmpmemctx );
if ( ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) ) if ( ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) )
{ {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
@ -623,6 +626,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
0, 0, 0 ); 0, 0, 0 );
#endif #endif
sl_release( mark, op->o_tmpmemctx );
return( 1 ); return( 1 );
} }
@ -633,7 +637,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
ber = op->o_res_ber; ber = op->o_res_ber;
else else
#endif #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 #ifdef LDAP_CONNECTIONLESS
if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { 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; size = i * sizeof(char *) + k;
if ( size > 0 ) { if ( size > 0 ) {
char *a_flags; 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 ) { if( e_flags == NULL ) {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR, 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 ); op->o_connid : 0, 0, 0 );
#else #else
Debug( LDAP_DEBUG_ANY, 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 #endif
ber_free( ber, 1 ); ber_free( ber, 1 );
@ -866,7 +880,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
* Reuse previous memory - we likely need less space * Reuse previous memory - we likely need less space
* for operational attributes * 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 ) { if ( tmp == NULL ) {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR, LDAP_LOG( OPERATION, ERR,
@ -1082,7 +1096,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
/* free e_flags */ /* free e_flags */
if ( e_flags ) { if ( e_flags ) {
free( e_flags ); sl_free( e_flags, op->o_tmpmemctx );
e_flags = NULL; e_flags = NULL;
} }
@ -1116,6 +1130,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
#endif #endif
ber_free_buf( ber ); ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" ); send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
sl_release( mark, op->o_tmpmemctx );
return( 1 ); return( 1 );
} }
@ -1136,6 +1151,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
0, 0, 0 ); 0, 0, 0 );
#endif #endif
sl_release( mark, op->o_tmpmemctx );
return -1; return -1;
} }
rs->sr_nentries++; rs->sr_nentries++;
@ -1163,7 +1179,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
rc = 0; rc = 0;
error_return:; 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 ); return( rc );
} }

View File

@ -91,14 +91,13 @@ sl_malloc(
if (sh->h_last + size >= sh->h_end ) { if (sh->h_last + size >= sh->h_end ) {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR, LDAP_LOG( OPERATION, INFO,
"sl_malloc: allocation of %lu bytes failed\n", (long)size, 0,0 ); "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
#else #else
Debug( LDAP_DEBUG_ANY, "sl_malloc of %lu bytes failed\n", Debug( LDAP_DEBUG_TRACE,
(long) size, 0, 0 ); "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
#endif #endif
assert( 0 ); return ch_malloc( size );
exit( EXIT_FAILURE );
} }
new = sh->h_last; new = sh->h_last;
*new++ = size - sizeof(ber_len_t); *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 ); if ( ptr == NULL ) return sl_malloc( size, ctx );
/* Not our memory? */
if ( ptr < sh->h_base || ptr >= sh->h_end ) { if ( ptr < sh->h_base || ptr >= sh->h_end ) {
#ifdef NEW_LOGGING return ch_realloc( ptr, size );
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 );
} }
if ( size == 0 ) return NULL; 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 + sizeof( ber_len_t );
size &= ~pad; size &= ~pad;
/* We always alloc a new block */ /* Never shrink blocks, always alloc if growth needed */
if (size <= p[-1]) { if (size <= p[-1]) {
p[-1] = size;
new = p; new = p;
} else { } else {
new = sl_malloc( size, ctx ); new = sl_malloc( size, ctx );
@ -164,14 +155,24 @@ sl_free( void *ptr, void *ctx )
struct slab_heap *sh = ctx; struct slab_heap *sh = ctx;
if ( ptr < sh->h_base || ptr >= sh->h_end ) { if ( ptr < sh->h_base || ptr >= sh->h_end ) {
#ifdef NEW_LOGGING ch_free( ptr );
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 );
} }
} }
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;
}