Skip to content

Commit 08722f1

Browse files
committed
Rework stats-gathering struct. Fix one debug tests bug.
1 parent e99e962 commit 08722f1

File tree

3 files changed

+83
-114
lines changed

3 files changed

+83
-114
lines changed

src/platform_linux/platform.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,8 @@ memfrag_move(platform_memfrag *dst, platform_memfrag *src)
819819
* say, for memory fragments allocated for an array of n-structs.
820820
*
821821
* - To catch code errors where we may attempt to free the same memory fragment
822-
* twice, it's a hard assertion if input 'p' ptr is NULL (likely already
823-
* freed).
822+
* twice, it's a hard assertion if input ptr 'p' is NULL (likely already
823+
* freed).
824824
*/
825825
#define platform_free(hid, p) \
826826
do { \

src/platform_linux/shmem.c

Lines changed: 79 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,41 @@ typedef struct free_frag_hdr {
8787
size_t free_frag_size;
8888
} free_frag_hdr;
8989

90+
/*
91+
* ------------------------------------------------------------------------
92+
* Shared-memory usage statistics & metrics:
93+
*
94+
* Set of usage-stats fields copied from shmem_info{} struct, so that we
95+
* can print these after shared segment has been destroyed.
96+
* ------------------------------------------------------------------------
97+
*/
98+
typedef struct shminfo_usage_stats {
99+
int shmid; // Shared memory ID returned by shmget()
100+
size_t total_bytes; // Total size of shared segment allocated initially.
101+
size_t used_bytes; // Used bytes of memory left (that were allocated)
102+
size_t free_bytes; // Free bytes of memory left (that can be allocated)
103+
size_t bytes_freed; // Bytes of memory that underwent 'free' (can be
104+
// reallocated).
105+
size_t nfrees; // Total # of calls to free memory
106+
107+
// Distribution of 'free' calls based on fragment size
108+
size_t nfrees_eq0;
109+
size_t nfrees_le32;
110+
size_t nfrees_le64;
111+
size_t nfrees_le128;
112+
size_t nfrees_le256;
113+
size_t nfrees_le512;
114+
size_t nfrees_le1K;
115+
size_t nfrees_le2K;
116+
size_t nfrees_le4K;
117+
size_t nfrees_large_frags;
118+
119+
size_t nf_search_skipped;
120+
size_t used_by_large_frags_bytes;
121+
uint32 frags_inuse_HWM;
122+
int large_frags_found_in_use;
123+
} shminfo_usage_stats;
124+
90125
/*
91126
* -----------------------------------------------------------------------------
92127
* shmem_info{}: Shared memory Control Block:
@@ -107,43 +142,24 @@ typedef struct shmem_info {
107142
void *shm_end; // Points to end address; one past end of sh segment
108143
void *shm_next; // Points to next 'free' address to allocate from.
109144

110-
free_frag_hdr *shm_free_le64; // Chain of free-fragments of size <= 64 bytes
111-
free_frag_hdr
112-
*shm_free_le128; // Chain of free-fragments of size <= 128 bytes
145+
free_frag_hdr *shm_free_le64; // Chain of free-fragments <= 64 bytes
146+
free_frag_hdr *shm_free_le128; // Chain of free-fragments <= 128 bytes
113147

114148
void *shm_splinterdb_handle;
115149
void *shm_large_frag_hip; // Highest addr of large-fragments tracked
116150

117151
platform_mutex shm_mem_frags_mutex;
118152
// Protected by shm_mem_frags_mutex. Must hold to read or modify.
119153
shm_frag_info shm_mem_frags[SHM_NUM_LARGE_FRAGS];
154+
size_t shm_used_by_large_frags; // Actually reserved
120155
uint32 shm_num_frags_tracked;
121156
uint32 shm_num_frags_inuse;
122157
uint32 shm_num_frags_inuse_HWM;
123-
size_t shm_used_by_large_frags; // Actually reserved
124-
size_t shm_nfrees; // # of calls to free memory
125-
126-
// Distribution of free calls to diff sizes of memory fragments
127-
size_t shm_nfrees_eq0;
128-
size_t shm_nfrees_le32;
129-
size_t shm_nfrees_le64;
130-
size_t shm_nfrees_le128;
131-
size_t shm_nfrees_le256;
132-
size_t shm_nfrees_le512;
133-
size_t shm_nfrees_le1K;
134-
size_t shm_nfrees_le2K;
135-
size_t shm_nfrees_le4K;
136-
size_t shm_nfrees_large_frags;
137-
138-
size_t shm_nf_search_skipped; // See above;
139-
140-
size_t shm_total_bytes; // Total size of shared segment allocated initially.
141-
size_t shm_free_bytes; // Free bytes of memory left (that can be allocated)
142-
size_t shm_used_bytes; // Used bytes of memory left (that were allocated)
143-
size_t shm_bytes_freed; // Bytes of memory that underwent 'free' (can be
144-
// reallocated)
145-
uint64 shm_magic; // Magic identifier for shared memory segment
146-
int shm_id; // Shared memory ID returned by shmget()
158+
int shm_id; // Shared memory ID returned by shmget()
159+
160+
shminfo_usage_stats usage;
161+
162+
uint64 shm_magic; // Magic identifier for shared memory segment
147163

148164
} PLATFORM_CACHELINE_ALIGNED shmem_info;
149165

@@ -279,37 +295,6 @@ platform_valid_addr_in_heap(platform_heap_id heap_id, const void *addr)
279295
return platform_valid_addr_in_shm(platform_heap_id_to_handle(heap_id), addr);
280296
}
281297

282-
/*
283-
* ------------------------------------------------------------------------
284-
* Shared-memory usage statistics & metrics:
285-
*
286-
* Set of usage-stats fields copied from shmem_info{} struct, so that we
287-
* can print these after shared segment has been destroyed.
288-
* ------------------------------------------------------------------------
289-
*/
290-
typedef struct shminfo_usage_stats {
291-
size_t total_bytes;
292-
size_t used_bytes;
293-
size_t free_bytes;
294-
size_t bytes_freed;
295-
size_t nfrees;
296-
size_t nfrees_eq0;
297-
size_t nfrees_le32;
298-
size_t nfrees_le64;
299-
size_t nfrees_le128;
300-
size_t nfrees_le256;
301-
size_t nfrees_le512;
302-
size_t nfrees_le1K;
303-
size_t nfrees_le2K;
304-
size_t nfrees_le4K;
305-
size_t nfrees_large_frags;
306-
size_t nf_search_skipped;
307-
size_t used_by_large_frags_bytes;
308-
uint32 frags_inuse_HWM;
309-
int large_frags_found_in_use;
310-
int shmid;
311-
} shminfo_usage_stats;
312-
313298
/*
314299
* Produce a formatted one-line output of shared memory usage stats / metrics.
315300
*/
@@ -410,26 +395,8 @@ platform_shm_print_usage_stats(shminfo_usage_stats *usage)
410395
int
411396
platform_save_usage_stats(shminfo_usage_stats *usage, shmem_info *shminfo)
412397
{
413-
usage->shmid = shminfo->shm_id;
414-
usage->total_bytes = shminfo->shm_total_bytes;
415-
usage->used_bytes = shminfo->shm_used_bytes;
416-
usage->free_bytes = shminfo->shm_free_bytes;
417-
usage->bytes_freed = shminfo->shm_bytes_freed;
418-
usage->nfrees = shminfo->shm_nfrees;
419-
usage->nfrees_eq0 = shminfo->shm_nfrees_eq0;
420-
usage->nfrees_le32 = shminfo->shm_nfrees_le32;
421-
usage->nfrees_le64 = shminfo->shm_nfrees_le64;
422-
usage->nfrees_le128 = shminfo->shm_nfrees_le128;
423-
usage->nfrees_le256 = shminfo->shm_nfrees_le256;
424-
usage->nfrees_le512 = shminfo->shm_nfrees_le512;
425-
usage->nfrees_le1K = shminfo->shm_nfrees_le1K;
426-
usage->nfrees_le2K = shminfo->shm_nfrees_le2K;
427-
usage->nfrees_le4K = shminfo->shm_nfrees_le4K;
428-
usage->nfrees_large_frags = shminfo->shm_nfrees_large_frags;
429-
usage->nf_search_skipped = shminfo->shm_nf_search_skipped;
430-
usage->used_by_large_frags_bytes = shminfo->shm_used_by_large_frags;
431-
usage->frags_inuse_HWM = shminfo->shm_num_frags_inuse_HWM;
432-
usage->large_frags_found_in_use = platform_trace_large_frags(shminfo);
398+
*usage = shminfo->usage;
399+
usage->large_frags_found_in_use = platform_trace_large_frags(shminfo);
433400
return usage->large_frags_found_in_use;
434401
}
435402

@@ -499,15 +466,16 @@ platform_shmcreate(size_t size,
499466
size_t free_bytes;
500467
shmem_info *shminfo = (shmem_info *)shmaddr;
501468

502-
shminfo->shm_start = shmaddr;
503-
shminfo->shm_end = (shmaddr + size);
504-
shminfo->shm_next = (shmaddr + sizeof(shmem_info));
505-
shminfo->shm_total_bytes = size;
506-
free_bytes = (size - sizeof(shmem_info));
507-
shminfo->shm_free_bytes = free_bytes;
508-
shminfo->shm_used_bytes = 0;
509-
shminfo->shm_id = shmid;
510-
shminfo->shm_magic = SPLINTERDB_SHMEM_MAGIC;
469+
shminfo->shm_start = shmaddr;
470+
shminfo->shm_end = (shmaddr + size);
471+
shminfo->shm_next = (shmaddr + sizeof(shmem_info));
472+
shminfo->shm_id = shmid;
473+
shminfo->shm_magic = SPLINTERDB_SHMEM_MAGIC;
474+
475+
shminfo->usage.total_bytes = size;
476+
free_bytes = (size - sizeof(shmem_info));
477+
shminfo->usage.free_bytes = free_bytes;
478+
shminfo->usage.used_bytes = 0;
511479

512480
// Return 'heap' handles, if requested, pointing to shared segment handles.
513481
if (heap_handle) {
@@ -663,9 +631,9 @@ platform_shm_alloc(platform_heap_id hid,
663631
file,
664632
line,
665633
shminfo->shm_next,
666-
shminfo->shm_total_bytes,
667-
shminfo->shm_used_bytes,
668-
shminfo->shm_free_bytes);
634+
shminfo->usage.total_bytes,
635+
shminfo->usage.used_bytes,
636+
shminfo->usage.free_bytes);
669637

670638
void *retptr = NULL;
671639

@@ -704,7 +672,7 @@ platform_shm_alloc(platform_heap_id hid,
704672
func,
705673
size,
706674
objname,
707-
shminfo->shm_free_bytes,
675+
shminfo->usage.free_bytes,
708676
shminfo->shm_num_frags_tracked,
709677
shminfo->shm_num_frags_inuse,
710678
shminfo->shm_num_frags_inuse_HWM);
@@ -717,8 +685,8 @@ platform_shm_alloc(platform_heap_id hid,
717685
return NULL;
718686
}
719687
// Track approx memory usage metrics; mainly for troubleshooting
720-
__sync_fetch_and_add(&shminfo->shm_used_bytes, size);
721-
__sync_fetch_and_sub(&shminfo->shm_free_bytes, size);
688+
__sync_fetch_and_add(&shminfo->usage.used_bytes, size);
689+
__sync_fetch_and_sub(&shminfo->usage.free_bytes, size);
722690

723691
if (size >= SHM_LARGE_FRAG_SIZE) {
724692
platform_shm_track_alloc(shminfo, retptr, size, func, line);
@@ -942,42 +910,42 @@ platform_shm_track_free(shmem_info *shm,
942910
line);
943911

944912
shm_lock_mem_frags(shm);
945-
shm->shm_nfrees++;
946-
shm->shm_bytes_freed += size;
913+
shm->usage.nfrees++;
914+
shm->usage.bytes_freed += size;
947915

948916
// If we are freeing a fragment beyond the high-address of all
949917
// large fragments tracked, then this is certainly not a large
950918
// fragment. So, no further need to see if it's a tracked fragment.
951919
if ((addr > shm->shm_large_frag_hip) || (size && size < SHM_LARGE_FRAG_SIZE))
952920
{
953-
shm->shm_nf_search_skipped++; // Track # of optimizations done
921+
shm->usage.nf_search_skipped++; // Track # of optimizations done
954922

955923
if (size == 0) {
956-
shm->shm_nfrees_eq0++;
924+
shm->usage.nfrees_eq0++;
957925
} else if (size <= 32) {
958-
shm->shm_nfrees_le32++;
926+
shm->usage.nfrees_le32++;
959927
} else if (size <= 64) {
960928
platform_shm_hook_free_frag(&shm->shm_free_le64, addr, size);
961-
shm->shm_nfrees_le64++;
929+
shm->usage.nfrees_le64++;
962930
} else if (size <= 128) {
963931
platform_shm_hook_free_frag(&shm->shm_free_le128, addr, size);
964-
shm->shm_nfrees_le128++;
932+
shm->usage.nfrees_le128++;
965933
} else if (size <= 256) {
966-
shm->shm_nfrees_le256++;
934+
shm->usage.nfrees_le256++;
967935
} else if (size <= 512) {
968-
shm->shm_nfrees_le512++;
936+
shm->usage.nfrees_le512++;
969937
} else if (size <= KiB) {
970-
shm->shm_nfrees_le1K++;
938+
shm->usage.nfrees_le1K++;
971939
} else if (size <= (2 * KiB)) {
972-
shm->shm_nfrees_le2K++;
940+
shm->usage.nfrees_le2K++;
973941
} else if (size <= (4 * KiB)) {
974-
shm->shm_nfrees_le4K++;
942+
shm->usage.nfrees_le4K++;
975943
}
976944
shm_unlock_mem_frags(shm);
977945
return;
978946
}
979947

980-
shm->shm_nfrees_large_frags++;
948+
shm->usage.nfrees_large_frags++;
981949
bool found_tracked_frag = FALSE;
982950
bool trace_shmem = (Trace_shmem || Trace_shmem_frees);
983951

@@ -1417,23 +1385,23 @@ size_t
14171385
platform_shmsize_by_hh(platform_heap_handle heap_handle)
14181386
{
14191387
return (platform_shm_heap_handle_valid(heap_handle)
1420-
? ((shmem_info *)heap_handle)->shm_total_bytes
1388+
? ((shmem_info *)heap_handle)->usage.total_bytes
14211389
: 0);
14221390
}
14231391

14241392
size_t
14251393
platform_shmused_by_hh(platform_heap_handle heap_handle)
14261394
{
14271395
return (platform_shm_heap_handle_valid(heap_handle)
1428-
? ((shmem_info *)heap_handle)->shm_used_bytes
1396+
? ((shmem_info *)heap_handle)->usage.used_bytes
14291397
: 0);
14301398
}
14311399

14321400
size_t
14331401
platform_shmfree_by_hh(platform_heap_handle heap_handle)
14341402
{
14351403
return (platform_shm_heap_handle_valid(heap_handle)
1436-
? ((shmem_info *)heap_handle)->shm_free_bytes
1404+
? ((shmem_info *)heap_handle)->usage.free_bytes
14371405
: 0);
14381406
}
14391407

@@ -1497,6 +1465,6 @@ platform_shm_trace_allocs(shmem_info *shminfo,
14971465
size_str(size),
14981466
objname,
14991467
retptr,
1500-
shminfo->shm_free_bytes,
1501-
size_str(shminfo->shm_free_bytes));
1468+
shminfo->usage.free_bytes,
1469+
size_str(shminfo->usage.free_bytes));
15021470
}

src/trunk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,8 @@ trunk_bundle_build_filters(void *arg, void *scratch)
40134013
spl, &stream, "----------------------------------------\n");
40144014
trunk_log_stream_if_enabled(spl, &stream, "\n");
40154015

4016+
fingerprint_unalias(&filter_req.filter_fingerprint);
4017+
40164018
next_node:
40174019
compact_req->addr = trunk_next_addr(&node);
40184020
generation = trunk_generation(spl, &node);
@@ -4025,7 +4027,6 @@ trunk_bundle_build_filters(void *arg, void *scratch)
40254027
debug_assert(compact_req->addr != 0);
40264028
}
40274029
trunk_close_log_stream_if_enabled(spl, &stream);
4028-
fingerprint_unalias(&filter_req.filter_fingerprint);
40294030

40304031
} while (compact_req->generation != generation);
40314032

0 commit comments

Comments
 (0)