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: 2024-11-21 08:14:44 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-2024, 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             : 
      54             :     .shared_size = sizeof(PgStat_StatInjFixedEntry),
      55             :     .shared_data_off = offsetof(PgStatShared_InjectionPointFixed, stats),
      56             :     .shared_data_len = sizeof(((PgStatShared_InjectionPointFixed *) 0)->stats),
      57             : 
      58             :     .init_shmem_cb = injection_stats_fixed_init_shmem_cb,
      59             :     .reset_all_cb = injection_stats_fixed_reset_all_cb,
      60             :     .snapshot_cb = injection_stats_fixed_snapshot_cb,
      61             : };
      62             : 
      63             : /*
      64             :  * Kind ID reserved for statistics of injection points.
      65             :  */
      66             : #define PGSTAT_KIND_INJECTION_FIXED 130
      67             : 
      68             : /* Track if fixed-numbered stats are loaded */
      69             : static bool inj_fixed_loaded = false;
      70             : 
      71             : static void
      72           8 : injection_stats_fixed_init_shmem_cb(void *stats)
      73             : {
      74           8 :     PgStatShared_InjectionPointFixed *stats_shmem =
      75             :         (PgStatShared_InjectionPointFixed *) stats;
      76             : 
      77           8 :     LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
      78           8 : }
      79             : 
      80             : static void
      81           2 : injection_stats_fixed_reset_all_cb(TimestampTz ts)
      82             : {
      83             :     PgStatShared_InjectionPointFixed *stats_shmem =
      84           2 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
      85             : 
      86           2 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
      87           2 :     pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
      88           2 :                                     &stats_shmem->stats,
      89             :                                     sizeof(stats_shmem->stats),
      90             :                                     &stats_shmem->changecount);
      91           2 :     stats_shmem->stats.stat_reset_timestamp = ts;
      92           2 :     LWLockRelease(&stats_shmem->lock);
      93           2 : }
      94             : 
      95             : static void
      96          12 : injection_stats_fixed_snapshot_cb(void)
      97             : {
      98             :     PgStatShared_InjectionPointFixed *stats_shmem =
      99          12 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
     100             :     PgStat_StatInjFixedEntry *stat_snap =
     101          12 :         pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
     102          12 :     PgStat_StatInjFixedEntry *reset_offset = &stats_shmem->reset_offset;
     103             :     PgStat_StatInjFixedEntry reset;
     104             : 
     105          12 :     pgstat_copy_changecounted_stats(stat_snap,
     106          12 :                                     &stats_shmem->stats,
     107             :                                     sizeof(stats_shmem->stats),
     108             :                                     &stats_shmem->changecount);
     109             : 
     110          12 :     LWLockAcquire(&stats_shmem->lock, LW_SHARED);
     111          12 :     memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
     112          12 :     LWLockRelease(&stats_shmem->lock);
     113             : 
     114             :     /* compensate by reset offsets */
     115             : #define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
     116          12 :     FIXED_COMP(numattach);
     117          12 :     FIXED_COMP(numdetach);
     118          12 :     FIXED_COMP(numrun);
     119          12 :     FIXED_COMP(numcached);
     120          12 :     FIXED_COMP(numloaded);
     121             : #undef FIXED_COMP
     122          12 : }
     123             : 
     124             : /*
     125             :  * Workhorse to do the registration work, called in _PG_init().
     126             :  */
     127             : void
     128           8 : pgstat_register_inj_fixed(void)
     129             : {
     130           8 :     pgstat_register_kind(PGSTAT_KIND_INJECTION_FIXED, &injection_stats_fixed);
     131             : 
     132             :     /* mark stats as loaded */
     133           8 :     inj_fixed_loaded = true;
     134           8 : }
     135             : 
     136             : /*
     137             :  * Report fixed number of statistics for an injection point.
     138             :  */
     139             : void
     140         178 : pgstat_report_inj_fixed(uint32 numattach,
     141             :                         uint32 numdetach,
     142             :                         uint32 numrun,
     143             :                         uint32 numcached,
     144             :                         uint32 numloaded)
     145             : {
     146             :     PgStatShared_InjectionPointFixed *stats_shmem;
     147             : 
     148             :     /* leave if disabled */
     149         178 :     if (!inj_fixed_loaded || !inj_stats_enabled)
     150         168 :         return;
     151             : 
     152          10 :     stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
     153             : 
     154          10 :     pgstat_begin_changecount_write(&stats_shmem->changecount);
     155          10 :     stats_shmem->stats.numattach += numattach;
     156          10 :     stats_shmem->stats.numdetach += numdetach;
     157          10 :     stats_shmem->stats.numrun += numrun;
     158          10 :     stats_shmem->stats.numcached += numcached;
     159          10 :     stats_shmem->stats.numloaded += numloaded;
     160          10 :     pgstat_end_changecount_write(&stats_shmem->changecount);
     161             : }
     162             : 
     163             : /*
     164             :  * SQL function returning fixed-numbered statistics for injection points.
     165             :  */
     166          44 : PG_FUNCTION_INFO_V1(injection_points_stats_fixed);
     167             : Datum
     168           6 : injection_points_stats_fixed(PG_FUNCTION_ARGS)
     169             : {
     170             :     TupleDesc   tupdesc;
     171           6 :     Datum       values[5] = {0};
     172           6 :     bool        nulls[5] = {0};
     173             :     PgStat_StatInjFixedEntry *stats;
     174             : 
     175           6 :     if (!inj_fixed_loaded || !inj_stats_enabled)
     176           0 :         PG_RETURN_NULL();
     177             : 
     178           6 :     pgstat_snapshot_fixed(PGSTAT_KIND_INJECTION_FIXED);
     179           6 :     stats = pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
     180             : 
     181             :     /* Initialise attributes information in the tuple descriptor */
     182           6 :     tupdesc = CreateTemplateTupleDesc(5);
     183           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
     184             :                        INT8OID, -1, 0);
     185           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
     186             :                        INT8OID, -1, 0);
     187           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
     188             :                        INT8OID, -1, 0);
     189           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 4, "numcached",
     190             :                        INT8OID, -1, 0);
     191           6 :     TupleDescInitEntry(tupdesc, (AttrNumber) 5, "numloaded",
     192             :                        INT8OID, -1, 0);
     193           6 :     BlessTupleDesc(tupdesc);
     194             : 
     195           6 :     values[0] = Int64GetDatum(stats->numattach);
     196           6 :     values[1] = Int64GetDatum(stats->numdetach);
     197           6 :     values[2] = Int64GetDatum(stats->numrun);
     198           6 :     values[3] = Int64GetDatum(stats->numcached);
     199           6 :     values[4] = Int64GetDatum(stats->numloaded);
     200           6 :     nulls[0] = false;
     201           6 :     nulls[1] = false;
     202           6 :     nulls[2] = false;
     203           6 :     nulls[3] = false;
     204           6 :     nulls[4] = false;
     205             : 
     206             :     /* Returns the record as Datum */
     207           6 :     PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
     208             : }

Generated by: LCOV version 1.14