LCOV - code coverage report
Current view: top level - src/backend/utils/activity - pgstat_lock.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 92.5 % 53 49
Test Date: 2026-07-08 05:15:38 Functions: 87.5 % 8 7
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 87.5 % 8 7

             Branch data     Line data    Source code
       1                 :             : /* -------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * pgstat_lock.c
       4                 :             :  *    Implementation of lock statistics.
       5                 :             :  *
       6                 :             :  * This file contains the implementation of lock statistics.  It is kept
       7                 :             :  * separate from pgstat.c to enforce the line between the statistics
       8                 :             :  * access / storage implementation and the details about individual types
       9                 :             :  * of statistics.
      10                 :             :  *
      11                 :             :  * Copyright (c) 2021-2026, PostgreSQL Global Development Group
      12                 :             :  *
      13                 :             :  * IDENTIFICATION
      14                 :             :  *    src/backend/utils/activity/pgstat_lock.c
      15                 :             :  * -------------------------------------------------------------------------
      16                 :             :  */
      17                 :             : 
      18                 :             : #include "postgres.h"
      19                 :             : 
      20                 :             : #include "utils/pgstat_internal.h"
      21                 :             : 
      22                 :             : static PgStat_PendingLock PendingLockStats;
      23                 :             : static bool have_lockstats = false;
      24                 :             : 
      25                 :             : PgStat_Lock *
      26                 :          12 : pgstat_fetch_stat_lock(void)
      27                 :             : {
      28                 :          12 :     pgstat_snapshot_fixed(PGSTAT_KIND_LOCK);
      29                 :             : 
      30                 :          12 :     return &pgStatLocal.snapshot.lock;
      31                 :             : }
      32                 :             : 
      33                 :             : /*
      34                 :             :  * Simpler wrapper of pgstat_lock_flush_cb()
      35                 :             :  */
      36                 :             : void
      37                 :           0 : pgstat_lock_flush(bool nowait)
      38                 :             : {
      39                 :           0 :     (void) pgstat_lock_flush_cb(nowait);
      40                 :           0 : }
      41                 :             : 
      42                 :             : /*
      43                 :             :  * Flush out locally pending lock statistics
      44                 :             :  *
      45                 :             :  * If no stats have been recorded, this function returns false.
      46                 :             :  *
      47                 :             :  * If nowait is true, this function returns true if the lock could not be
      48                 :             :  * acquired. Otherwise, return false.
      49                 :             :  */
      50                 :             : bool
      51                 :       40118 : pgstat_lock_flush_cb(bool nowait)
      52                 :             : {
      53                 :             :     LWLock     *lckstat_lock;
      54                 :             :     PgStatShared_Lock *shstats;
      55                 :             : 
      56         [ +  + ]:       40118 :     if (!have_lockstats)
      57                 :       39887 :         return false;
      58                 :             : 
      59                 :         231 :     shstats = &pgStatLocal.shmem->lock;
      60                 :         231 :     lckstat_lock = &shstats->lock;
      61                 :             : 
      62         [ +  + ]:         231 :     if (!nowait)
      63                 :         217 :         LWLockAcquire(lckstat_lock, LW_EXCLUSIVE);
      64         [ -  + ]:          14 :     else if (!LWLockConditionalAcquire(lckstat_lock, LW_EXCLUSIVE))
      65                 :           0 :         return true;
      66                 :             : 
      67         [ +  + ]:        3003 :     for (int i = 0; i <= LOCKTAG_LAST_TYPE; i++)
      68                 :             :     {
      69                 :             : #define LOCKSTAT_ACC(fld) \
      70                 :             :     (shstats->stats.stats[i].fld += PendingLockStats.stats[i].fld)
      71                 :        2772 :         LOCKSTAT_ACC(waits);
      72                 :        2772 :         LOCKSTAT_ACC(wait_time);
      73                 :        2772 :         LOCKSTAT_ACC(fastpath_exceeded);
      74                 :             : #undef LOCKSTAT_ACC
      75                 :             :     }
      76                 :             : 
      77                 :         231 :     LWLockRelease(lckstat_lock);
      78                 :             : 
      79                 :         231 :     memset(&PendingLockStats, 0, sizeof(PendingLockStats));
      80                 :         231 :     have_lockstats = false;
      81                 :             : 
      82                 :         231 :     return false;
      83                 :             : }
      84                 :             : 
      85                 :             : void
      86                 :        1246 : pgstat_lock_init_shmem_cb(void *stats)
      87                 :             : {
      88                 :        1246 :     PgStatShared_Lock *stat_shmem = (PgStatShared_Lock *) stats;
      89                 :             : 
      90                 :        1246 :     LWLockInitialize(&stat_shmem->lock, LWTRANCHE_PGSTATS_DATA);
      91                 :        1246 : }
      92                 :             : 
      93                 :             : void
      94                 :         261 : pgstat_lock_reset_all_cb(TimestampTz ts)
      95                 :             : {
      96                 :         261 :     LWLock     *lckstat_lock = &pgStatLocal.shmem->lock.lock;
      97                 :             : 
      98                 :         261 :     LWLockAcquire(lckstat_lock, LW_EXCLUSIVE);
      99                 :             : 
     100                 :         261 :     pgStatLocal.shmem->lock.stats.stat_reset_timestamp = ts;
     101                 :             : 
     102                 :         261 :     memset(pgStatLocal.shmem->lock.stats.stats, 0,
     103                 :             :            sizeof(pgStatLocal.shmem->lock.stats.stats));
     104                 :             : 
     105                 :         261 :     LWLockRelease(lckstat_lock);
     106                 :         261 : }
     107                 :             : 
     108                 :             : void
     109                 :         809 : pgstat_lock_snapshot_cb(void)
     110                 :             : {
     111                 :         809 :     LWLock     *lckstat_lock = &pgStatLocal.shmem->lock.lock;
     112                 :             : 
     113                 :         809 :     LWLockAcquire(lckstat_lock, LW_SHARED);
     114                 :             : 
     115                 :         809 :     pgStatLocal.snapshot.lock = pgStatLocal.shmem->lock.stats;
     116                 :             : 
     117                 :         809 :     LWLockRelease(lckstat_lock);
     118                 :         809 : }
     119                 :             : 
     120                 :             : /*
     121                 :             :  * Increment counter for lock not acquired with the fast-path, per lock
     122                 :             :  * type, due to the fast-path slot limit reached.
     123                 :             :  *
     124                 :             :  * Note: This function should not be called in performance-sensitive paths,
     125                 :             :  * like lock acquisitions.
     126                 :             :  */
     127                 :             : void
     128                 :       89507 : pgstat_count_lock_fastpath_exceeded(uint8 locktag_type)
     129                 :             : {
     130                 :             :     Assert(locktag_type <= LOCKTAG_LAST_TYPE);
     131                 :       89507 :     PendingLockStats.stats[locktag_type].fastpath_exceeded++;
     132                 :       89507 :     have_lockstats = true;
     133                 :       89507 :     pgstat_report_fixed = true;
     134                 :             : 
     135                 :       89507 :     pgstat_count_backend_lock_fastpath_exceeded(locktag_type);
     136                 :       89507 : }
     137                 :             : 
     138                 :             : /*
     139                 :             :  * Increment the number of waits and wait time, per lock type.
     140                 :             :  *
     141                 :             :  * Note: This function should not be called in performance-sensitive paths,
     142                 :             :  * like lock acquisitions.
     143                 :             :  */
     144                 :             : void
     145                 :          27 : pgstat_count_lock_waits(uint8 locktag_type, PgStat_Counter usecs)
     146                 :             : {
     147                 :             :     Assert(locktag_type <= LOCKTAG_LAST_TYPE);
     148                 :          27 :     PendingLockStats.stats[locktag_type].waits++;
     149                 :          27 :     PendingLockStats.stats[locktag_type].wait_time += usecs;
     150                 :          27 :     have_lockstats = true;
     151                 :          27 :     pgstat_report_fixed = true;
     152                 :             : 
     153                 :          27 :     pgstat_count_backend_lock_waits(locktag_type, usecs);
     154                 :          27 : }
        

Generated by: LCOV version 2.0-1