PostgreSQL Source Code git master
Loading...
Searching...
No Matches
test_dsa.c
Go to the documentation of this file.
1/*--------------------------------------------------------------------------
2 *
3 * test_dsa.c
4 * Test dynamic shared memory areas (DSAs)
5 *
6 * Copyright (c) 2022-2026, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/test/modules/test_dsa/test_dsa.c
10 *
11 * -------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "fmgr.h"
17#include "storage/lwlock.h"
18#include "utils/dsa.h"
19#include "utils/freepage.h"
20#include "utils/resowner.h"
21
23
24static void
25init_tranche(void *ptr, void *arg)
26{
27 int *tranche_id = (int *) ptr;
28
29 *tranche_id = LWLockNewTrancheId("test_dsa");
30}
31
32/* Test basic DSA functionality */
36{
37 int *tranche_id;
38 bool found;
39 dsa_area *a;
40 dsa_pointer p[100];
41
42 tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
43 init_tranche, &found, NULL);
44
45 a = dsa_create(*tranche_id);
46 for (int i = 0; i < 100; i++)
47 {
48 p[i] = dsa_allocate(a, 1000);
49 snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
50 }
51
52 for (int i = 0; i < 100; i++)
53 {
54 char buf[100];
55
56 snprintf(buf, 100, "foobar%d", i);
57 if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
58 elog(ERROR, "no match");
59 }
60
61 for (int i = 0; i < 100; i++)
62 {
63 dsa_free(a, p[i]);
64 }
65
67
69}
70
71/* Test using DSA across different resource owners */
75{
76 int *tranche_id;
77 bool found;
78 dsa_area *a;
79 dsa_pointer p[10000];
80 ResourceOwner oldowner;
82
83 tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
84 init_tranche, &found, NULL);
85
86 /* Create DSA in parent resource owner */
87 a = dsa_create(*tranche_id);
88
89 /*
90 * Switch to child resource owner, and do a bunch of allocations in the
91 * DSA
92 */
93 oldowner = CurrentResourceOwner;
94 childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
96
97 for (int i = 0; i < 10000; i++)
98 {
99 p[i] = dsa_allocate(a, 1000);
100 snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
101 }
102
103 /* Also test freeing, by freeing some of the allocations. */
104 for (int i = 0; i < 500; i++)
105 dsa_free(a, p[i]);
106
107 /* Release the child resource owner */
108 CurrentResourceOwner = oldowner;
111 true, false);
114 true, false);
117 true, false);
119
120 dsa_detach(a);
121
123}
124
125/*
126 * test_dsa_allocate
127 *
128 * Test DSA allocation across a range of sizes to exercise the pagemap
129 * sizing logic in make_new_segment(). A fresh DSA is created for each
130 * iteration so that each allocation triggers a new segment creation,
131 * including the odd-sized segment path.
132 */
134Datum
136{
139 int step = PG_GETARG_INT32(2);
140 size_t usable_pages;
141 int *tranche_id;
142 bool found;
143 dsa_area *a;
145
147 elog(ERROR, "incorrect start and end parameters");
148
149 tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
150 init_tranche, &found, NULL);
151
152 for (usable_pages = start_num_pages; usable_pages < end_num_pages; usable_pages += step)
153 {
154 a = dsa_create(*tranche_id);
155 dp = dsa_allocate(a, usable_pages * FPM_PAGE_SIZE);
156
157 dsa_free(a, dp);
158 dsa_detach(a);
159 }
160
162}
void * dsa_get_address(dsa_area *area, dsa_pointer dp)
Definition dsa.c:957
void dsa_detach(dsa_area *area)
Definition dsa.c:2002
void dsa_free(dsa_area *area, dsa_pointer dp)
Definition dsa.c:841
uint64 dsa_pointer
Definition dsa.h:62
#define dsa_create(tranche_id)
Definition dsa.h:117
#define dsa_allocate(area, size)
Definition dsa.h:109
void * GetNamedDSMSegment(const char *name, size_t size, void(*init_callback)(void *ptr, void *arg), bool *found, void *arg)
Datum arg
Definition elog.c:1322
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_FUNCTION_INFO_V1(funcname)
Definition fmgr.h:417
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define FPM_PAGE_SIZE
Definition freepage.h:30
int a
Definition isn.c:73
int i
Definition isn.c:77
int LWLockNewTrancheId(const char *name)
Definition lwlock.c:597
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define snprintf
Definition port.h:260
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition resowner.c:418
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition resowner.c:655
void ResourceOwnerDelete(ResourceOwner owner)
Definition resowner.c:868
@ RESOURCE_RELEASE_LOCKS
Definition resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition resowner.h:56
Datum test_dsa_basic(PG_FUNCTION_ARGS)
Definition test_dsa.c:35
static void init_tranche(void *ptr, void *arg)
Definition test_dsa.c:25
PG_MODULE_MAGIC
Definition test_dsa.c:22
Datum test_dsa_resowners(PG_FUNCTION_ARGS)
Definition test_dsa.c:74
Datum test_dsa_allocate(PG_FUNCTION_ARGS)
Definition test_dsa.c:135