diff options
author | Sverker Eriksson <[email protected]> | 2011-10-05 16:21:42 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2011-10-06 12:00:10 +0200 |
commit | f3d4ed5a10fea88b596ffa52f7b5b1f835f54fba (patch) | |
tree | db37774480e10e118f3f74f1c28c118503bd4dc1 /erts/emulator | |
parent | d01551f400e2a7944dcc10319be0c9f248ca3179 (diff) | |
download | otp-f3d4ed5a10fea88b596ffa52f7b5b1f835f54fba.tar.gz otp-f3d4ed5a10fea88b596ffa52f7b5b1f835f54fba.tar.bz2 otp-f3d4ed5a10fea88b596ffa52f7b5b1f835f54fba.zip |
ETS: Fix valgrind PossiblyLost in ETS hash tables
Add an extra pointer to start of segment with the active segment table
to get rid of PossiblyLost errors without the need of a too general
suppression that may hide real memory leaks in ETS.
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/erl_db_hash.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_hash.h | 3 |
2 files changed, 19 insertions, 5 deletions
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index e3380a57b2..2428ba655a 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -314,13 +314,23 @@ struct ext_segment { #define SIZEOF_EXTSEG(NSEGS) \ (sizeof(struct ext_segment) - sizeof(struct segment*) + sizeof(struct segment*)*(NSEGS)) -#ifdef DEBUG +#if defined(DEBUG) || defined(VALGRIND) # include <stddef.h> /* offsetof */ # define EXTSEG(SEGTAB_PTR) \ ((struct ext_segment*) (((char*)(SEGTAB_PTR)) - offsetof(struct ext_segment,segtab))) #endif +static ERTS_INLINE void SET_SEGTAB(DbTableHash* tb, + struct segment** segtab) +{ + erts_smp_atomic_set_wb(&tb->segtab, (erts_aint_t) segtab); +#ifdef VALGRIND + tb->top_ptr_to_segment_with_active_segtab = EXTSEG(segtab); +#endif +} + + /* How the table segments relate to each other: ext_segment: ext_segment: "plain" segment @@ -649,7 +659,8 @@ int db_create_hash(Process *p, DbTable *tbl) erts_smp_atomic_init_nob(&tb->szm, SEGSZ_MASK); erts_smp_atomic_init_nob(&tb->nactive, SEGSZ); erts_smp_atomic_init_nob(&tb->fixdel, (erts_aint_t)NULL); - erts_smp_atomic_init_nob(&tb->segtab, (erts_aint_t) alloc_ext_seg(tb,0,NULL)->segtab); + erts_smp_atomic_init_nob(&tb->segtab, (erts_aint_t)NULL); + SET_SEGTAB(tb, alloc_ext_seg(tb,0,NULL)->segtab); tb->nsegs = NSEG_1; tb->nslots = SEGSZ; @@ -2357,7 +2368,7 @@ static int alloc_seg(DbTableHash *tb) struct ext_segment* eseg; eseg = (struct ext_segment*) SEGTAB(tb)[seg_ix-1]; MY_ASSERT(eseg!=NULL && eseg->s.is_ext_segment); - erts_smp_atomic_set_wb(&tb->segtab, (erts_aint_t) eseg->segtab); + SET_SEGTAB(tb, eseg->segtab); tb->nsegs = eseg->nsegs; } ASSERT(seg_ix < tb->nsegs); @@ -2429,7 +2440,7 @@ static int free_seg(DbTableHash *tb, int free_records) MY_ASSERT(newtop->s.is_ext_segment); if (newtop->prev_segtab != NULL) { /* Time to use a smaller segtab */ - erts_smp_atomic_set_wb(&tb->segtab, (erts_aint_t)newtop->prev_segtab); + SET_SEGTAB(tb, newtop->prev_segtab); tb->nsegs = seg_ix; ASSERT(tb->nsegs == EXTSEG(SEGTAB(tb))->nsegs); } @@ -2446,7 +2457,7 @@ static int free_seg(DbTableHash *tb, int free_records) if (seg_ix > 0) { if (seg_ix < tb->nsegs) SEGTAB(tb)[seg_ix] = NULL; } else { - erts_smp_atomic_set_wb(&tb->segtab, (erts_aint_t)NULL); + SET_SEGTAB(tb, NULL); } #endif tb->nslots -= SEGSZ; diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h index e0285fa5ed..23ac493118 100644 --- a/erts/emulator/beam/erl_db_hash.h +++ b/erts/emulator/beam/erl_db_hash.h @@ -58,6 +58,9 @@ typedef struct db_table_hash { #ifdef ERTS_SMP DbTableHashFineLocks* locks; #endif +#ifdef VALGRIND + struct ext_segment* top_ptr_to_segment_with_active_segtab; +#endif } DbTableHash; |