LCOV - code coverage report
Current view: top level - src/test/modules/injection_points - injection_stats_fixed.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 69 70 98.6 %
Date: 2025-10-10 19:18:08 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*--------------------------------------------------------------------------
       2             :  *
       3             :  * injection_stats_fixed.c
       4             :  *      Code for fixed-numbered statistics of injection points.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  * IDENTIFICATION
      10             :  *      src/test/modules/injection_points/injection_stats_fixed.c
      11             :  *
      12             :  * -------------------------------------------------------------------------
      13             :  */
      14             : 
      15             : #include "postgres.h"
      16             : 
      17             : #include "fmgr.h"
      18             : 
      19             : #include "access/htup_details.h"
      20             : #include "common/hashfn.h"
      21             : #include "funcapi.h"
      22             : #include "injection_stats.h"
      23             : #include "pgstat.h"
      24             : #include "utils/builtins.h"
      25             : #include "utils/pgstat_internal.h"
      26             : 
      27             : /* Structures for statistics of injection points, fixed-size */
      28             : typedef struct PgStat_StatInjFixedEntry
      29             : {
      30             :     PgStat_Counter numattach;   /* number of points attached */
      31             :     PgStat_Counter numdetach;   /* number of points detached */
      32             :     PgStat_Counter numrun;      /* number of points run */
      33             :     PgStat_Counter numcached;   /* number of points cached */
      34             :     PgStat_Counter numloaded;   /* number of points loaded */
      35             :     TimestampTz stat_reset_timestamp;
      36             : } PgStat_StatInjFixedEntry;
      37             : 
      38             : typedef struct PgStatShared_InjectionPointFixed
      39             : {
      40             :     LWLock      lock;           /* protects all the counters */
      41             :     uint32      changecount;
      42             :     PgStat_StatInjFixedEntry stats;
      43             :     PgStat_StatInjFixedEntry reset_offset;
      44             : } PgStatShared_InjectionPointFixed;
      45             : 
      46             : /* Callbacks for fixed-numbered stats */
      47             : static void injection_stats_fixed_init_shmem_cb(void *stats);
      48             : static void injection_stats_fixed_reset_all_cb(TimestampTz ts);
      49             : static void injection_stats_fixed_snapshot_cb(void);
      50             : 
      51             : static const PgStat_KindInfo injection_stats_fixed = {
      52             :     .name = "injection_points_fixed",
      53             :     .fixed_amount = true,
      54             :     .write_to_file = true,
      55             : 
      56             :     .shared_size = sizeof(PgStat_StatInjFixedEntry),
      57             :     .shared_data_off = offsetof(PgStatShared_InjectionPointFixed, stats),
      58             :     .shared_data_len = sizeof(((PgStatShared_InjectionPointFixed *) 0)->stats),
      59             : 
      60             :     .init_shmem_cb = injection_stats_fixed_init_shmem_cb,
      61             :     .reset_all_cb = injection_stats_fixed_reset_all_cb,
      62             :     .snapshot_cb = injection_stats_fixed_snapshot_cb,
      63             : };
      64             : 
      65             : /*
      66             :  * Kind ID reserved for statistics of injection points.
      67             :  */
      68             : #define PGSTAT_KIND_INJECTION_FIXED 26
      69             : 
      70             : /* Track if fixed-numbered stats are loaded */
      71             : static bool inj_fixed_loaded = false;
      72             : 
      73             : static void
      74          10 : injection_stats_fixed_init_shmem_cb(void *stats)
      75             : {
      76          10 :     PgStatShared_InjectionPointFixed *stats_shmem =
      77             :         (PgStatShared_InjectionPointFixed *) stats;
      78             : 
      79          10 :     LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
      80          10 : }
      81             : 
      82             : static void
      83           2 : injection_stats_fixed_reset_all_cb(TimestampTz ts)
      84             : {
      85             :     PgStatShared_InjectionPointFixed *stats_shmem =
      86           2 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
      87             : 
      88           2 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
      89           2 :     pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
      90           2 :                                     &stats_shmem->stats,
      91             :                                     sizeof(stats_shmem->stats),
      92             :                                     &stats_shmem->changecount);
      93           2 :     stats_shmem->stats.stat_reset_timestamp = ts;
      94           2 :     LWLockRelease(&stats_shmem->lock);
      95           2 : }
      96             : 
      97             : static void
      98          12 : injection_stats_fixed_snapshot_cb(void)
      99             : {
     100             :     PgStatShared_InjectionPointFixed *stats_shmem =
     101          12 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
     102             :     PgStat_StatInjFixedEntry *stat_snap =
     103          12 :         pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
     104          12 :     PgStat_StatInjFixedEntry *reset_offset = &stats_shmem->reset_offset;
     105             :     PgStat_StatInjFixedEntry reset;
     106             : 
     107          12 :     pgstat_copy_changecounted_stats(stat_snap,
     108          12 :                                     &stats_shmem->stats,
     109             :                                     sizeof(stats_shmem->stats),
     110             :                                     &stats_shmem->changecount);
     111             : 
     112          12 :     LWLockAcquire(&stats_shmem->lock, LW_SHARED);
     113          12 :     memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
     114          12 :     LWLockRelease(&stats_shmem->lock);
     115             : 
     116             :     /* compensate by reset offsets */
     117             : #define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
     118          12 :     FIXED_COMP(numattach);
     119          12 :     FIXED_COMP(numdetach);
     120          12 :     FIXED_COMP(numrun);
     121          12 :     FIXED_COMP(numcached);
     122          12 :     FIXED_COMP(numloaded);
     123             : #undef FIXED_COMP
     124          12 : }
     125             : 
     126             : /*
     127             :  * Workhorse to do the registration work, called in _PG_init().
     128             :  */
     129             : void
     130          10 : pgstat_register_inj_fixed(void)
     131             : {
     132          10 :     pgstat_register_kind(PGSTAT_KIND_INJECTION_FIXED, &injection_stats_fixed);
     133             : 
     134             :     /* mark stats as loaded */
     135          10 :     inj_fixed_loaded = true;
     136          10 : }
     137             : 
     138             : /*
     139             :  * Report fixed number of statistics for an injection point.
     140             :  */
     141             : void
     142         284 : pgstat_report_inj_fixed(uint32 numattach,
     143             :                         uint32 numdetach,
     144             :                         uint32 numrun,
     145             :                         uint32 numcached,
     146             :                         uint32 numloaded)
     147             : {
     148             :     PgStatShared_InjectionPointFixed *stats_shmem;
     149             : 
     150             :     /* leave if disabled */
     151         284 :     if (!inj_fixed_loaded || !inj_stats_enabled)
     152         268 :         return;
     153             : 
     154          16 :     stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
     155             : 
     156          16 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
     157             : 
     158          16 :     pgstat_begin_changecount_write(&stats_shmem->changecount);
     159          16 :     stats_shmem->stats.numattach += numattach;
     160          16 :     stats_shmem->stats.numdetach += numdetach;
     161          16 :     stats_shmem->stats.numrun += numrun;
     162          16 :     stats_shmem->stats.numcached += numcached;
     163          16 :     stats_shmem->stats.numloaded += numloaded;
     164          16 :     pgstat_end_changecount_write(&stats_shmem->changecount);
     165             : 
     166          16 :     LWLockRelease(&stats_shmem->lock);
     167             : }
     168             : 
     169             : /*
     170             :  * SQL function returning fixed-numbered statistics for injection points.
     171             :  */
     172          70 : PG_FUNCTION_INFO_V1(injection_points_stats_fixed);
     173             : Datum
     174           6 : injection_points_stats_fixed(PG_FUNCTION_ARGS)
     175             : {
     176             :     TupleDesc   tupdesc;
     177           6 :     Datum       values[5] = {0};
     178           6 :     bool        nulls[5] = {0};
     179             :     PgStat_StatInjFixedEntry *stats;
     180             : 
     181           6 :     if (!inj_fixed_loaded || !inj_stats_enabled)
     182           0 :         PG_RETURN_NULL();
     183             : 
     184           6 :     pgstat_snapshot_fixed(PGSTAT_KIND_INJECTION_FIXED);
     185           6 :     stats = pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
     186             : 
     187             :     /* Initialise attributes information in the tuple descriptor */
     188           6 :     tupdesc = CreateTemplateTupleDesc(5);
     189           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
     190             :                        INT8OID, -1, 0);
     191           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
     192             :                        INT8OID, -1, 0);
     193           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
     194             :                        INT8OID, -1, 0);
     195           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 4, "numcached",
     196             :                        INT8OID, -1, 0);
     197           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 5, "numloaded",
     198             :                        INT8OID, -1, 0);
     199           6 :     BlessTupleDesc(tupdesc);
     200             : 
     201           6 :     values[0] = Int64GetDatum(stats->numattach);
     202           6 :     values[1] = Int64GetDatum(stats->numdetach);
     203           6 :     values[2] = Int64GetDatum(stats->numrun);
     204           6 :     values[3] = Int64GetDatum(stats->numcached);
     205           6 :     values[4] = Int64GetDatum(stats->numloaded);
     206           6 :     nulls[0] = false;
     207           6 :     nulls[1] = false;
     208           6 :     nulls[2] = false;
     209           6 :     nulls[3] = false;
     210           6 :     nulls[4] = false;
     211             : 
     212             :     /* Returns the record as Datum */
     213           6 :     PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
     214             : }

Generated by: LCOV version 1.16