LCOV - code coverage report
Current view: top level - src/test/modules/test_dsa - test_dsa.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 38 39 97.4 %
Date: 2025-12-02 13:18:37 Functions: 6 6 100.0 %
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-2025, 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           2 : PG_MODULE_MAGIC;
      22             : 
      23             : static void
      24           2 : init_tranche(void *ptr)
      25             : {
      26           2 :     int        *tranche_id = (int *) ptr;
      27             : 
      28           2 :     *tranche_id = LWLockNewTrancheId("test_dsa");
      29           2 : }
      30             : 
      31             : /* Test basic DSA functionality */
      32           4 : PG_FUNCTION_INFO_V1(test_dsa_basic);
      33             : Datum
      34           2 : 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           2 :     tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
      42             :                                     init_tranche, &found);
      43             : 
      44           2 :     a = dsa_create(*tranche_id);
      45         202 :     for (int i = 0; i < 100; i++)
      46             :     {
      47         200 :         p[i] = dsa_allocate(a, 1000);
      48         200 :         snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
      49             :     }
      50             : 
      51         202 :     for (int i = 0; i < 100; i++)
      52             :     {
      53             :         char        buf[100];
      54             : 
      55         200 :         snprintf(buf, 100, "foobar%d", i);
      56         200 :         if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
      57           0 :             elog(ERROR, "no match");
      58             :     }
      59             : 
      60         202 :     for (int i = 0; i < 100; i++)
      61             :     {
      62         200 :         dsa_free(a, p[i]);
      63             :     }
      64             : 
      65           2 :     dsa_detach(a);
      66             : 
      67           2 :     PG_RETURN_VOID();
      68             : }
      69             : 
      70             : /* Test using DSA across different resource owners */
      71           4 : PG_FUNCTION_INFO_V1(test_dsa_resowners);
      72             : Datum
      73           2 : 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           2 :     tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
      83             :                                     init_tranche, &found);
      84             : 
      85             :     /* Create DSA in parent resource owner */
      86           2 :     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           2 :     oldowner = CurrentResourceOwner;
      93           2 :     childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
      94           2 :     CurrentResourceOwner = childowner;
      95             : 
      96       20002 :     for (int i = 0; i < 10000; i++)
      97             :     {
      98       20000 :         p[i] = dsa_allocate(a, 1000);
      99       20000 :         snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
     100             :     }
     101             : 
     102             :     /* Also test freeing, by freeing some of the allocations. */
     103        1002 :     for (int i = 0; i < 500; i++)
     104        1000 :         dsa_free(a, p[i]);
     105             : 
     106             :     /* Release the child resource owner */
     107           2 :     CurrentResourceOwner = oldowner;
     108           2 :     ResourceOwnerRelease(childowner,
     109             :                          RESOURCE_RELEASE_BEFORE_LOCKS,
     110             :                          true, false);
     111           2 :     ResourceOwnerRelease(childowner,
     112             :                          RESOURCE_RELEASE_LOCKS,
     113             :                          true, false);
     114           2 :     ResourceOwnerRelease(childowner,
     115             :                          RESOURCE_RELEASE_AFTER_LOCKS,
     116             :                          true, false);
     117           2 :     ResourceOwnerDelete(childowner);
     118             : 
     119           2 :     dsa_detach(a);
     120             : 
     121           2 :     PG_RETURN_VOID();
     122             : }

Generated by: LCOV version 1.16