Age Owner Branch data TLA 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/dsm_registry.h"
17 : : #include "storage/lwlock.h"
18 : : #include "utils/dsa.h"
19 : : #include "utils/resowner.h"
20 : :
763 heikki.linnakangas@i 21 :CBC 1 : PG_MODULE_MAGIC;
22 : :
23 : : static void
2 nathan@postgresql.or 24 :GNC 1 : init_tranche(void *ptr, void *arg)
25 : : {
35 26 : 1 : int *tranche_id = (int *) ptr;
27 : :
28 : 1 : *tranche_id = LWLockNewTrancheId("test_dsa");
29 : 1 : }
30 : :
31 : : /* Test basic DSA functionality */
763 heikki.linnakangas@i 32 :CBC 2 : PG_FUNCTION_INFO_V1(test_dsa_basic);
33 : : Datum
34 : 1 : test_dsa_basic(PG_FUNCTION_ARGS)
35 : : {
36 : : int *tranche_id;
37 : : bool found;
38 : : dsa_area *a;
39 : : dsa_pointer p[100];
40 : :
35 nathan@postgresql.or 41 :GNC 1 : tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
42 : : init_tranche, &found, NULL);
43 : :
44 : 1 : a = dsa_create(*tranche_id);
763 heikki.linnakangas@i 45 [ + + ]:CBC 101 : for (int i = 0; i < 100; i++)
46 : : {
47 : 100 : p[i] = dsa_allocate(a, 1000);
48 : 100 : snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
49 : : }
50 : :
51 [ + + ]: 101 : for (int i = 0; i < 100; i++)
52 : : {
53 : : char buf[100];
54 : :
55 : 100 : snprintf(buf, 100, "foobar%d", i);
56 [ - + ]: 100 : if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
763 heikki.linnakangas@i 57 [ # # ]:UBC 0 : elog(ERROR, "no match");
58 : : }
59 : :
763 heikki.linnakangas@i 60 [ + + ]:CBC 101 : for (int i = 0; i < 100; i++)
61 : : {
62 : 100 : dsa_free(a, p[i]);
63 : : }
64 : :
65 : 1 : dsa_detach(a);
66 : :
67 : 1 : PG_RETURN_VOID();
68 : : }
69 : :
70 : : /* Test using DSA across different resource owners */
71 : 2 : PG_FUNCTION_INFO_V1(test_dsa_resowners);
72 : : Datum
73 : 1 : test_dsa_resowners(PG_FUNCTION_ARGS)
74 : : {
75 : : int *tranche_id;
76 : : bool found;
77 : : dsa_area *a;
78 : : dsa_pointer p[10000];
79 : : ResourceOwner oldowner;
80 : : ResourceOwner childowner;
81 : :
35 nathan@postgresql.or 82 :GNC 1 : tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
83 : : init_tranche, &found, NULL);
84 : :
85 : : /* Create DSA in parent resource owner */
86 : 1 : a = dsa_create(*tranche_id);
87 : :
88 : : /*
89 : : * Switch to child resource owner, and do a bunch of allocations in the
90 : : * DSA
91 : : */
763 heikki.linnakangas@i 92 :CBC 1 : oldowner = CurrentResourceOwner;
93 : 1 : childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
94 : 1 : CurrentResourceOwner = childowner;
95 : :
96 [ + + ]: 10001 : for (int i = 0; i < 10000; i++)
97 : : {
98 : 10000 : p[i] = dsa_allocate(a, 1000);
99 : 10000 : snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
100 : : }
101 : :
102 : : /* Also test freeing, by freeing some of the allocations. */
103 [ + + ]: 501 : for (int i = 0; i < 500; i++)
104 : 500 : dsa_free(a, p[i]);
105 : :
106 : : /* Release the child resource owner */
107 : 1 : CurrentResourceOwner = oldowner;
108 : 1 : ResourceOwnerRelease(childowner,
109 : : RESOURCE_RELEASE_BEFORE_LOCKS,
110 : : true, false);
111 : 1 : ResourceOwnerRelease(childowner,
112 : : RESOURCE_RELEASE_LOCKS,
113 : : true, false);
114 : 1 : ResourceOwnerRelease(childowner,
115 : : RESOURCE_RELEASE_AFTER_LOCKS,
116 : : true, false);
117 : 1 : ResourceOwnerDelete(childowner);
118 : :
119 : 1 : dsa_detach(a);
120 : :
121 : 1 : PG_RETURN_VOID();
122 : : }
|