Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit abfbd13

Browse files
committed
Create waitfuncs.c for pg_isolation_test_session_is_blocked().
The next commit makes the function inspect an additional non-lock contention source, so it no longer fits in lockfuncs.c. Reviewed by Robert Haas. Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
1 parent bb93640 commit abfbd13

File tree

4 files changed

+98
-79
lines changed

4 files changed

+98
-79
lines changed

src/backend/utils/adt/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ OBJS = \
116116
varchar.o \
117117
varlena.o \
118118
version.o \
119+
waitfuncs.o \
119120
windowfuncs.o \
120121
xid.o \
121122
xid8funcs.o \

src/backend/utils/adt/lockfuncs.c

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "postgres.h"
1414

1515
#include "access/htup_details.h"
16-
#include "catalog/pg_type.h"
1716
#include "funcapi.h"
1817
#include "miscadmin.h"
1918
#include "storage/predicate_internals.h"
@@ -601,84 +600,6 @@ pg_safe_snapshot_blocking_pids(PG_FUNCTION_ARGS)
601600
}
602601

603602

604-
/*
605-
* pg_isolation_test_session_is_blocked - support function for isolationtester
606-
*
607-
* Check if specified PID is blocked by any of the PIDs listed in the second
608-
* argument. Currently, this looks for blocking caused by waiting for
609-
* heavyweight locks or safe snapshots. We ignore blockage caused by PIDs
610-
* not directly under the isolationtester's control, eg autovacuum.
611-
*
612-
* This is an undocumented function intended for use by the isolation tester,
613-
* and may change in future releases as required for testing purposes.
614-
*/
615-
Datum
616-
pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
617-
{
618-
int blocked_pid = PG_GETARG_INT32(0);
619-
ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
620-
ArrayType *blocking_pids_a;
621-
int32 *interesting_pids;
622-
int32 *blocking_pids;
623-
int num_interesting_pids;
624-
int num_blocking_pids;
625-
int dummy;
626-
int i,
627-
j;
628-
629-
/* Validate the passed-in array */
630-
Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
631-
if (array_contains_nulls(interesting_pids_a))
632-
elog(ERROR, "array must not contain nulls");
633-
interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
634-
num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
635-
ARR_DIMS(interesting_pids_a));
636-
637-
/*
638-
* Get the PIDs of all sessions blocking the given session's attempt to
639-
* acquire heavyweight locks.
640-
*/
641-
blocking_pids_a =
642-
DatumGetArrayTypeP(DirectFunctionCall1(pg_blocking_pids, blocked_pid));
643-
644-
Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
645-
Assert(!array_contains_nulls(blocking_pids_a));
646-
blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
647-
num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
648-
ARR_DIMS(blocking_pids_a));
649-
650-
/*
651-
* Check if any of these are in the list of interesting PIDs, that being
652-
* the sessions that the isolation tester is running. We don't use
653-
* "arrayoverlaps" here, because it would lead to cache lookups and one of
654-
* our goals is to run quickly with debug_discard_caches > 0. We expect
655-
* blocking_pids to be usually empty and otherwise a very small number in
656-
* isolation tester cases, so make that the outer loop of a naive search
657-
* for a match.
658-
*/
659-
for (i = 0; i < num_blocking_pids; i++)
660-
for (j = 0; j < num_interesting_pids; j++)
661-
{
662-
if (blocking_pids[i] == interesting_pids[j])
663-
PG_RETURN_BOOL(true);
664-
}
665-
666-
/*
667-
* Check if blocked_pid is waiting for a safe snapshot. We could in
668-
* theory check the resulting array of blocker PIDs against the
669-
* interesting PIDs list, but since there is no danger of autovacuum
670-
* blocking GetSafeSnapshot there seems to be no point in expending cycles
671-
* on allocating a buffer and searching for overlap; so it's presently
672-
* sufficient for the isolation tester's purposes to use a single element
673-
* buffer and check if the number of safe snapshot blockers is non-zero.
674-
*/
675-
if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
676-
PG_RETURN_BOOL(true);
677-
678-
PG_RETURN_BOOL(false);
679-
}
680-
681-
682603
/*
683604
* Functions for manipulating advisory locks
684605
*

src/backend/utils/adt/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ backend_sources += files(
103103
'varchar.c',
104104
'varlena.c',
105105
'version.c',
106+
'waitfuncs.c',
106107
'windowfuncs.c',
107108
'xid.c',
108109
'xid8funcs.c',

src/backend/utils/adt/waitfuncs.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* waitfuncs.c
4+
* Functions for SQL access to syntheses of multiple contention types.
5+
*
6+
* Copyright (c) 2002-2024, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/backend/utils/adt/waitfuncs.c
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
#include "postgres.h"
14+
15+
#include "catalog/pg_type.h"
16+
#include "storage/predicate_internals.h"
17+
#include "utils/array.h"
18+
#include "utils/builtins.h"
19+
20+
21+
/*
22+
* pg_isolation_test_session_is_blocked - support function for isolationtester
23+
*
24+
* Check if specified PID is blocked by any of the PIDs listed in the second
25+
* argument. Currently, this looks for blocking caused by waiting for
26+
* heavyweight locks or safe snapshots. We ignore blockage caused by PIDs
27+
* not directly under the isolationtester's control, eg autovacuum.
28+
*
29+
* This is an undocumented function intended for use by the isolation tester,
30+
* and may change in future releases as required for testing purposes.
31+
*/
32+
Datum
33+
pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
34+
{
35+
int blocked_pid = PG_GETARG_INT32(0);
36+
ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
37+
ArrayType *blocking_pids_a;
38+
int32 *interesting_pids;
39+
int32 *blocking_pids;
40+
int num_interesting_pids;
41+
int num_blocking_pids;
42+
int dummy;
43+
int i,
44+
j;
45+
46+
/* Validate the passed-in array */
47+
Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
48+
if (array_contains_nulls(interesting_pids_a))
49+
elog(ERROR, "array must not contain nulls");
50+
interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
51+
num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
52+
ARR_DIMS(interesting_pids_a));
53+
54+
/*
55+
* Get the PIDs of all sessions blocking the given session's attempt to
56+
* acquire heavyweight locks.
57+
*/
58+
blocking_pids_a =
59+
DatumGetArrayTypeP(DirectFunctionCall1(pg_blocking_pids, blocked_pid));
60+
61+
Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
62+
Assert(!array_contains_nulls(blocking_pids_a));
63+
blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
64+
num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
65+
ARR_DIMS(blocking_pids_a));
66+
67+
/*
68+
* Check if any of these are in the list of interesting PIDs, that being
69+
* the sessions that the isolation tester is running. We don't use
70+
* "arrayoverlaps" here, because it would lead to cache lookups and one of
71+
* our goals is to run quickly with debug_discard_caches > 0. We expect
72+
* blocking_pids to be usually empty and otherwise a very small number in
73+
* isolation tester cases, so make that the outer loop of a naive search
74+
* for a match.
75+
*/
76+
for (i = 0; i < num_blocking_pids; i++)
77+
for (j = 0; j < num_interesting_pids; j++)
78+
{
79+
if (blocking_pids[i] == interesting_pids[j])
80+
PG_RETURN_BOOL(true);
81+
}
82+
83+
/*
84+
* Check if blocked_pid is waiting for a safe snapshot. We could in
85+
* theory check the resulting array of blocker PIDs against the
86+
* interesting PIDs list, but since there is no danger of autovacuum
87+
* blocking GetSafeSnapshot there seems to be no point in expending cycles
88+
* on allocating a buffer and searching for overlap; so it's presently
89+
* sufficient for the isolation tester's purposes to use a single element
90+
* buffer and check if the number of safe snapshot blockers is non-zero.
91+
*/
92+
if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
93+
PG_RETURN_BOOL(true);
94+
95+
PG_RETURN_BOOL(false);
96+
}

0 commit comments

Comments
 (0)