LCOV - differential code coverage report
Current view: top level - src/backend/storage/aio - aio_funcs.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 20.8 % 72 15 57 15
Current Date: 2025-09-06 07:49:51 +0900 Functions: 50.0 % 2 1 1 1
Baseline: lcov-20250906-005545-baseline Branches: 12.5 % 24 3 21 3
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 33.3 % 3 1 2 1
(30,360] days: 20.3 % 69 14 55 14
Function coverage date bins:
(30,360] days: 50.0 % 2 1 1 1
Branch coverage date bins:
(7,30] days: 0.0 % 4 0 4
(30,360] days: 15.0 % 20 3 17 3

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * aio_funcs.c
                                  4                 :                :  *    AIO - SQL interface for AIO
                                  5                 :                :  *
                                  6                 :                :  *
                                  7                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/storage/aio/aio_funcs.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : 
                                 16                 :                : #include "postgres.h"
                                 17                 :                : 
                                 18                 :                : #include "fmgr.h"
                                 19                 :                : #include "funcapi.h"
                                 20                 :                : #include "nodes/execnodes.h"
                                 21                 :                : #include "port/atomics.h"
                                 22                 :                : #include "storage/aio_internal.h"
                                 23                 :                : #include "storage/lock.h"
                                 24                 :                : #include "storage/proc.h"
                                 25                 :                : #include "storage/procnumber.h"
                                 26                 :                : #include "utils/builtins.h"
                                 27                 :                : #include "utils/fmgrprotos.h"
                                 28                 :                : #include "utils/tuplestore.h"
                                 29                 :                : 
                                 30                 :                : 
                                 31                 :                : /*
                                 32                 :                :  * Byte length of an iovec.
                                 33                 :                :  */
                                 34                 :                : static size_t
  158 andres@anarazel.de         35                 :UBC           0 : iov_byte_length(const struct iovec *iov, int cnt)
                                 36                 :                : {
                                 37                 :              0 :     size_t      len = 0;
                                 38                 :                : 
                                 39         [ #  # ]:              0 :     for (int i = 0; i < cnt; i++)
                                 40                 :                :     {
                                 41                 :              0 :         len += iov[i].iov_len;
                                 42                 :                :     }
                                 43                 :                : 
                                 44                 :              0 :     return len;
                                 45                 :                : }
                                 46                 :                : 
                                 47                 :                : Datum
  158 andres@anarazel.de         48                 :CBC           3 : pg_get_aios(PG_FUNCTION_ARGS)
                                 49                 :                : {
                                 50                 :              3 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
                                 51                 :                : 
                                 52                 :              3 :     InitMaterializedSRF(fcinfo, 0);
                                 53                 :                : 
                                 54                 :                : #define PG_GET_AIOS_COLS    15
                                 55                 :                : 
                                 56         [ +  + ]:          21721 :     for (uint64 i = 0; i < pgaio_ctl->io_handle_count; i++)
                                 57                 :                :     {
                                 58                 :          21718 :         PgAioHandle *live_ioh = &pgaio_ctl->io_handles[i];
   16 peter@eisentraut.org       59                 :          21718 :         int         ioh_id = pgaio_io_get_id(live_ioh);
  158 andres@anarazel.de         60                 :          21718 :         Datum       values[PG_GET_AIOS_COLS] = {0};
                                 61                 :          21718 :         bool        nulls[PG_GET_AIOS_COLS] = {0};
                                 62                 :                :         ProcNumber  owner;
                                 63                 :                :         PGPROC     *owner_proc;
                                 64                 :                :         int32       owner_pid;
                                 65                 :                :         PgAioHandleState start_state;
                                 66                 :                :         uint64      start_generation;
                                 67                 :                :         PgAioHandle ioh_copy;
                                 68                 :                :         struct iovec iov_copy[PG_IOV_MAX];
                                 69                 :                : 
                                 70                 :                : 
                                 71                 :                :         /*
                                 72                 :                :          * There is no lock that could prevent the state of the IO to advance
                                 73                 :                :          * concurrently - and we don't want to introduce one, as that would
                                 74                 :                :          * introduce atomics into a very common path. Instead we
                                 75                 :                :          *
                                 76                 :                :          * 1) Determine the state + generation of the IO.
                                 77                 :                :          *
                                 78                 :                :          * 2) Copy the IO to local memory.
                                 79                 :                :          *
                                 80                 :                :          * 3) Check if state or generation of the IO changed. If the state
                                 81                 :                :          * changed, retry, if the generation changed don't display the IO.
                                 82                 :                :          */
                                 83                 :                : 
                                 84                 :                :         /* 1) from above */
                                 85                 :          21718 :         start_generation = live_ioh->generation;
                                 86                 :                : 
                                 87                 :                :         /*
                                 88                 :                :          * Retry at this point, so we can accept changing states, but not
                                 89                 :                :          * changing generations.
                                 90                 :                :          */
                                 91                 :          21718 : retry:
                                 92                 :          21718 :         pg_read_barrier();
                                 93                 :          21718 :         start_state = live_ioh->state;
                                 94                 :                : 
                                 95         [ +  - ]:          21718 :         if (start_state == PGAIO_HS_IDLE)
                                 96                 :          21718 :             continue;
                                 97                 :                : 
                                 98                 :                :         /* 2) from above */
  158 andres@anarazel.de         99                 :UBC           0 :         memcpy(&ioh_copy, live_ioh, sizeof(PgAioHandle));
                                100                 :                : 
                                101                 :                :         /*
                                102                 :                :          * Safe to copy even if no iovec is used - we always reserve the
                                103                 :                :          * required space.
                                104                 :                :          */
                                105                 :              0 :         memcpy(&iov_copy, &pgaio_ctl->iovecs[ioh_copy.iovec_off],
                                106                 :                :                PG_IOV_MAX * sizeof(struct iovec));
                                107                 :                : 
                                108                 :                :         /*
                                109                 :                :          * Copy information about owner before 3) below, if the process exited
                                110                 :                :          * it'd have to wait for the IO to finish first, which we would detect
                                111                 :                :          * in 3).
                                112                 :                :          */
                                113                 :              0 :         owner = ioh_copy.owner_procno;
                                114                 :              0 :         owner_proc = GetPGProcByNumber(owner);
                                115                 :              0 :         owner_pid = owner_proc->pid;
                                116                 :                : 
                                117                 :                :         /* 3) from above */
                                118                 :              0 :         pg_read_barrier();
                                119                 :                : 
                                120                 :                :         /*
                                121                 :                :          * The IO completed and a new one was started with the same ID. Don't
                                122                 :                :          * display it - it really started after this function was called.
                                123                 :                :          * There be a risk of a livelock if we just retried endlessly, if IOs
                                124                 :                :          * complete very quickly.
                                125                 :                :          */
                                126         [ #  # ]:              0 :         if (live_ioh->generation != start_generation)
                                127                 :              0 :             continue;
                                128                 :                : 
                                129                 :                :         /*
                                130                 :                :          * The IO's state changed while we were "rendering" it. Just start
                                131                 :                :          * from scratch. There's no risk of a livelock here, as an IO has a
                                132                 :                :          * limited sets of states it can be in, and state changes go only in a
                                133                 :                :          * single direction.
                                134                 :                :          */
                                135         [ #  # ]:              0 :         if (live_ioh->state != start_state)
                                136                 :              0 :             goto retry;
                                137                 :                : 
                                138                 :                :         /*
                                139                 :                :          * Now that we have copied the IO into local memory and checked that
                                140                 :                :          * it's still in the same state, we are not allowed to access "live"
                                141                 :                :          * memory anymore. To make it slightly easier to catch such cases, set
                                142                 :                :          * the "live" pointers to NULL.
                                143                 :                :          */
                                144                 :              0 :         live_ioh = NULL;
                                145                 :              0 :         owner_proc = NULL;
                                146                 :                : 
                                147                 :                : 
                                148                 :                :         /* column: owning pid */
                                149         [ #  # ]:              0 :         if (owner_pid != 0)
                                150                 :              0 :             values[0] = Int32GetDatum(owner_pid);
                                151                 :                :         else
                                152                 :              0 :             nulls[0] = false;
                                153                 :                : 
                                154                 :                :         /* column: IO's id */
   16 peter@eisentraut.org      155                 :              0 :         values[1] = Int32GetDatum(ioh_id);
                                156                 :                : 
                                157                 :                :         /* column: IO's generation */
  158 andres@anarazel.de        158                 :              0 :         values[2] = Int64GetDatum(start_generation);
                                159                 :                : 
                                160                 :                :         /* column: IO's state */
                                161                 :              0 :         values[3] = CStringGetTextDatum(pgaio_io_get_state_name(&ioh_copy));
                                162                 :                : 
                                163                 :                :         /*
                                164                 :                :          * If the IO is in PGAIO_HS_HANDED_OUT state, none of the following
                                165                 :                :          * fields are valid yet (or are in the process of being set).
                                166                 :                :          * Therefore we don't want to display any other columns.
                                167                 :                :          */
                                168         [ #  # ]:              0 :         if (start_state == PGAIO_HS_HANDED_OUT)
                                169                 :                :         {
                                170                 :              0 :             memset(nulls + 4, 1, (lengthof(nulls) - 4) * sizeof(bool));
                                171                 :              0 :             goto display;
                                172                 :                :         }
                                173                 :                : 
                                174                 :                :         /* column: IO's operation */
                                175                 :              0 :         values[4] = CStringGetTextDatum(pgaio_io_get_op_name(&ioh_copy));
                                176                 :                : 
                                177                 :                :         /* columns: details about the IO's operation (offset, length) */
   10                           178   [ #  #  #  # ]:              0 :         switch ((PgAioOp) ioh_copy.op)
                                179                 :                :         {
  158                           180                 :              0 :             case PGAIO_OP_INVALID:
                                181                 :              0 :                 nulls[5] = true;
                                182                 :              0 :                 nulls[6] = true;
                                183                 :              0 :                 break;
                                184                 :              0 :             case PGAIO_OP_READV:
                                185                 :              0 :                 values[5] = Int64GetDatum(ioh_copy.op_data.read.offset);
                                186                 :              0 :                 values[6] =
                                187                 :              0 :                     Int64GetDatum(iov_byte_length(iov_copy, ioh_copy.op_data.read.iov_length));
                                188                 :              0 :                 break;
                                189                 :              0 :             case PGAIO_OP_WRITEV:
                                190                 :              0 :                 values[5] = Int64GetDatum(ioh_copy.op_data.write.offset);
                                191                 :              0 :                 values[6] =
                                192                 :              0 :                     Int64GetDatum(iov_byte_length(iov_copy, ioh_copy.op_data.write.iov_length));
                                193                 :              0 :                 break;
                                194                 :                :         }
                                195                 :                : 
                                196                 :                :         /* column: IO's target */
                                197                 :              0 :         values[7] = CStringGetTextDatum(pgaio_io_get_target_name(&ioh_copy));
                                198                 :                : 
                                199                 :                :         /* column: length of IO's data array */
                                200                 :              0 :         values[8] = Int16GetDatum(ioh_copy.handle_data_len);
                                201                 :                : 
                                202                 :                :         /* column: raw result (i.e. some form of syscall return value) */
                                203         [ #  # ]:              0 :         if (start_state == PGAIO_HS_COMPLETED_IO
                                204         [ #  # ]:              0 :             || start_state == PGAIO_HS_COMPLETED_SHARED
                                205         [ #  # ]:              0 :             || start_state == PGAIO_HS_COMPLETED_LOCAL)
                                206                 :              0 :             values[9] = Int32GetDatum(ioh_copy.result);
                                207                 :                :         else
                                208                 :              0 :             nulls[9] = true;
                                209                 :                : 
                                210                 :                :         /*
                                211                 :                :          * column: result in the higher level representation (unknown if not
                                212                 :                :          * finished)
                                213                 :                :          */
                                214                 :              0 :         values[10] =
                                215                 :              0 :             CStringGetTextDatum(pgaio_result_status_string(ioh_copy.distilled_result.status));
                                216                 :                : 
                                217                 :                :         /* column: target description */
                                218                 :              0 :         values[11] = CStringGetTextDatum(pgaio_io_get_target_description(&ioh_copy));
                                219                 :                : 
                                220                 :                :         /* columns: one for each flag */
                                221                 :              0 :         values[12] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_SYNCHRONOUS);
                                222                 :              0 :         values[13] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_REFERENCES_LOCAL);
                                223                 :              0 :         values[14] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_BUFFERED);
                                224                 :                : 
                                225                 :              0 : display:
                                226                 :              0 :         tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
                                227                 :                :     }
                                228                 :                : 
  158 andres@anarazel.de        229                 :CBC           3 :     return (Datum) 0;
                                230                 :                : }
        

Generated by: LCOV version 2.4-beta