Age Owner Branch data TLA Line data Source code
1 : : /*--------------------------------------------------------------------------
2 : : *
3 : : * test_lwlock_tranches.c
4 : : * Test code for LWLock tranches allocated by extensions.
5 : : *
6 : : * Copyright (c) 2025-2026, PostgreSQL Global Development Group
7 : : *
8 : : * IDENTIFICATION
9 : : * src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c
10 : : *
11 : : * -------------------------------------------------------------------------
12 : : */
13 : :
14 : : #include "postgres.h"
15 : :
16 : : #include "fmgr.h"
17 : : #include "miscadmin.h"
18 : : #include "storage/lwlock.h"
19 : : #include "utils/builtins.h"
20 : : #include "utils/wait_classes.h"
21 : :
229 nathan@postgresql.or 22 :GNC 1 : PG_MODULE_MAGIC;
23 : :
24 : : static shmem_request_hook_type prev_shmem_request_hook;
25 : : static void test_lwlock_tranches_shmem_request(void);
26 : :
27 : : void
28 : 1 : _PG_init(void)
29 : : {
30 : 1 : prev_shmem_request_hook = shmem_request_hook;
31 : 1 : shmem_request_hook = test_lwlock_tranches_shmem_request;
32 : 1 : }
33 : :
34 : : static void
35 : 1 : test_lwlock_tranches_shmem_request(void)
36 : : {
37 [ - + ]: 1 : if (prev_shmem_request_hook)
229 nathan@postgresql.or 38 :UNC 0 : prev_shmem_request_hook();
39 : :
40 : : /*
41 : : * Request some tranches with RequestNamedLWLockTranche() for
42 : : * test_startup_lwlocks()
43 : : */
30 heikki.linnakangas@i 44 :GNC 1 : RequestNamedLWLockTranche("test_lwlock_tranches_startup", 1);
45 : 1 : RequestNamedLWLockTranche("test_lwlock_tranches_startup10", 10);
229 nathan@postgresql.or 46 : 1 : }
47 : :
48 : : /*
49 : : * Test locks requested with RequestNamedLWLockTranche
50 : : */
30 heikki.linnakangas@i 51 : 2 : PG_FUNCTION_INFO_V1(test_startup_lwlocks);
52 : : Datum
53 : 1 : test_startup_lwlocks(PG_FUNCTION_ARGS)
54 : : {
55 : : LWLockPadded *lwlock_startup;
56 : : LWLockPadded *lwlock_startup10;
57 : :
58 : : /* Check that the locks can be used */
59 : 1 : lwlock_startup = GetNamedLWLockTranche("test_lwlock_tranches_startup");
60 : 1 : lwlock_startup10 = GetNamedLWLockTranche("test_lwlock_tranches_startup10");
61 : :
62 : 1 : LWLockAcquire(&lwlock_startup->lock, LW_EXCLUSIVE);
63 [ + + ]: 11 : for (int i = 0; i < 10; i++)
64 : 10 : LWLockAcquire(&lwlock_startup10[i].lock, LW_EXCLUSIVE);
65 : :
66 : 1 : LWLockRelease(&lwlock_startup->lock);
67 [ + + ]: 11 : for (int i = 0; i < 10; i++)
68 : 10 : LWLockRelease(&lwlock_startup10[i].lock);
69 : :
70 : : /*
71 : : * Check that GetLWLockIdentifier() returns the expected value for
72 : : * tranches
73 : : */
74 [ - + ]: 1 : if (strcmp("test_lwlock_tranches_startup",
75 : : GetLWLockIdentifier(PG_WAIT_LWLOCK, LWTRANCHE_FIRST_USER_DEFINED)) != 0)
30 heikki.linnakangas@i 76 [ # # ]:UNC 0 : elog(ERROR, "incorrect startup lock tranche name");
30 heikki.linnakangas@i 77 [ - + ]:GNC 1 : if (strcmp("test_lwlock_tranches_startup10",
78 : : GetLWLockIdentifier(PG_WAIT_LWLOCK, LWTRANCHE_FIRST_USER_DEFINED + 1)) != 0)
30 heikki.linnakangas@i 79 [ # # ]:UNC 0 : elog(ERROR, "incorrect startup lock tranche name");
80 : :
229 nathan@postgresql.or 81 :GNC 1 : PG_RETURN_VOID();
82 : : }
83 : :
84 : : /*
85 : : * Wrapper for LWLockNewTrancheId().
86 : : */
30 heikki.linnakangas@i 87 : 2 : PG_FUNCTION_INFO_V1(test_lwlock_tranche_create);
88 : : Datum
89 : 257 : test_lwlock_tranche_create(PG_FUNCTION_ARGS)
90 : : {
229 nathan@postgresql.or 91 [ + + ]: 257 : char *tranche_name = PG_ARGISNULL(0) ? NULL : TextDatumGetCString(PG_GETARG_DATUM(0));
92 : : int tranche_id;
93 : :
30 heikki.linnakangas@i 94 : 257 : tranche_id = LWLockNewTrancheId(tranche_name);
95 : :
96 : 254 : PG_RETURN_INT32(tranche_id);
97 : : }
98 : :
99 : : /*
100 : : * Wrapper for GetNamedLWLockTranche().
101 : : */
229 nathan@postgresql.or 102 : 2 : PG_FUNCTION_INFO_V1(test_lwlock_tranche_lookup);
103 : : Datum
104 : 2 : test_lwlock_tranche_lookup(PG_FUNCTION_ARGS)
105 : : {
106 : 2 : char *tranche_name = TextDatumGetCString(PG_GETARG_DATUM(0));
107 : :
108 : 2 : (void) GetNamedLWLockTranche(tranche_name);
109 : :
229 nathan@postgresql.or 110 :UNC 0 : PG_RETURN_VOID();
111 : : }
112 : :
30 heikki.linnakangas@i 113 :GNC 2 : PG_FUNCTION_INFO_V1(test_lwlock_get_lwlock_identifier);
114 : : Datum
115 : 4 : test_lwlock_get_lwlock_identifier(PG_FUNCTION_ARGS)
116 : : {
117 : 4 : int eventId = PG_GETARG_INT32(0);
118 : : const char *tranche_name;
119 : :
120 : 4 : tranche_name = GetLWLockIdentifier(PG_WAIT_LWLOCK, eventId);
121 : :
122 [ + - ]: 4 : if (tranche_name)
123 : 4 : PG_RETURN_TEXT_P(cstring_to_text(tranche_name));
124 : : else
30 heikki.linnakangas@i 125 :UNC 0 : PG_RETURN_NULL();
126 : : }
127 : :
128 : : /*
129 : : * Wrapper for LWLockInitialize().
130 : : */
229 nathan@postgresql.or 131 :GNC 2 : PG_FUNCTION_INFO_V1(test_lwlock_initialize);
132 : : Datum
133 : 1 : test_lwlock_initialize(PG_FUNCTION_ARGS)
134 : : {
135 : 1 : int tranche_id = PG_GETARG_INT32(0);
136 : : LWLock lock;
137 : :
138 : 1 : LWLockInitialize(&lock, tranche_id);
139 : :
229 nathan@postgresql.or 140 :UNC 0 : PG_RETURN_VOID();
141 : : }
|