LCOV - code coverage report
Current view: top level - src/test/modules/test_dsa - test_dsa.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 97.4 % 39 38
Test Date: 2026-03-03 14:15:12 Functions: 100.0 % 6 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*--------------------------------------------------------------------------
       2              :  *
       3              :  * test_dsa.c
       4              :  *      Test dynamic shared memory areas (DSAs)
       5              :  *
       6              :  * Copyright (c) 2022-2026, PostgreSQL Global Development Group
       7              :  *
       8              :  * IDENTIFICATION
       9              :  *      src/test/modules/test_dsa/test_dsa.c
      10              :  *
      11              :  * -------------------------------------------------------------------------
      12              :  */
      13              : #include "postgres.h"
      14              : 
      15              : #include "fmgr.h"
      16              : #include "storage/dsm_registry.h"
      17              : #include "storage/lwlock.h"
      18              : #include "utils/dsa.h"
      19              : #include "utils/resowner.h"
      20              : 
      21            1 : PG_MODULE_MAGIC;
      22              : 
      23              : static void
      24            1 : init_tranche(void *ptr, void *arg)
      25              : {
      26            1 :     int        *tranche_id = (int *) ptr;
      27              : 
      28            1 :     *tranche_id = LWLockNewTrancheId("test_dsa");
      29            1 : }
      30              : 
      31              : /* Test basic DSA functionality */
      32            2 : PG_FUNCTION_INFO_V1(test_dsa_basic);
      33              : Datum
      34            1 : test_dsa_basic(PG_FUNCTION_ARGS)
      35              : {
      36              :     int        *tranche_id;
      37              :     bool        found;
      38              :     dsa_area   *a;
      39              :     dsa_pointer p[100];
      40              : 
      41            1 :     tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
      42              :                                     init_tranche, &found, NULL);
      43              : 
      44            1 :     a = dsa_create(*tranche_id);
      45          101 :     for (int i = 0; i < 100; i++)
      46              :     {
      47          100 :         p[i] = dsa_allocate(a, 1000);
      48          100 :         snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
      49              :     }
      50              : 
      51          101 :     for (int i = 0; i < 100; i++)
      52              :     {
      53              :         char        buf[100];
      54              : 
      55          100 :         snprintf(buf, 100, "foobar%d", i);
      56          100 :         if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
      57            0 :             elog(ERROR, "no match");
      58              :     }
      59              : 
      60          101 :     for (int i = 0; i < 100; i++)
      61              :     {
      62          100 :         dsa_free(a, p[i]);
      63              :     }
      64              : 
      65            1 :     dsa_detach(a);
      66              : 
      67            1 :     PG_RETURN_VOID();
      68              : }
      69              : 
      70              : /* Test using DSA across different resource owners */
      71            2 : PG_FUNCTION_INFO_V1(test_dsa_resowners);
      72              : Datum
      73            1 : test_dsa_resowners(PG_FUNCTION_ARGS)
      74              : {
      75              :     int        *tranche_id;
      76              :     bool        found;
      77              :     dsa_area   *a;
      78              :     dsa_pointer p[10000];
      79              :     ResourceOwner oldowner;
      80              :     ResourceOwner childowner;
      81              : 
      82            1 :     tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
      83              :                                     init_tranche, &found, NULL);
      84              : 
      85              :     /* Create DSA in parent resource owner */
      86            1 :     a = dsa_create(*tranche_id);
      87              : 
      88              :     /*
      89              :      * Switch to child resource owner, and do a bunch of allocations in the
      90              :      * DSA
      91              :      */
      92            1 :     oldowner = CurrentResourceOwner;
      93            1 :     childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
      94            1 :     CurrentResourceOwner = childowner;
      95              : 
      96        10001 :     for (int i = 0; i < 10000; i++)
      97              :     {
      98        10000 :         p[i] = dsa_allocate(a, 1000);
      99        10000 :         snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
     100              :     }
     101              : 
     102              :     /* Also test freeing, by freeing some of the allocations. */
     103          501 :     for (int i = 0; i < 500; i++)
     104          500 :         dsa_free(a, p[i]);
     105              : 
     106              :     /* Release the child resource owner */
     107            1 :     CurrentResourceOwner = oldowner;
     108            1 :     ResourceOwnerRelease(childowner,
     109              :                          RESOURCE_RELEASE_BEFORE_LOCKS,
     110              :                          true, false);
     111            1 :     ResourceOwnerRelease(childowner,
     112              :                          RESOURCE_RELEASE_LOCKS,
     113              :                          true, false);
     114            1 :     ResourceOwnerRelease(childowner,
     115              :                          RESOURCE_RELEASE_AFTER_LOCKS,
     116              :                          true, false);
     117            1 :     ResourceOwnerDelete(childowner);
     118              : 
     119            1 :     dsa_detach(a);
     120              : 
     121            1 :     PG_RETURN_VOID();
     122              : }
        

Generated by: LCOV version 2.0-1