GCC Code Coverage Report


Directory: src/
File: src/standalone/shm_toc.c
Date: 2026-09-30 11:11:31
Exec Total Coverage
Lines: 44 53 83.0%
Functions: 6 6 100.0%
Branches: 14 20 70.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2026 Tiger Data, Inc.
3 * Licensed under the PostgreSQL License. See LICENSE for details.
4 *
5 * shm_toc_standalone.c - Keyed shared-region table over a heap arena
6 *
7 * Standalone implementation of the shm_toc API the parallel build uses. See
8 * vs_shm_toc.h. PG builds use PostgreSQL's shm_toc (backed by a DSM segment)
9 * instead, so this file is compiled only for standalone.
10 */
11
12 #ifdef VS_STANDALONE
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include "standalone/shm_toc.h"
18
19 struct shm_toc
20 {
21 uint64_t magic;
22 char *arena; /* caller-provided chunk arena */
23 size_t nbytes; /* arena capacity */
24 size_t allocated; /* bump offset into the arena */
25
26 /* Key -> region map (grown on insert; separate from the arena). */
27 uint64_t *keys;
28 void **ptrs;
29 size_t nkeys;
30 size_t cap;
31 };
32
33 size_t
34 86 shm_toc_estimate(shm_toc_estimator *e)
35 {
36 86 return e->space_for_chunks;
37 }
38
39 shm_toc *
40 92 shm_toc_create(uint64_t magic, void *address, size_t nbytes)
41 {
42 92 shm_toc *toc = malloc(sizeof(shm_toc));
43
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (toc == NULL)
45 {
46 ✗ fprintf(stderr, "shm_toc_create: out of memory\n");
47 ✗ abort();
48 }
49
50 92 toc->magic = magic;
51 92 toc->arena = (char *)address;
52 92 toc->nbytes = nbytes;
53 92 toc->allocated = 0;
54 92 toc->keys = NULL;
55 92 toc->ptrs = NULL;
56 92 toc->nkeys = 0;
57 92 toc->cap = 0;
58 92 return toc;
59 }
60
61 void *
62 936 shm_toc_allocate(shm_toc *toc, size_t nbytes)
63 {
64 936 size_t offset = VS_TOC_ALIGN(toc->allocated);
65 936 size_t end = offset + VS_TOC_ALIGN(nbytes);
66
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 936 times.
936 if (end > toc->nbytes)
68 {
69 ✗ fprintf(stderr,
70 "shm_toc_allocate: arena exhausted (need %zu, have %zu)\n",
71 end,
72 toc->nbytes);
73 ✗ abort();
74 }
75
76 936 toc->allocated = end;
77 936 return toc->arena + offset;
78 }
79
80 void
81 766 shm_toc_insert(shm_toc *toc, uint64_t key, void *address)
82 {
83
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 670 times.
766 if (toc->nkeys == toc->cap)
84 {
85
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 90 times.
96 size_t newcap = toc->cap == 0 ? 8 : toc->cap * 2;
86 96 uint64_t *nk = realloc(toc->keys, newcap * sizeof(uint64_t));
87 96 void **np = realloc(toc->ptrs, newcap * sizeof(void *));
88
89
2/4
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
96 if (nk == NULL || np == NULL)
90 {
91 ✗ fprintf(stderr, "shm_toc_insert: out of memory\n");
92 ✗ abort();
93 }
94 96 toc->keys = nk;
95 96 toc->ptrs = np;
96 96 toc->cap = newcap;
97 }
98
99 766 toc->keys[toc->nkeys] = key;
100 766 toc->ptrs[toc->nkeys] = address;
101 766 toc->nkeys++;
102 766 }
103
104 void *
105 1138 shm_toc_lookup(shm_toc *toc, uint64_t key, bool noError)
106 {
107
2/2
✓ Branch 0 taken 7634 times.
✓ Branch 1 taken 2 times.
7636 for (size_t i = 0; i < toc->nkeys; i++)
108
2/2
✓ Branch 0 taken 1136 times.
✓ Branch 1 taken 6498 times.
7634 if (toc->keys[i] == key)
109 1136 return toc->ptrs[i];
110
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!noError)
112 {
113 ✗ fprintf(stderr,
114 "shm_toc_lookup: key %llu not found\n",
115 (unsigned long long)key);
116 ✗ abort();
117 }
118 2 return NULL;
119 }
120
121 void
122 92 vs_shm_toc_free(shm_toc *toc)
123 {
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (toc == NULL)
125 ✗ return;
126 92 free(toc->keys);
127 92 free(toc->ptrs);
128 92 free(toc);
129 }
130
131 #endif /* VS_STANDALONE */
132