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

Generated by: LCOV version 1.14