Line data Source code
1 : /*--------------------------------------------------------------------------
2 : *
3 : * test_dsa.c
4 : * Test dynamic shared memory areas (DSAs)
5 : *
6 : * Copyright (c) 2022-2025, 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"
16 : #include "storage/lwlock.h"
17 : #include "utils/dsa.h"
18 : #include "utils/resowner.h"
19 :
20 2 : PG_MODULE_MAGIC;
21 :
22 : /* Test basic DSA functionality */
23 4 : PG_FUNCTION_INFO_V1(test_dsa_basic);
24 : Datum
25 2 : test_dsa_basic(PG_FUNCTION_ARGS)
26 : {
27 : int tranche_id;
28 : dsa_area *a;
29 : dsa_pointer p[100];
30 :
31 : /* XXX: this tranche is leaked */
32 2 : tranche_id = LWLockNewTrancheId("test_dsa");
33 :
34 2 : a = dsa_create(tranche_id);
35 202 : for (int i = 0; i < 100; i++)
36 : {
37 200 : p[i] = dsa_allocate(a, 1000);
38 200 : snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
39 : }
40 :
41 202 : for (int i = 0; i < 100; i++)
42 : {
43 : char buf[100];
44 :
45 200 : snprintf(buf, 100, "foobar%d", i);
46 200 : if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
47 0 : elog(ERROR, "no match");
48 : }
49 :
50 202 : for (int i = 0; i < 100; i++)
51 : {
52 200 : dsa_free(a, p[i]);
53 : }
54 :
55 2 : dsa_detach(a);
56 :
57 2 : PG_RETURN_VOID();
58 : }
59 :
60 : /* Test using DSA across different resource owners */
61 4 : PG_FUNCTION_INFO_V1(test_dsa_resowners);
62 : Datum
63 2 : test_dsa_resowners(PG_FUNCTION_ARGS)
64 : {
65 : int tranche_id;
66 : dsa_area *a;
67 : dsa_pointer p[10000];
68 : ResourceOwner oldowner;
69 : ResourceOwner childowner;
70 :
71 : /* XXX: this tranche is leaked */
72 2 : tranche_id = LWLockNewTrancheId("test_dsa");
73 :
74 : /* Create DSA in parent resource owner */
75 2 : a = dsa_create(tranche_id);
76 :
77 : /*
78 : * Switch to child resource owner, and do a bunch of allocations in the
79 : * DSA
80 : */
81 2 : oldowner = CurrentResourceOwner;
82 2 : childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
83 2 : CurrentResourceOwner = childowner;
84 :
85 20002 : for (int i = 0; i < 10000; i++)
86 : {
87 20000 : p[i] = dsa_allocate(a, 1000);
88 20000 : snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
89 : }
90 :
91 : /* Also test freeing, by freeing some of the allocations. */
92 1002 : for (int i = 0; i < 500; i++)
93 1000 : dsa_free(a, p[i]);
94 :
95 : /* Release the child resource owner */
96 2 : CurrentResourceOwner = oldowner;
97 2 : ResourceOwnerRelease(childowner,
98 : RESOURCE_RELEASE_BEFORE_LOCKS,
99 : true, false);
100 2 : ResourceOwnerRelease(childowner,
101 : RESOURCE_RELEASE_LOCKS,
102 : true, false);
103 2 : ResourceOwnerRelease(childowner,
104 : RESOURCE_RELEASE_AFTER_LOCKS,
105 : true, false);
106 2 : ResourceOwnerDelete(childowner);
107 :
108 2 : dsa_detach(a);
109 :
110 2 : PG_RETURN_VOID();
111 : }
|