/
githubmirror
/
postgres
Обзор
Документация
Войти
/
githubmirror
/
postgres
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/test/modules/test_dsa/test_dsa.c
162 строки
4 KB
Michael Paquier
Fix size underestimation of DSA pagemap for odd-sized segments
09 мар 2026, 07:46
09 мар 2026, 07:46
4da2afd
Код
Авторство
О чём код?
/*-------------------------------------------------------------------------- * * test_dsa.c * Test dynamic shared memory areas (DSAs) * * Copyright (c) 2022-2026, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_dsa/test_dsa.c * * ------------------------------------------------------------------------- */ #include "postgres.h" #include "fmgr.h" #include "storage/dsm_registry.h" #include "storage/lwlock.h" #include "utils/dsa.h" #include "utils/freepage.h" #include "utils/resowner.h" PG_MODULE_MAGIC; static void init_tranche(void *ptr, void *arg) { int *tranche_id = (int *) ptr; *tranche_id = LWLockNewTrancheId("test_dsa"); } /* Test basic DSA functionality */ PG_FUNCTION_INFO_V1(test_dsa_basic); Datum test_dsa_basic(PG_FUNCTION_ARGS) { int *tranche_id; bool found; dsa_area *a; dsa_pointer p[100]; tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int), init_tranche, &found, NULL); a = dsa_create(*tranche_id); for (int i = 0; i < 100; i++) { p[i] = dsa_allocate(a, 1000); snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i); } for (int i = 0; i < 100; i++) { char buf[100]; snprintf(buf, 100, "foobar%d", i); if (strcmp(dsa_get_address(a, p[i]), buf) != 0) elog(ERROR, "no match"); } for (int i = 0; i < 100; i++) { dsa_free(a, p[i]); } dsa_detach(a); PG_RETURN_VOID(); } /* Test using DSA across different resource owners */ PG_FUNCTION_INFO_V1(test_dsa_resowners); Datum test_dsa_resowners(PG_FUNCTION_ARGS) { int *tranche_id; bool found; dsa_area *a; dsa_pointer p[10000]; ResourceOwner oldowner; ResourceOwner childowner; tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int), init_tranche, &found, NULL); /* Create DSA in parent resource owner */ a = dsa_create(*tranche_id); /* * Switch to child resource owner, and do a bunch of allocations in the * DSA */ oldowner = CurrentResourceOwner; childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner"); CurrentResourceOwner = childowner; for (int i = 0; i < 10000; i++) { p[i] = dsa_allocate(a, 1000); snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i); } /* Also test freeing, by freeing some of the allocations. */ for (int i = 0; i < 500; i++) dsa_free(a, p[i]); /* Release the child resource owner */ CurrentResourceOwner = oldowner; ResourceOwnerRelease(childowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false); ResourceOwnerRelease(childowner, RESOURCE_RELEASE_LOCKS, true, false); ResourceOwnerRelease(childowner, RESOURCE_RELEASE_AFTER_LOCKS, true, false); ResourceOwnerDelete(childowner); dsa_detach(a); PG_RETURN_VOID(); } /* * test_dsa_allocate * * Test DSA allocation across a range of sizes to exercise the pagemap * sizing logic in make_new_segment(). A fresh DSA is created for each * iteration so that each allocation triggers a new segment creation, * including the odd-sized segment path. */ PG_FUNCTION_INFO_V1(test_dsa_allocate); Datum test_dsa_allocate(PG_FUNCTION_ARGS) { int start_num_pages = PG_GETARG_INT32(0); int end_num_pages = PG_GETARG_INT32(1); int step = PG_GETARG_INT32(2); size_t usable_pages; int *tranche_id; bool found; dsa_area *a; dsa_pointer dp; if (start_num_pages > end_num_pages) elog(ERROR, "incorrect start and end parameters"); tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int), init_tranche, &found, NULL); for (usable_pages = start_num_pages; usable_pages < end_num_pages; usable_pages += step) { a = dsa_create(*tranche_id); dp = dsa_allocate(a, usable_pages * FPM_PAGE_SIZE); dsa_free(a, dp); dsa_detach(a); } PG_RETURN_VOID(); }