From: Howard Chu Date: Tue, 29 Aug 2006 01:43:23 +0000 (+0000) Subject: Entry/Attribute struct caching, to minimize malloc fragmentation X-Git-Tag: OPENLDAP_REL_ENG_2_3_MP~243 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=78172aa0cf52dd5beb8994c10ba5ea6bd18a5e65;p=openldap Entry/Attribute struct caching, to minimize malloc fragmentation Note: this breaks LDAP_COMP_MATCH and SLAP_ZONE_MALLOC. But they were probably broken already anyway. --- diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 314d044aab..b69f7a720d 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -69,7 +69,7 @@ do_add( Operation *op, SlapReply *rs ) return SLAPD_DISCONNECT; } - op->ora_e = (Entry *) ch_calloc( 1, sizeof(Entry) ); + op->ora_e = entry_alloc(); rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); @@ -506,10 +506,7 @@ slap_mods2entry( } } - attr = ch_calloc( 1, sizeof(Attribute) ); - - /* move ad to attr structure */ - attr->a_desc = mods->sml_desc; + attr = attr_alloc( mods->sml_desc ); /* move values to attr structure */ /* should check for duplicates */ diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index fc9579283a..36878d2398 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -40,37 +40,118 @@ #include "slap.h" +/* + * Allocate in chunks, minimum of 1000 at a time. + */ +#define CHUNK_SIZE 1000 +typedef struct slap_list { + struct slap_list *next; +} slap_list; +static slap_list *attr_chunks; +static Attribute *attr_list; +static ldap_pvt_thread_mutex_t attr_mutex; + +int +attr_prealloc( int num ) +{ + Attribute *a; + slap_list *s; + + if (!num) return 0; + + s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Attribute)); + s->next = attr_chunks; + attr_chunks = s; + + a = (Attribute *)(s+1); + for ( ;num>1; num--) { + a->a_next = a+1; + a++; + } + a->a_next = attr_list; + attr_list = (Attribute *)(s+1); + + return 0; +} + Attribute * attr_alloc( AttributeDescription *ad ) { - Attribute *a = ch_malloc( sizeof(Attribute) ); - - a->a_desc = ad; + Attribute *a; + + + ldap_pvt_thread_mutex_lock( &attr_mutex ); + if ( !attr_list ) + attr_prealloc( CHUNK_SIZE ); + a = attr_list; + attr_list = a->a_next; a->a_next = NULL; - a->a_flags = 0; - a->a_vals = NULL; - a->a_nvals = NULL; -#ifdef LDAP_COMP_MATCH - a->a_comp_data = NULL; -#endif + ldap_pvt_thread_mutex_unlock( &attr_mutex ); + + a->a_desc = ad; return a; } +/* Return a list of num attrs */ +Attribute * +attrs_alloc( int num ) +{ + Attribute *head = NULL; + Attribute **a; + + ldap_pvt_thread_mutex_lock( &attr_mutex ); + for ( a = &attr_list; *a && num > 0; a = &(*a)->a_next ) { + if ( !head ) + head = *a; + num--; + } + attr_list = *a; + if ( num > 0 ) { + attr_prealloc( num > CHUNK_SIZE ? num : CHUNK_SIZE ); + *a = attr_list; + for ( ; *a && num > 0; a = &(*a)->a_next ) { + if ( !head ) + head = *a; + num--; + } + attr_list = *a; + } + *a = NULL; + ldap_pvt_thread_mutex_unlock( &attr_mutex ); + + return head; +} + + void attr_free( Attribute *a ) { - if ( a->a_nvals && a->a_nvals != a->a_vals ) { - ber_bvarray_free( a->a_nvals ); + if ( a->a_nvals && a->a_nvals != a->a_vals && + !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) { + if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) { + free( a->a_nvals ); + } else { + ber_bvarray_free( a->a_nvals ); + } } /* a_vals may be equal to slap_dummy_bv, a static empty berval; * this is used as a placeholder for attributes that do not carry * values, e.g. when proxying search entries with the "attrsonly" * bit set. */ - if ( a->a_vals != &slap_dummy_bv ) { - ber_bvarray_free( a->a_vals ); + if ( a->a_vals != &slap_dummy_bv && + !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) { + if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) { + free( a->a_vals ); + } else { + ber_bvarray_free( a->a_vals ); + } } - free( a ); + memset( a, 0, sizeof( Attribute )); + ldap_pvt_thread_mutex_lock( &attr_mutex ); + a->a_next = attr_list; + attr_list = a; + ldap_pvt_thread_mutex_unlock( &attr_mutex ); } #ifdef LDAP_COMP_MATCH @@ -399,3 +480,22 @@ attr_delete( return LDAP_NO_SUCH_ATTRIBUTE; } +int +attr_init( void ) +{ + ldap_pvt_thread_mutex_init( &attr_mutex ); + return 0; +} + +int +attr_destroy( void ) +{ + slap_list *a; + + for ( a=attr_chunks; a; a=attr_chunks ) { + attr_chunks = a->next; + free( a ); + } + ldap_pvt_thread_mutex_destroy( &attr_mutex ); + return 0; +} diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c index 869c217aad..58fafd1cc9 100644 --- a/servers/slapd/back-bdb/id2entry.c +++ b/servers/slapd/back-bdb/id2entry.c @@ -176,64 +176,31 @@ int bdb_id2entry_delete( return rc; } -#ifdef SLAP_ZONE_ALLOC -int bdb_entry_return( - struct bdb_info *bdb, - Entry *e, - int zseq -) -#else int bdb_entry_return( Entry *e ) -#endif { -#ifdef SLAP_ZONE_ALLOC - if (!slap_zn_validate(bdb->bi_cache.c_zctx, e, zseq)) { - return 0; - } -#endif /* Our entries are allocated in two blocks; the data comes from * the db itself and the Entry structure and associated pointers * are allocated in entry_decode. The db data pointer is saved - * in e_bv. Since the Entry structure is allocated as a single - * block, e_attrs is always a fixed offset from e. The exception - * is when an entry has been modified, in which case we also need - * to free e_attrs. + * in e_bv. */ - -#ifdef LDAP_COMP_MATCH - comp_tree_free( e->e_attrs ); -#endif - if( !e->e_bv.bv_val ) { /* Entry added by do_add */ - entry_free( e ); - return 0; - } - if( (void *) e->e_attrs != (void *) (e+1)) { - attrs_free( e->e_attrs ); - } - - /* See if the DNs were changed by modrdn */ - if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > - e->e_bv.bv_val + e->e_bv.bv_len ) { - ch_free(e->e_name.bv_val); - ch_free(e->e_nname.bv_val); + if ( e->e_bv.bv_val ) { + /* See if the DNs were changed by modrdn */ + if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > + e->e_bv.bv_val + e->e_bv.bv_len ) { + ch_free(e->e_name.bv_val); + ch_free(e->e_nname.bv_val); + } e->e_name.bv_val = NULL; e->e_nname.bv_val = NULL; + /* In tool mode the e_bv buffer is realloc'd, leave it alone */ + if( !(slapMode & SLAP_TOOL_MODE) ) { + free( e->e_bv.bv_val ); + } + BER_BVZERO( &e->e_bv ); } -#ifndef SLAP_ZONE_ALLOC - /* In tool mode the e_bv buffer is realloc'd, leave it alone */ - if( !(slapMode & SLAP_TOOL_MODE) ) { - free( e->e_bv.bv_val ); - } -#endif /* !SLAP_ZONE_ALLOC */ - -#ifdef SLAP_ZONE_ALLOC - slap_zn_free( e, bdb->bi_cache.c_zctx ); -#else - free( e ); -#endif - + entry_free( e ); return 0; } diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index e8c1562981..dccc329070 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -424,6 +424,8 @@ bdb_db_open( BackendDB *be ) bdb->bi_flags |= BDB_IS_OPEN; + entry_prealloc( bdb->bi_cache.c_maxsize ); + attr_prealloc( bdb->bi_cache.c_maxsize * 20 ); return 0; fail: diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 97d4ee2c7a..16b08fe8a3 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -565,13 +565,10 @@ ldap_build_entry( slap_syntax_validate_func *validate; slap_syntax_transform_func *pretty; - attr = (Attribute *)ch_malloc( sizeof( Attribute ) ); + attr = attr_alloc( NULL ); if ( attr == NULL ) { continue; } - attr->a_flags = 0; - attr->a_next = 0; - attr->a_desc = NULL; if ( slap_bv2ad( &a, &attr->a_desc, &text ) != LDAP_SUCCESS ) { @@ -792,7 +789,7 @@ retry: goto cleanup; } - *ent = ch_calloc( 1, sizeof( Entry ) ); + *ent = entry_alloc(); if ( *ent == NULL ) { rc = LDAP_NO_MEMORY; goto cleanup; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 463141d2b2..8bd5877f78 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -1417,7 +1417,7 @@ meta_send_entry( ( void )ber_scanf( &ber, "x" /* [W] */ ); continue; } - attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) ); + attr = attr_alloc( NULL ); if ( attr == NULL ) { continue; } diff --git a/servers/slapd/back-monitor/entry.c b/servers/slapd/back-monitor/entry.c index 3a2377489b..3b3d4691c5 100644 --- a/servers/slapd/back-monitor/entry.c +++ b/servers/slapd/back-monitor/entry.c @@ -193,7 +193,7 @@ monitor_entry_stub( if ( rc ) return NULL; - e = ch_calloc( 1, sizeof( Entry )); + e = entry_alloc(); if ( e ) { struct berval nrdn; diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 817435f94c..88d02229e3 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -661,10 +661,10 @@ read_baseObject( return LDAP_OTHER; } - bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) ); + bi->sql_baseObject = entry_alloc(); if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_ANY, - "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 ); + "read_baseObject_file: entry_alloc failed", 0, 0, 0 ); ldif_close( fp ); return LDAP_NO_MEMORY; } diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 801729e733..d381fe3a29 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -615,10 +615,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) append = 1; /* Make space for the array of values */ - attr = (Attribute *) ch_malloc( sizeof( Attribute ) ); - attr->a_desc = at->bam_ad; - attr->a_flags = 0; - attr->a_next = NULL; + attr = attr_alloc( at->bam_ad ); attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) ); if ( attr->a_vals == NULL ) { Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 ); diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index f103939181..f0933a6318 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -53,8 +53,7 @@ backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id ) return NULL; } - a = ch_malloc( sizeof( Attribute ) ); - a->a_desc = desc; + a = attr_alloc( desc ); a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); a->a_vals[ 0 ] = val; @@ -63,9 +62,6 @@ backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id ) a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); a->a_nvals[ 0 ] = nval; BER_BVZERO( &a->a_nvals[ 1 ] ); - - a->a_next = NULL; - a->a_flags = 0; return a; } @@ -77,8 +73,7 @@ backsql_operational_entryCSN( Operation *op ) struct berval entryCSN; Attribute *a; - a = ch_malloc( sizeof( Attribute ) ); - a->a_desc = slap_schema.si_ad_entryCSN; + a = attr_alloc( slap_schema.si_ad_entryCSN ); a->a_vals = ch_malloc( 2 * sizeof( struct berval ) ); BER_BVZERO( &a->a_vals[ 1 ] ); @@ -100,9 +95,6 @@ backsql_operational_entryCSN( Operation *op ) a->a_nvals = a->a_vals; - a->a_next = NULL; - a->a_flags = 0; - return a; } diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 6824827a09..1e3d92d9c7 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -2469,7 +2469,7 @@ backsql_entry_get( BER_BVZERO( &anlist[ 1 ].an_name ); } - bsi.bsi_e = ch_malloc( sizeof( Entry ) ); + bsi.bsi_e = entry_alloc(); rc = backsql_init_search( &bsi, ndn, LDAP_SCOPE_BASE, diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index ada0f53d21..351d4946f0 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -4403,7 +4403,7 @@ Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent, ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra ) { - Entry *e = ch_calloc( 1, sizeof(Entry) ); + Entry *e = entry_alloc(); CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) ); struct berval val; struct berval ad_name; diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c index a018d47119..0cab941536 100644 --- a/servers/slapd/ctxcsn.c +++ b/servers/slapd/ctxcsn.c @@ -128,7 +128,7 @@ slap_create_context_csn_entry( struct berval bv; - e = (Entry *) ch_calloc( 1, sizeof( Entry )); + e = entry_alloc(); attr_merge( e, slap_schema.si_ad_objectClass, ocbva, NULL ); diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 93c27985b3..fed66efdc9 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -47,18 +47,53 @@ const Entry slap_entry_root = { NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL }; +/* + * these mutexes must be used when calling the entry2str() + * routine since it returns a pointer to static data. + */ +ldap_pvt_thread_mutex_t entry2str_mutex; + static const struct berval dn_bv = BER_BVC("dn"); +/* + * Entry free list + * + * Allocate in chunks, minimum of 1000 at a time. + */ +#define CHUNK_SIZE 1000 +typedef struct slap_list { + struct slap_list *next; +} slap_list; +static slap_list *entry_chunks; +static Entry *entry_list; +static ldap_pvt_thread_mutex_t entry_mutex; + int entry_destroy(void) { + slap_list *e; if ( ebuf ) free( ebuf ); ebuf = NULL; ecur = NULL; emaxsize = 0; - return 0; + + for ( e=entry_chunks; e; e=entry_chunks ) { + entry_chunks = e->next; + free( e ); + } + + ldap_pvt_thread_mutex_destroy( &entry_mutex ); + ldap_pvt_thread_mutex_destroy( &entry2str_mutex ); + return attr_destroy(); } +int entry_init(void) +{ + ldap_pvt_thread_mutex_init( &entry2str_mutex ); + ldap_pvt_thread_mutex_init( &entry_mutex ); + return attr_init(); +} + Entry * str2entry( char *s ) { @@ -97,8 +132,7 @@ str2entry2( char *s, int checkvals ) Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n", s ? s : "NULL", 0, 0 ); - /* initialize reader/writer lock */ - e = (Entry *) ch_calloc( 1, sizeof(Entry) ); + e = entry_alloc(); if( e == NULL ) { Debug( LDAP_DEBUG_ANY, @@ -228,7 +262,7 @@ str2entry2( char *s, int checkvals ) if (( ad_prev && ad != ad_prev ) || ( i == lines )) { int j, k; - atail->a_next = (Attribute *) ch_malloc( sizeof(Attribute) ); + atail->a_next = attr_alloc( NULL ); atail = atail->a_next; atail->a_flags = 0; atail->a_desc = ad_prev; @@ -409,26 +443,27 @@ entry_clean( Entry *e ) /* e_private must be freed by the caller */ assert( e->e_private == NULL ); - e->e_private = NULL; /* free DNs */ if ( !BER_BVISNULL( &e->e_name ) ) { free( e->e_name.bv_val ); - BER_BVZERO( &e->e_name ); } if ( !BER_BVISNULL( &e->e_nname ) ) { free( e->e_nname.bv_val ); - BER_BVZERO( &e->e_nname ); } if ( !BER_BVISNULL( &e->e_bv ) ) { free( e->e_bv.bv_val ); - BER_BVZERO( &e->e_bv ); + } + + if ( &e->e_abv ) { + free( e->e_abv ); } /* free attributes */ attrs_free( e->e_attrs ); - e->e_attrs = NULL; + + memset(e, 0, sizeof(Entry)); } void @@ -436,9 +471,52 @@ entry_free( Entry *e ) { entry_clean( e ); - free( e ); + ldap_pvt_thread_mutex_lock( &entry_mutex ); + e->e_private = entry_list; + entry_list = e; + ldap_pvt_thread_mutex_unlock( &entry_mutex ); } +int +entry_prealloc( int num ) +{ + Entry *e; + slap_list *s; + + if (!num) return 0; + + s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Entry)); + s->next = entry_chunks; + entry_chunks = s; + + e = (Entry *)(s+1); + for ( ;num>1; num--) { + e->e_private = e+1; + e++; + } + e->e_private = entry_list; + entry_list = (Entry *)(s+1); + + return 0; +} + +Entry * +entry_alloc( void ) +{ + Entry *e; + + ldap_pvt_thread_mutex_lock( &entry_mutex ); + if ( !entry_list ) + entry_prealloc( CHUNK_SIZE ); + e = entry_list; + entry_list = e->e_private; + e->e_private = NULL; + ldap_pvt_thread_mutex_unlock( &entry_mutex ); + + return e; +} + + /* * These routines are used only by Backend. * @@ -616,8 +694,8 @@ int entry_encode(Entry *e, struct berval *bv) *ptr++ = '\0'; if (a->a_vals) { for (i=0; a->a_vals[i].bv_val; i++); - entry_putlen(&ptr, i); - for (i=0; a->a_vals[i].bv_val; i++) { + entry_putlen(&ptr, i); + for (i=0; a->a_vals[i].bv_val; i++) { entry_putlen(&ptr, a->a_vals[i].bv_len); AC_MEMCPY(ptr, a->a_vals[i].bv_val, a->a_vals[i].bv_len); @@ -679,19 +757,9 @@ int entry_decode(struct berval *bv, Entry **e) "entry_decode: value count was zero\n", 0, 0, 0); return LDAP_OTHER; } - i = sizeof(Entry) + (nattrs * sizeof(Attribute)) + - (nvals * sizeof(struct berval)); -#ifdef SLAP_ZONE_ALLOC - x = slap_zn_calloc(1, i + bv->bv_len, ctx); - AC_MEMCPY((char*)x + i, bv->bv_val, bv->bv_len); - bv->bv_val = (char*)x + i; - ptr = (unsigned char *)bv->bv_val; - /* pointer is reset, now advance past nattrs and nvals again */ - entry_getlen(&ptr); - entry_getlen(&ptr); -#else - x = ch_calloc(1, i); -#endif + x = entry_alloc(); + x->e_attrs = attrs_alloc( nattrs ); + x->e_abv = ch_malloc( nvals * sizeof( struct berval )); i = entry_getlen(&ptr); x->e_name.bv_val = (char *) ptr; x->e_name.bv_len = i; @@ -705,21 +773,13 @@ int entry_decode(struct berval *bv, Entry **e) x->e_dn, 0, 0 ); x->e_bv = *bv; - /* A valid entry must have at least one attr, so this - * pointer can never be NULL - */ - x->e_attrs = (Attribute *)(x+1); - bptr = (BerVarray)x->e_attrs; - a = NULL; + a = x->e_attrs; + bptr = x->e_abv; while ((i = entry_getlen(&ptr))) { struct berval bv; bv.bv_len = i; bv.bv_val = (char *) ptr; - if (a) { - a->a_next = (Attribute *)bptr; - } - a = (Attribute *)bptr; ad = NULL; rc = slap_bv2ad( &bv, &ad, &text ); @@ -737,13 +797,9 @@ int entry_decode(struct berval *bv, Entry **e) } ptr += i + 1; a->a_desc = ad; - bptr = (BerVarray)(a+1); - a->a_vals = bptr; - a->a_flags = 0; -#ifdef LDAP_COMP_MATCH - a->a_comp_data = NULL; -#endif + a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS; count = j = entry_getlen(&ptr); + a->a_vals = bptr; while (j) { i = entry_getlen(&ptr); @@ -774,12 +830,12 @@ int entry_decode(struct berval *bv, Entry **e) } else { a->a_nvals = a->a_vals; } + a = a->a_next; nattrs--; if ( !nattrs ) break; } - if (a) a->a_next = NULL; Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n", x->e_dn, 0, 0 ); *e = x; diff --git a/servers/slapd/init.c b/servers/slapd/init.c index 4476d6a40e..a69cefe73c 100644 --- a/servers/slapd/init.c +++ b/servers/slapd/init.c @@ -71,11 +71,6 @@ ldap_pvt_thread_mutex_t gmtime_mutex; slap_counters_t slap_counters; -/* - * these mutexes must be used when calling the entry2str() - * routine since it returns a pointer to static data. - */ -ldap_pvt_thread_mutex_t entry2str_mutex; ldap_pvt_thread_mutex_t replog_mutex; static const char* slap_name = NULL; @@ -119,6 +114,13 @@ slap_init( int mode, const char *name ) return 1; } + if ( entry_init() != 0 ) { + slap_debug |= LDAP_DEBUG_NONE; + Debug( LDAP_DEBUG_ANY, + "%s: entry_init failed\n", + name, 0, 0 ); + return 1; + } switch ( slapMode & SLAP_MODE ) { case SLAP_SERVER_MODE: @@ -134,7 +136,6 @@ slap_init( int mode, const char *name ) ldap_pvt_thread_pool_init( &connection_pool, connection_pool_max, 0); - ldap_pvt_thread_mutex_init( &entry2str_mutex ); ldap_pvt_thread_mutex_init( &replog_mutex ); ldap_pvt_thread_mutex_init( &slap_counters.sc_sent_mutex ); diff --git a/servers/slapd/operational.c b/servers/slapd/operational.c index 121d5938ed..2d8510614f 100644 --- a/servers/slapd/operational.c +++ b/servers/slapd/operational.c @@ -29,8 +29,7 @@ slap_operational_subschemaSubentry( Backend *be ) /* The backend wants to take care of it */ if ( be && !SLAP_FRONTEND(be) && be->be_schemadn.bv_val ) return NULL; - a = ch_malloc( sizeof( Attribute ) ); - a->a_desc = slap_schema.si_ad_subschemaSubentry; + a = attr_alloc( slap_schema.si_ad_subschemaSubentry ); a->a_vals = ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( a->a_vals, &frontendDB->be_schemadn ); @@ -42,9 +41,6 @@ slap_operational_subschemaSubentry( Backend *be ) a->a_nvals[1].bv_len = 0; a->a_nvals[1].bv_val = NULL; - a->a_next = NULL; - a->a_flags = 0; - return a; } @@ -57,8 +53,7 @@ slap_operational_entryDN( Entry *e ) assert( !BER_BVISNULL( &e->e_name ) ); assert( !BER_BVISNULL( &e->e_nname ) ); - a = ch_malloc( sizeof( Attribute ) ); - a->a_desc = slap_schema.si_ad_entryDN; + a = attr_alloc( slap_schema.si_ad_entryDN ); a->a_vals = ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &a->a_vals[ 0 ], &e->e_name ); @@ -68,9 +63,6 @@ slap_operational_entryDN( Entry *e ) ber_dupbv( &a->a_nvals[ 0 ], &e->e_nname ); BER_BVZERO( &a->a_nvals[ 1 ] ); - a->a_next = NULL; - a->a_flags = 0; - return a; } @@ -82,8 +74,7 @@ slap_operational_hasSubordinate( int hs ) val = hs ? slap_true_bv : slap_false_bv; - a = ch_malloc( sizeof( Attribute ) ); - a->a_desc = slap_schema.si_ad_hasSubordinates; + a = attr_alloc( slap_schema.si_ad_hasSubordinates ); a->a_vals = ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &a->a_vals[0], &val ); @@ -91,9 +82,6 @@ slap_operational_hasSubordinate( int hs ) a->a_nvals = a->a_vals; - a->a_next = NULL; - a->a_flags = 0; - return a; } diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index f9f90c8255..f0a7d45d76 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -813,7 +813,7 @@ static Entry *accesslog_entry( Operation *op, int logop, struct berval rdn, nrdn, timestamp, ntimestamp, bv; slap_verbmasks *lo = logops+logop+EN_OFFSET; - Entry *e = ch_calloc( 1, sizeof(Entry) ); + Entry *e = entry_alloc(); strcpy( rdnbuf, RDNEQ ); rdn.bv_val = rdnbuf; @@ -1484,7 +1484,7 @@ accesslog_db_open( const char *text = NULL; Entry *e_ctx; - e = ch_calloc( 1, sizeof( Entry )); + e = entry_alloc(); e->e_name = *li->li_db->be_suffix; e->e_nname = *li->li_db->be_nsuffix; diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index db03777469..c03f8f532c 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -2132,13 +2132,10 @@ syncprov_operational( if ( !a ) { for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next ); - a = ch_malloc( sizeof(Attribute)); - a->a_desc = slap_schema.si_ad_contextCSN; + a = attr_alloc( slap_schema.si_ad_contextCSN ); a->a_vals = ch_malloc( 2 * sizeof(struct berval)); a->a_vals[1].bv_val = NULL; a->a_nvals = a->a_vals; - a->a_next = NULL; - a->a_flags = 0; *ap = a; } diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c index 0a446c83ab..12a2db2211 100644 --- a/servers/slapd/overlays/translucent.c +++ b/servers/slapd/overlays/translucent.c @@ -141,13 +141,12 @@ void glue_parent(Operation *op) { Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", ndn.bv_val, 0, 0); - e = ch_calloc(1, sizeof(Entry)); + e = entry_alloc(); e->e_id = NOID; ber_dupbv(&e->e_name, &ndn); ber_dupbv(&e->e_nname, &ndn); - a = ch_calloc(1, sizeof(Attribute)); - a->a_desc = slap_schema.si_ad_objectClass; + a = attr_alloc( slap_schema.si_ad_objectClass ); a->a_vals = ch_malloc(sizeof(struct berval) * 3); ber_dupbv(&a->a_vals[0], &glue[0]); ber_dupbv(&a->a_vals[1], &glue[1]); @@ -156,8 +155,7 @@ void glue_parent(Operation *op) { a->a_next = e->e_attrs; e->e_attrs = a; - a = ch_calloc(1, sizeof(Attribute)); - a->a_desc = slap_schema.si_ad_structuralObjectClass; + a = attr_alloc( slap_schema.si_ad_structuralObjectClass ); a->a_vals = ch_malloc(sizeof(struct berval) * 2); ber_dupbv(&a->a_vals[0], &glue[1]); ber_dupbv(&a->a_vals[1], &glue[2]); @@ -199,12 +197,13 @@ BerVarray dup_bervarray(BerVarray b) { ** free only the Attribute*, not the contents; ** */ -void free_attr_chain(Attribute *a) { - Attribute *ax; - for(; a; a = ax) { - ax = a->a_next; - ch_free(a); +void free_attr_chain(Attribute *b) { + Attribute *a; + for(a=b; a; a=a->a_next) { + a->a_vals = NULL; + a->a_nvals = NULL; } + attrs_free( b ); return; } @@ -423,8 +422,7 @@ release: if((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) del++; continue; } - a = ch_calloc(1, sizeof(Attribute)); - a->a_desc = m->sml_desc; + a = attr_alloc( m->sml_desc ); a->a_vals = m->sml_values; a->a_nvals = m->sml_nvalues; a->a_next = ax; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 640fc982ce..b320565c9c 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -248,6 +248,8 @@ LDAP_SLAPD_F (void) comp_tree_free LDAP_P(( Attribute *a )); #define attr_mergeit_one( e, d, v ) attr_merge_one( e, d, v, NULL /* FIXME */ ) LDAP_SLAPD_F (Attribute *) attr_alloc LDAP_P(( AttributeDescription *ad )); +LDAP_SLAPD_F (Attribute *) attrs_alloc LDAP_P(( int num )); +LDAP_SLAPD_F (int) attr_prealloc LDAP_P(( int num )); LDAP_SLAPD_F (int) attr_merge LDAP_P(( Entry *e, AttributeDescription *desc, BerVarray vals, @@ -271,6 +273,8 @@ LDAP_SLAPD_F (int) attr_delete LDAP_P(( LDAP_SLAPD_F (void) attrs_free LDAP_P(( Attribute *a )); LDAP_SLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a )); +LDAP_SLAPD_F (int) attr_init LDAP_P(( void )); +LDAP_SLAPD_F (int) attr_destroy LDAP_P(( void )); /* @@ -852,6 +856,8 @@ LDAP_SLAPD_F (int) entry_cmp LDAP_P(( Entry *a, Entry *b )); LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( const void *v_a, const void *v_b )); LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( const void *v_a, const void *v_b )); LDAP_SLAPD_F (Entry *) entry_dup LDAP_P(( Entry *e )); +LDAP_SLAPD_F (Entry *) entry_alloc LDAP_P((void)); +LDAP_SLAPD_F (int) entry_prealloc LDAP_P((int num)); /* * extended.c diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index 38f9f670b2..db2d83172a 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -213,10 +213,10 @@ root_dse_info( AttributeDescription *ad_ref = slap_schema.si_ad_ref; - e = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) ); + e = entry_alloc(); if( e == NULL ) { Debug( LDAP_DEBUG_ANY, - "root_dse_info: SLAP_CALLOC failed", 0, 0, 0 ); + "root_dse_info: entry_alloc failed", 0, 0, 0 ); return LDAP_OTHER; } @@ -395,10 +395,10 @@ int read_root_dse_file( const char *fname ) return EXIT_FAILURE; } - usr_attr = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) ); + usr_attr = entry_alloc(); if( usr_attr == NULL ) { Debug( LDAP_DEBUG_ANY, - "read_root_dse_file: SLAP_CALLOC failed", 0, 0, 0 ); + "read_root_dse_file: entry_alloc failed", 0, 0, 0 ); ldif_close( fp ); return LDAP_OTHER; } diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index e78686c758..403dac0cdf 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -42,11 +42,11 @@ schema_info( Entry **entry, const char **text ) struct berval vals[5]; struct berval nvals[5]; - e = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) ); + e = entry_alloc(); if( e == NULL ) { /* Out of memory, do something about it */ Debug( LDAP_DEBUG_ANY, - "schema_info: SLAP_CALLOC failed - out of memory.\n", 0, 0, 0 ); + "schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 ); *text = "out of memory"; return LDAP_OTHER; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 75100eb8fc..67dca3df48 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1102,6 +1102,8 @@ typedef struct slap_attr { unsigned a_flags; #define SLAP_ATTR_IXADD 0x1U #define SLAP_ATTR_IXDEL 0x2U +#define SLAP_ATTR_DONT_FREE_DATA 0x4U +#define SLAP_ATTR_DONT_FREE_VALS 0x8U } Attribute; @@ -1134,6 +1136,7 @@ typedef struct slap_entry { slap_mask_t e_ocflags; struct berval e_bv; /* For entry_encode/entry_decode */ + struct berval *e_abv; /* for use by the backend for any purpose */ void* e_private; diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c index d3fa90ab74..3a0939ff43 100644 --- a/servers/slapd/slapi/slapi_utils.c +++ b/servers/slapd/slapi/slapi_utils.c @@ -205,7 +205,7 @@ slapi_entry_attr_delete( Slapi_Entry * slapi_entry_alloc( void ) { - return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) ); + return (Slapi_Entry *)entry_alloc(); } void diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 1d72a08934..a92e59225b 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1260,7 +1260,7 @@ syncrepl_message_to_op( } if ( op->o_tag == LDAP_REQ_ADD ) { - op->ora_e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) ); + op->ora_e = entry_alloc(); op->ora_e->e_name = op->o_req_dn; op->ora_e->e_nname = op->o_req_ndn; rc = slap_mods2entry( modlist, &op->ora_e, 1, 0, &text, txtbuf, textlen); @@ -1389,7 +1389,7 @@ syncrepl_message_to_entry( return -1; } - e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) ); + e = entry_alloc(); e->e_name = op->o_req_dn; e->e_nname = op->o_req_ndn; @@ -2179,12 +2179,11 @@ syncrepl_add_glue( } while ( ndn.bv_val > e->e_nname.bv_val ) { - glue = (Entry *) ch_calloc( 1, sizeof(Entry) ); + glue = entry_alloc(); ber_dupbv( &glue->e_name, &dn ); ber_dupbv( &glue->e_nname, &ndn ); - a = ch_calloc( 1, sizeof( Attribute )); - a->a_desc = slap_schema.si_ad_objectClass; + a = attr_alloc( slap_schema.si_ad_objectClass ); a->a_vals = ch_calloc( 3, sizeof( struct berval )); ber_dupbv( &a->a_vals[0], &gcbva[0] ); @@ -2196,8 +2195,7 @@ syncrepl_add_glue( a->a_next = glue->e_attrs; glue->e_attrs = a; - a = ch_calloc( 1, sizeof( Attribute )); - a->a_desc = slap_schema.si_ad_structuralObjectClass; + a = attr_alloc( slap_schema.si_ad_structuralObjectClass ); a->a_vals = ch_calloc( 2, sizeof( struct berval )); ber_dupbv( &a->a_vals[0], &gcbva[1] ); diff --git a/servers/slapd/value.c b/servers/slapd/value.c index f76ab54036..071286a0ee 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -691,8 +691,7 @@ ordered_value_add( Attribute **ap; anum = 0; for ( ap=&e->e_attrs; *ap; ap = &(*ap)->a_next ) ; - a = ch_calloc( 1, sizeof(Attribute) ); - a->a_desc = ad; + a = attr_alloc( ad ); *ap = a; }