mirror of https://github.com/postgres/postgres
This covers basic calls within a single backend process, and also calling dsa_allocate() or dsa_get_address() while in a different resource owners. The latter case was fixed by the previous commit. Discussion: https://www.postgresql.org/message-id/11b70743-c5f3-3910-8e5b-dd6c115ff829%40gmail.compull/146/head
parent
a8b330ffb6
commit
325f54033e
@ -0,0 +1,23 @@ |
|||||||
|
# src/test/modules/test_dsa/Makefile
|
||||||
|
|
||||||
|
MODULE_big = test_dsa
|
||||||
|
OBJS = \
|
||||||
|
$(WIN32RES) \
|
||||||
|
test_dsa.o
|
||||||
|
PGFILEDESC = "test_dsa - test code for dynamic shared memory areas"
|
||||||
|
|
||||||
|
EXTENSION = test_dsa
|
||||||
|
DATA = test_dsa--1.0.sql
|
||||||
|
|
||||||
|
REGRESS = test_dsa
|
||||||
|
|
||||||
|
ifdef USE_PGXS |
||||||
|
PG_CONFIG = pg_config
|
||||||
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
|
include $(PGXS) |
||||||
|
else |
||||||
|
subdir = src/test/modules/test_dsa
|
||||||
|
top_builddir = ../../../..
|
||||||
|
include $(top_builddir)/src/Makefile.global |
||||||
|
include $(top_srcdir)/contrib/contrib-global.mk |
||||||
|
endif |
@ -0,0 +1,13 @@ |
|||||||
|
CREATE EXTENSION test_dsa; |
||||||
|
SELECT test_dsa_basic(); |
||||||
|
test_dsa_basic |
||||||
|
---------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT test_dsa_resowners(); |
||||||
|
test_dsa_resowners |
||||||
|
-------------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
@ -0,0 +1,33 @@ |
|||||||
|
# Copyright (c) 2022-2023, PostgreSQL Global Development Group |
||||||
|
|
||||||
|
test_dsa_sources = files( |
||||||
|
'test_dsa.c', |
||||||
|
) |
||||||
|
|
||||||
|
if host_system == 'windows' |
||||||
|
test_dsa_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ |
||||||
|
'--NAME', 'test_dsa', |
||||||
|
'--FILEDESC', 'test_dsa - test code for dynamic shared memory areas',]) |
||||||
|
endif |
||||||
|
|
||||||
|
test_dsa = shared_module('test_dsa', |
||||||
|
test_dsa_sources, |
||||||
|
kwargs: pg_test_mod_args, |
||||||
|
) |
||||||
|
test_install_libs += test_dsa |
||||||
|
|
||||||
|
test_install_data += files( |
||||||
|
'test_dsa.control', |
||||||
|
'test_dsa--1.0.sql', |
||||||
|
) |
||||||
|
|
||||||
|
tests += { |
||||||
|
'name': 'test_dsa', |
||||||
|
'sd': meson.current_source_dir(), |
||||||
|
'bd': meson.current_build_dir(), |
||||||
|
'regress': { |
||||||
|
'sql': [ |
||||||
|
'test_dsa', |
||||||
|
], |
||||||
|
}, |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
CREATE EXTENSION test_dsa; |
||||||
|
|
||||||
|
SELECT test_dsa_basic(); |
||||||
|
SELECT test_dsa_resowners(); |
@ -0,0 +1,12 @@ |
|||||||
|
/* src/test/modules/test_dsa/test_dsa--1.0.sql */ |
||||||
|
|
||||||
|
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
||||||
|
\echo Use "CREATE EXTENSION test_dsa" to load this file. \quit |
||||||
|
|
||||||
|
CREATE FUNCTION test_dsa_basic() |
||||||
|
RETURNS pg_catalog.void |
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C; |
||||||
|
|
||||||
|
CREATE FUNCTION test_dsa_resowners() |
||||||
|
RETURNS pg_catalog.void |
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C; |
@ -0,0 +1,113 @@ |
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* test_dsa.c |
||||||
|
* Test dynamic shared memory areas (DSAs) |
||||||
|
* |
||||||
|
* Copyright (c) 2022-2023, PostgreSQL Global Development Group |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* src/test/modules/test_dsa/test_dsa.c |
||||||
|
* |
||||||
|
* ------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#include "postgres.h" |
||||||
|
|
||||||
|
#include "fmgr.h" |
||||||
|
#include "utils/dsa.h" |
||||||
|
#include "storage/lwlock.h" |
||||||
|
#include "utils/resowner.h" |
||||||
|
|
||||||
|
PG_MODULE_MAGIC; |
||||||
|
|
||||||
|
/* Test basic DSA functionality */ |
||||||
|
PG_FUNCTION_INFO_V1(test_dsa_basic); |
||||||
|
Datum |
||||||
|
test_dsa_basic(PG_FUNCTION_ARGS) |
||||||
|
{ |
||||||
|
int tranche_id; |
||||||
|
dsa_area *a; |
||||||
|
dsa_pointer p[100]; |
||||||
|
|
||||||
|
/* XXX: this tranche is leaked */ |
||||||
|
tranche_id = LWLockNewTrancheId(); |
||||||
|
LWLockRegisterTranche(tranche_id, "test_dsa"); |
||||||
|
|
||||||
|
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; |
||||||
|
dsa_area *a; |
||||||
|
dsa_pointer p[10000]; |
||||||
|
ResourceOwner oldowner; |
||||||
|
ResourceOwner childowner; |
||||||
|
|
||||||
|
/* XXX: this tranche is leaked */ |
||||||
|
tranche_id = LWLockNewTrancheId(); |
||||||
|
LWLockRegisterTranche(tranche_id, "test_dsa"); |
||||||
|
|
||||||
|
/* 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(); |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
comment = 'Test code for dynamic shared memory areas' |
||||||
|
default_version = '1.0' |
||||||
|
module_pathname = '$libdir/test_dsa' |
||||||
|
relocatable = true |
Loading…
Reference in new issue