LCOV - code coverage report
Current view: top level - src/backend/utils/adt - waitfuncs.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 41 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 1 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 30 0

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * waitfuncs.c
       4                 :             :  *              Functions for SQL access to syntheses of multiple contention types.
       5                 :             :  *
       6                 :             :  * Copyright (c) 2002-2026, 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 "storage/proc.h"
      18                 :             : #include "storage/procarray.h"
      19                 :             : #include "utils/array.h"
      20                 :             : #include "utils/fmgrprotos.h"
      21                 :             : #include "utils/wait_event.h"
      22                 :             : 
      23                 :             : #define UINT32_ACCESS_ONCE(var)          ((uint32)(*((volatile uint32 *)&(var))))
      24                 :             : 
      25                 :             : 
      26                 :             : /*
      27                 :             :  * pg_isolation_test_session_is_blocked - support function for isolationtester
      28                 :             :  *
      29                 :             :  * Check if specified PID is blocked by any of the PIDs listed in the second
      30                 :             :  * argument.  Currently, this looks for blocking caused by waiting for
      31                 :             :  * injection points, heavyweight locks, or safe snapshots.  We ignore blockage
      32                 :             :  * caused by PIDs not directly under the isolationtester's control, eg
      33                 :             :  * autovacuum.
      34                 :             :  *
      35                 :             :  * This is an undocumented function intended for use by the isolation tester,
      36                 :             :  * and may change in future releases as required for testing purposes.
      37                 :             :  */
      38                 :             : Datum
      39                 :           0 : pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
      40                 :             : {
      41                 :           0 :         int                     blocked_pid = PG_GETARG_INT32(0);
      42                 :           0 :         ArrayType  *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
      43                 :           0 :         PGPROC     *proc;
      44                 :           0 :         const char *wait_event_type;
      45                 :           0 :         ArrayType  *blocking_pids_a;
      46                 :           0 :         int32      *interesting_pids;
      47                 :           0 :         int32      *blocking_pids;
      48                 :           0 :         int                     num_interesting_pids;
      49                 :           0 :         int                     num_blocking_pids;
      50                 :           0 :         int                     dummy;
      51                 :           0 :         int                     i,
      52                 :             :                                 j;
      53                 :             : 
      54                 :             :         /* Check if blocked_pid is in an injection point. */
      55                 :           0 :         proc = BackendPidGetProc(blocked_pid);
      56         [ #  # ]:           0 :         if (proc == NULL)
      57                 :           0 :                 PG_RETURN_BOOL(false);  /* session gone: definitely unblocked */
      58                 :           0 :         wait_event_type =
      59                 :           0 :                 pgstat_get_wait_event_type(UINT32_ACCESS_ONCE(proc->wait_event_info));
      60   [ #  #  #  # ]:           0 :         if (wait_event_type && strcmp("InjectionPoint", wait_event_type) == 0)
      61                 :           0 :                 PG_RETURN_BOOL(true);
      62                 :             : 
      63                 :             :         /* Validate the passed-in array */
      64         [ #  # ]:           0 :         Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
      65         [ #  # ]:           0 :         if (array_contains_nulls(interesting_pids_a))
      66   [ #  #  #  # ]:           0 :                 elog(ERROR, "array must not contain nulls");
      67         [ #  # ]:           0 :         interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
      68                 :           0 :         num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
      69                 :           0 :                                                                                   ARR_DIMS(interesting_pids_a));
      70                 :             : 
      71                 :             :         /*
      72                 :             :          * Get the PIDs of all sessions blocking the given session's attempt to
      73                 :             :          * acquire heavyweight locks.
      74                 :             :          */
      75                 :           0 :         blocking_pids_a =
      76                 :           0 :                 DatumGetArrayTypeP(DirectFunctionCall1(pg_blocking_pids, Int32GetDatum(blocked_pid)));
      77                 :             : 
      78         [ #  # ]:           0 :         Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
      79         [ #  # ]:           0 :         Assert(!array_contains_nulls(blocking_pids_a));
      80         [ #  # ]:           0 :         blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
      81                 :           0 :         num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
      82                 :           0 :                                                                            ARR_DIMS(blocking_pids_a));
      83                 :             : 
      84                 :             :         /*
      85                 :             :          * Check if any of these are in the list of interesting PIDs, that being
      86                 :             :          * the sessions that the isolation tester is running.  We don't use
      87                 :             :          * "arrayoverlaps" here, because it would lead to cache lookups and one of
      88                 :             :          * our goals is to run quickly with debug_discard_caches > 0.  We expect
      89                 :             :          * blocking_pids to be usually empty and otherwise a very small number in
      90                 :             :          * isolation tester cases, so make that the outer loop of a naive search
      91                 :             :          * for a match.
      92                 :             :          */
      93         [ #  # ]:           0 :         for (i = 0; i < num_blocking_pids; i++)
      94         [ #  # ]:           0 :                 for (j = 0; j < num_interesting_pids; j++)
      95                 :             :                 {
      96         [ #  # ]:           0 :                         if (blocking_pids[i] == interesting_pids[j])
      97                 :           0 :                                 PG_RETURN_BOOL(true);
      98                 :           0 :                 }
      99                 :             : 
     100                 :             :         /*
     101                 :             :          * Check if blocked_pid is waiting for a safe snapshot.  We could in
     102                 :             :          * theory check the resulting array of blocker PIDs against the
     103                 :             :          * interesting PIDs list, but since there is no danger of autovacuum
     104                 :             :          * blocking GetSafeSnapshot there seems to be no point in expending cycles
     105                 :             :          * on allocating a buffer and searching for overlap; so it's presently
     106                 :             :          * sufficient for the isolation tester's purposes to use a single element
     107                 :             :          * buffer and check if the number of safe snapshot blockers is non-zero.
     108                 :             :          */
     109         [ #  # ]:           0 :         if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
     110                 :           0 :                 PG_RETURN_BOOL(true);
     111                 :             : 
     112                 :           0 :         PG_RETURN_BOOL(false);
     113                 :           0 : }
        

Generated by: LCOV version 2.3.2-1