Skip to content

Commit 54d4af2

Browse files
committed
HP_MALLOC: Aggregate SHM statistic updates
It is better to update the stats with a diff of the attached/detached/split/merged fragment changes. Updating the stats in a "step by step" manner has the side-effect of creating temporarily bogus values. (i.e. negative "used" and/or "real_used") Many thanks to 46Labs for supporting this work!
1 parent 0d6d33e commit 54d4af2

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

mem/hp_malloc_dyn.h

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,14 @@ void __rpm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
324324

325325
/* size should already be rounded-up */
326326
#if !defined INLINE_ALLOC && defined DBG_MALLOC
327-
void shm_frag_split_dbg(struct hp_block *hpb, struct hp_frag *frag,
327+
unsigned long shm_frag_split_dbg(struct hp_block *hpb, struct hp_frag *frag,
328328
unsigned long size, unsigned int old_hash,
329329
const char *file, const char *func, unsigned int line)
330330
#elif !defined HP_MALLOC_DYN && !defined DBG_MALLOC
331-
void shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
331+
unsigned long shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
332332
unsigned long size, unsigned int old_hash)
333333
#else
334-
void shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
334+
unsigned long shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
335335
unsigned long size, unsigned int old_hash,
336336
const char *file, const char *func, unsigned int line)
337337
#endif
@@ -345,12 +345,12 @@ void shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
345345
hpb->free_hash[PEEK_HASH_RR(hpb, size)].total_no++;
346346
#endif
347347

348-
rest = frag->size - size;
348+
rest = frag->size - size - FRAG_OVERHEAD;
349349
frag->size = size;
350350

351351
/* split the fragment */
352352
n = FRAG_NEXT(frag);
353-
n->size = rest - FRAG_OVERHEAD;
353+
n->size = rest;
354354

355355
#ifdef DBG_MALLOC
356356
/* frag created by malloc, mark it*/
@@ -369,11 +369,11 @@ void shm_frag_split(struct hp_block *hpb, struct hp_frag *frag,
369369
if (hash != old_hash)
370370
SHM_UNLOCK(hash);
371371

372-
update_stats_shm_frag_attach(n);
373-
374372
#ifdef HP_MALLOC_FAST_STATS
375373
hpb->free_hash[PEEK_HASH_RR(hpb, n->size)].total_no++;
376374
#endif
375+
376+
return rest;
377377
}
378378

379379
#if !defined INLINE_ALLOC && defined DBG_MALLOC
@@ -505,10 +505,6 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size,
505505

506506
if (stats_are_ready()) {
507507
update_stats_shm_frag_detach(frag->size);
508-
#if defined(DBG_MALLOC) || defined(STATISTICS)
509-
hpb->used += frag->size;
510-
hpb->real_used += frag->size + FRAG_OVERHEAD;
511-
#endif
512508
} else {
513509
hpb->used += frag->size;
514510
hpb->real_used += frag->size + FRAG_OVERHEAD;
@@ -632,7 +628,8 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size,
632628
{
633629
struct hp_frag *frag;
634630
unsigned int init_hash, hash, sec_hash;
635-
unsigned long old_size;
631+
unsigned long old_size, split_size;
632+
long extra_used;
636633
int i = 0;
637634

638635
/* size must be a multiple of ROUNDTO */
@@ -704,24 +701,28 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size,
704701
frag->line=line;
705702
#endif
706703

707-
update_stats_shm_frag_detach(old_size);
708-
709704
if (can_split_shm_frag(frag, size)) {
710705
#if !defined INLINE_ALLOC && defined DBG_MALLOC
711706
/* split the fragment if possible */
712-
shm_frag_split_dbg(hpb, frag, size, hash, file, "hp_malloc frag", line);
707+
split_size = shm_frag_split_dbg(hpb, frag, size, hash, file,
708+
"hp_malloc frag", line);
713709
#elif !defined HP_MALLOC_DYN && !defined DBG_MALLOC
714-
shm_frag_split(hpb, frag, size, hash);
710+
split_size = shm_frag_split(hpb, frag, size, hash);
715711
#else
716-
shm_frag_split(hpb, frag, size, hash, file, "hp_malloc frag", line);
712+
split_size = shm_frag_split(hpb, frag, size, hash, file, "hp_malloc frag", line);
717713
#endif
718714
SHM_UNLOCK(hash);
719715

720-
update_stats_shm_frag_split();
716+
extra_used = split_size + FRAG_OVERHEAD;
717+
update_stat(shm_frags, +1);
721718
} else {
722719
SHM_UNLOCK(hash);
720+
extra_used = 0;
723721
}
724722

723+
update_stat(shm_used, old_size - extra_used);
724+
update_stat(shm_rused, old_size + FRAG_OVERHEAD - extra_used);
725+
725726
#ifndef HP_MALLOC_FAST_STATS
726727
unsigned long real_used;
727728

@@ -945,7 +946,8 @@ void hp_shm_free(struct hp_block *hpb, void *p,
945946
{
946947
struct hp_frag *f, *neigh;
947948
unsigned int hash;
948-
unsigned long neigh_size;
949+
unsigned long neigh_size, f_size;
950+
long extra_used;
949951

950952
if (!p) {
951953
LM_GEN1(memlog, "free(NULL) called\n");
@@ -964,18 +966,22 @@ void hp_shm_free(struct hp_block *hpb, void *p,
964966
if (!frag_is_free(neigh) || neigh->size != neigh_size) {
965967
/* the fragment is volatile, abort mission */
966968
hp_unlock(hpb, hash);
969+
extra_used = 0;
967970
} else {
968971
hp_frag_detach(hpb, neigh);
969972
hp_unlock(hpb, hash);
970973

971-
update_stats_shm_frag_detach(neigh_size);
972-
973974
f->size += neigh_size + FRAG_OVERHEAD;
974-
update_stats_shm_frag_merge();
975+
976+
extra_used = neigh_size + FRAG_OVERHEAD;
977+
update_stat(shm_frags, -1);
975978
}
979+
} else {
980+
extra_used = 0;
976981
}
977982

978983
hash = PEEK_HASH_RR(hpb, f->size);
984+
f_size = f->size;
979985

980986
SHM_LOCK(hash);
981987
hp_frag_attach(hpb, f);
@@ -986,12 +992,8 @@ void hp_shm_free(struct hp_block *hpb, void *p,
986992
#endif
987993
SHM_UNLOCK(hash);
988994

989-
update_stats_shm_frag_attach(f);
990-
991-
#if defined(DBG_MALLOC) || defined(STATISTICS)
992-
hpb->used -= f->size;
993-
hpb->real_used -= f->size + FRAG_OVERHEAD;
994-
#endif
995+
update_stat(shm_used, -(long)f_size + extra_used);
996+
update_stat(shm_rused, -(long)(f_size + FRAG_OVERHEAD) + extra_used);
995997
}
996998

997999
#if !defined INLINE_ALLOC && defined DBG_MALLOC

0 commit comments

Comments
 (0)