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