mirror of
https://github.com/postgres/postgres.git
synced 2026-04-20 22:00:13 -04:00
Use the new shmem allocation functions in a few core subsystems
These subsystems have some complicating properties, making them slightly harder to convert than most: - The initialization callbacks of some of these subsystems have dependencies, i.e. they need to be initialized in the right order. - The ProcGlobal pointer still needs to be inherited by the BackendParameters mechanism on EXEC_BACKEND builds, because ProcGlobal is required by InitProcess() to get a PGPROC entry, and the PGPROC entry is required to use LWLocks, and usually attaching to shared memory areas requires the use of LWLocks. - Similarly, ProcSignal pointer still needs to be handled by BackendParameters, because query cancellation connections access it without calling InitProcess Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com
This commit is contained in:
parent
a006bc7b16
commit
c6d55714ba
25 changed files with 345 additions and 382 deletions
|
|
@ -282,7 +282,7 @@ TwoPhaseShmemInit(void)
|
|||
gxacts[i].next = TwoPhaseState->freeGXacts;
|
||||
TwoPhaseState->freeGXacts = &gxacts[i];
|
||||
|
||||
/* associate it with a PGPROC assigned by InitProcGlobal */
|
||||
/* associate it with a PGPROC assigned by ProcGlobalShmemInit */
|
||||
gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "postmaster/autovacuum.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
|
@ -30,35 +31,25 @@
|
|||
/* Number of OIDs to prefetch (preallocate) per XLOG write */
|
||||
#define VAR_OID_PREFETCH 8192
|
||||
|
||||
static void VarsupShmemRequest(void *arg);
|
||||
|
||||
/* pointer to variables struct in shared memory */
|
||||
TransamVariablesData *TransamVariables = NULL;
|
||||
|
||||
const ShmemCallbacks VarsupShmemCallbacks = {
|
||||
.request_fn = VarsupShmemRequest,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialization of shared memory for TransamVariables.
|
||||
* Request shared memory for TransamVariables.
|
||||
*/
|
||||
Size
|
||||
VarsupShmemSize(void)
|
||||
static void
|
||||
VarsupShmemRequest(void *arg)
|
||||
{
|
||||
return sizeof(TransamVariablesData);
|
||||
}
|
||||
|
||||
void
|
||||
VarsupShmemInit(void)
|
||||
{
|
||||
bool found;
|
||||
|
||||
/* Initialize our shared state struct */
|
||||
TransamVariables = ShmemInitStruct("TransamVariables",
|
||||
sizeof(TransamVariablesData),
|
||||
&found);
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
Assert(!found);
|
||||
memset(TransamVariables, 0, sizeof(TransamVariablesData));
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
ShmemRequestStruct(.name = "TransamVariables",
|
||||
.size = sizeof(TransamVariablesData),
|
||||
.ptr = (void **) &TransamVariables,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -159,22 +159,24 @@ PosixSemaphoreKill(sem_t *sem)
|
|||
|
||||
|
||||
/*
|
||||
* Report amount of shared memory needed for semaphores
|
||||
* Request shared memory needed for semaphores
|
||||
*/
|
||||
Size
|
||||
PGSemaphoreShmemSize(int maxSemas)
|
||||
void
|
||||
PGSemaphoreShmemRequest(int maxSemas)
|
||||
{
|
||||
#ifdef USE_NAMED_POSIX_SEMAPHORES
|
||||
/* No shared memory needed in this case */
|
||||
return 0;
|
||||
#else
|
||||
/* Need a PGSemaphoreData per semaphore */
|
||||
return mul_size(maxSemas, sizeof(PGSemaphoreData));
|
||||
ShmemRequestStruct(.name = "Semaphores",
|
||||
.size = mul_size(maxSemas, sizeof(PGSemaphoreData)),
|
||||
.ptr = (void **) &sharedSemas,
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* PGReserveSemaphores --- initialize semaphore support
|
||||
* PGSemaphoreInit --- initialize semaphore support
|
||||
*
|
||||
* This is called during postmaster start or shared memory reinitialization.
|
||||
* It should do whatever is needed to be able to support up to maxSemas
|
||||
|
|
@ -193,10 +195,9 @@ PGSemaphoreShmemSize(int maxSemas)
|
|||
* we don't have to expose the counters to other processes.)
|
||||
*/
|
||||
void
|
||||
PGReserveSemaphores(int maxSemas)
|
||||
PGSemaphoreInit(int maxSemas)
|
||||
{
|
||||
struct stat statbuf;
|
||||
bool found;
|
||||
|
||||
/*
|
||||
* We use the data directory's inode number to seed the search for free
|
||||
|
|
@ -214,11 +215,6 @@ PGReserveSemaphores(int maxSemas)
|
|||
mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *));
|
||||
if (mySemPointers == NULL)
|
||||
elog(PANIC, "out of memory");
|
||||
#else
|
||||
|
||||
sharedSemas = (PGSemaphore)
|
||||
ShmemInitStruct("Semaphores", PGSemaphoreShmemSize(maxSemas), &found);
|
||||
Assert(!found);
|
||||
#endif
|
||||
|
||||
numSems = 0;
|
||||
|
|
|
|||
|
|
@ -301,16 +301,20 @@ IpcSemaphoreCreate(int numSems)
|
|||
|
||||
|
||||
/*
|
||||
* Report amount of shared memory needed for semaphores
|
||||
* Request shared memory needed for semaphores
|
||||
*/
|
||||
Size
|
||||
PGSemaphoreShmemSize(int maxSemas)
|
||||
void
|
||||
PGSemaphoreShmemRequest(int maxSemas)
|
||||
{
|
||||
return mul_size(maxSemas, sizeof(PGSemaphoreData));
|
||||
/* Need a PGSemaphoreData per semaphore */
|
||||
ShmemRequestStruct(.name = "Semaphores",
|
||||
.size = mul_size(maxSemas, sizeof(PGSemaphoreData)),
|
||||
.ptr = (void **) &sharedSemas,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* PGReserveSemaphores --- initialize semaphore support
|
||||
* PGSemaphoreInit --- initialize semaphore support
|
||||
*
|
||||
* This is called during postmaster start or shared memory reinitialization.
|
||||
* It should do whatever is needed to be able to support up to maxSemas
|
||||
|
|
@ -327,10 +331,9 @@ PGSemaphoreShmemSize(int maxSemas)
|
|||
* have clobbered.)
|
||||
*/
|
||||
void
|
||||
PGReserveSemaphores(int maxSemas)
|
||||
PGSemaphoreInit(int maxSemas)
|
||||
{
|
||||
struct stat statbuf;
|
||||
bool found;
|
||||
|
||||
/*
|
||||
* We use the data directory's inode number to seed the search for free
|
||||
|
|
@ -344,10 +347,6 @@ PGReserveSemaphores(int maxSemas)
|
|||
errmsg("could not stat data directory \"%s\": %m",
|
||||
DataDir)));
|
||||
|
||||
sharedSemas = (PGSemaphore)
|
||||
ShmemInitStruct("Semaphores", PGSemaphoreShmemSize(maxSemas), &found);
|
||||
Assert(!found);
|
||||
|
||||
numSharedSemas = 0;
|
||||
maxSharedSemas = maxSemas;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,17 +25,16 @@ static void ReleaseSemaphores(int code, Datum arg);
|
|||
|
||||
|
||||
/*
|
||||
* Report amount of shared memory needed for semaphores
|
||||
* Request shared memory needed for semaphores
|
||||
*/
|
||||
Size
|
||||
PGSemaphoreShmemSize(int maxSemas)
|
||||
void
|
||||
PGSemaphoreShmemRequest(int maxSemas)
|
||||
{
|
||||
/* No shared memory needed on Windows */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* PGReserveSemaphores --- initialize semaphore support
|
||||
* PGSemaphoreInit --- initialize semaphore support
|
||||
*
|
||||
* In the Win32 implementation, we acquire semaphores on-demand; the
|
||||
* maxSemas parameter is just used to size the array that keeps track of
|
||||
|
|
@ -44,7 +43,7 @@ PGSemaphoreShmemSize(int maxSemas)
|
|||
* process exits.
|
||||
*/
|
||||
void
|
||||
PGReserveSemaphores(int maxSemas)
|
||||
PGSemaphoreInit(int maxSemas)
|
||||
{
|
||||
mySemSet = (HANDLE *) malloc(maxSemas * sizeof(HANDLE));
|
||||
if (mySemSet == NULL)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "storage/lwlock.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/freepage.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/resowner.h"
|
||||
|
|
@ -109,6 +110,15 @@ static bool dsm_init_done = false;
|
|||
|
||||
/* Preallocated DSM space in the main shared memory region. */
|
||||
static void *dsm_main_space_begin = NULL;
|
||||
static size_t dsm_main_space_size;
|
||||
|
||||
static void dsm_main_space_request(void *arg);
|
||||
static void dsm_main_space_init(void *arg);
|
||||
|
||||
const ShmemCallbacks dsm_shmem_callbacks = {
|
||||
.request_fn = dsm_main_space_request,
|
||||
.init_fn = dsm_main_space_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* List of dynamic shared memory segments used by this backend.
|
||||
|
|
@ -464,42 +474,40 @@ dsm_set_control_handle(dsm_handle h)
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Reserve some space in the main shared memory segment for DSM segments.
|
||||
* Reserve space in the main shared memory segment for DSM segments.
|
||||
*/
|
||||
size_t
|
||||
dsm_estimate_size(void)
|
||||
static void
|
||||
dsm_main_space_request(void *arg)
|
||||
{
|
||||
return 1024 * 1024 * (size_t) min_dynamic_shared_memory;
|
||||
}
|
||||
dsm_main_space_size = 1024 * 1024 * (size_t) min_dynamic_shared_memory;
|
||||
|
||||
/*
|
||||
* Initialize space in the main shared memory segment for DSM segments.
|
||||
*/
|
||||
void
|
||||
dsm_shmem_init(void)
|
||||
{
|
||||
size_t size = dsm_estimate_size();
|
||||
bool found;
|
||||
|
||||
if (size == 0)
|
||||
if (dsm_main_space_size == 0)
|
||||
return;
|
||||
|
||||
dsm_main_space_begin = ShmemInitStruct("Preallocated DSM", size, &found);
|
||||
if (!found)
|
||||
{
|
||||
FreePageManager *fpm = (FreePageManager *) dsm_main_space_begin;
|
||||
size_t first_page = 0;
|
||||
size_t pages;
|
||||
ShmemRequestStruct(.name = "Preallocated DSM",
|
||||
.size = dsm_main_space_size,
|
||||
.ptr = &dsm_main_space_begin,
|
||||
);
|
||||
}
|
||||
|
||||
/* Reserve space for the FreePageManager. */
|
||||
while (first_page * FPM_PAGE_SIZE < sizeof(FreePageManager))
|
||||
++first_page;
|
||||
static void
|
||||
dsm_main_space_init(void *arg)
|
||||
{
|
||||
FreePageManager *fpm = (FreePageManager *) dsm_main_space_begin;
|
||||
size_t first_page = 0;
|
||||
size_t pages;
|
||||
|
||||
/* Initialize it and give it all the rest of the space. */
|
||||
FreePageManagerInitialize(fpm, dsm_main_space_begin);
|
||||
pages = (size / FPM_PAGE_SIZE) - first_page;
|
||||
FreePageManagerPut(fpm, first_page, pages);
|
||||
}
|
||||
if (dsm_main_space_size == 0)
|
||||
return;
|
||||
|
||||
/* Reserve space for the FreePageManager. */
|
||||
while (first_page * FPM_PAGE_SIZE < sizeof(FreePageManager))
|
||||
++first_page;
|
||||
|
||||
/* Initialize it and give it all the rest of the space. */
|
||||
FreePageManagerInitialize(fpm, dsm_main_space_begin);
|
||||
pages = (dsm_main_space_size / FPM_PAGE_SIZE) - first_page;
|
||||
FreePageManagerPut(fpm, first_page, pages);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "storage/dsm_registry.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/tuplestore.h"
|
||||
|
|
@ -57,6 +58,14 @@ typedef struct DSMRegistryCtxStruct
|
|||
|
||||
static DSMRegistryCtxStruct *DSMRegistryCtx;
|
||||
|
||||
static void DSMRegistryShmemRequest(void *arg);
|
||||
static void DSMRegistryShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks DSMRegistryShmemCallbacks = {
|
||||
.request_fn = DSMRegistryShmemRequest,
|
||||
.init_fn = DSMRegistryShmemInit,
|
||||
};
|
||||
|
||||
typedef struct NamedDSMState
|
||||
{
|
||||
dsm_handle handle;
|
||||
|
|
@ -114,27 +123,20 @@ static const dshash_parameters dsh_params = {
|
|||
static dsa_area *dsm_registry_dsa;
|
||||
static dshash_table *dsm_registry_table;
|
||||
|
||||
Size
|
||||
DSMRegistryShmemSize(void)
|
||||
static void
|
||||
DSMRegistryShmemRequest(void *arg)
|
||||
{
|
||||
return MAXALIGN(sizeof(DSMRegistryCtxStruct));
|
||||
ShmemRequestStruct(.name = "DSM Registry Data",
|
||||
.size = sizeof(DSMRegistryCtxStruct),
|
||||
.ptr = (void **) &DSMRegistryCtx,
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
DSMRegistryShmemInit(void)
|
||||
static void
|
||||
DSMRegistryShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
DSMRegistryCtx = (DSMRegistryCtxStruct *)
|
||||
ShmemInitStruct("DSM Registry Data",
|
||||
DSMRegistryShmemSize(),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DSMRegistryCtx->dsah = DSA_HANDLE_INVALID;
|
||||
DSMRegistryCtx->dshh = DSHASH_HANDLE_INVALID;
|
||||
}
|
||||
DSMRegistryCtx->dsah = DSA_HANDLE_INVALID;
|
||||
DSMRegistryCtx->dshh = DSHASH_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "access/nbtree.h"
|
||||
#include "access/subtrans.h"
|
||||
#include "access/syncscan.h"
|
||||
#include "access/transam.h"
|
||||
#include "access/twophase.h"
|
||||
#include "access/xlogprefetcher.h"
|
||||
#include "access/xlogrecovery.h"
|
||||
|
|
@ -42,16 +41,11 @@
|
|||
#include "storage/aio_subsys.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/dsm.h"
|
||||
#include "storage/dsm_registry.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/predicate.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
|
@ -105,14 +99,10 @@ CalculateShmemSize(void)
|
|||
size = add_size(size, ShmemGetRequestedSize());
|
||||
|
||||
/* legacy subsystems */
|
||||
size = add_size(size, dsm_estimate_size());
|
||||
size = add_size(size, DSMRegistryShmemSize());
|
||||
size = add_size(size, BufferManagerShmemSize());
|
||||
size = add_size(size, LockManagerShmemSize());
|
||||
size = add_size(size, PredicateLockShmemSize());
|
||||
size = add_size(size, ProcGlobalShmemSize());
|
||||
size = add_size(size, XLogPrefetchShmemSize());
|
||||
size = add_size(size, VarsupShmemSize());
|
||||
size = add_size(size, XLOGShmemSize());
|
||||
size = add_size(size, XLogRecoveryShmemSize());
|
||||
size = add_size(size, CLOGShmemSize());
|
||||
|
|
@ -121,11 +111,7 @@ CalculateShmemSize(void)
|
|||
size = add_size(size, TwoPhaseShmemSize());
|
||||
size = add_size(size, BackgroundWorkerShmemSize());
|
||||
size = add_size(size, MultiXactShmemSize());
|
||||
size = add_size(size, ProcArrayShmemSize());
|
||||
size = add_size(size, BackendStatusShmemSize());
|
||||
size = add_size(size, SharedInvalShmemSize());
|
||||
size = add_size(size, PMSignalShmemSize());
|
||||
size = add_size(size, ProcSignalShmemSize());
|
||||
size = add_size(size, CheckpointerShmemSize());
|
||||
size = add_size(size, AutoVacuumShmemSize());
|
||||
size = add_size(size, ReplicationSlotsShmemSize());
|
||||
|
|
@ -278,13 +264,9 @@ RegisterBuiltinShmemCallbacks(void)
|
|||
static void
|
||||
CreateOrAttachShmemStructs(void)
|
||||
{
|
||||
dsm_shmem_init();
|
||||
DSMRegistryShmemInit();
|
||||
|
||||
/*
|
||||
* Set up xlog, clog, and buffers
|
||||
*/
|
||||
VarsupShmemInit();
|
||||
XLOGShmemInit();
|
||||
XLogPrefetchShmemInit();
|
||||
XLogRecoveryShmemInit();
|
||||
|
|
@ -307,23 +289,13 @@ CreateOrAttachShmemStructs(void)
|
|||
/*
|
||||
* Set up process table
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
InitProcGlobal();
|
||||
ProcArrayShmemInit();
|
||||
BackendStatusShmemInit();
|
||||
TwoPhaseShmemInit();
|
||||
BackgroundWorkerShmemInit();
|
||||
|
||||
/*
|
||||
* Set up shared-inval messaging
|
||||
*/
|
||||
SharedInvalShmemInit();
|
||||
|
||||
/*
|
||||
* Set up interprocess signaling mechanisms
|
||||
*/
|
||||
PMSignalShmemInit();
|
||||
ProcSignalShmemInit();
|
||||
CheckpointerShmemInit();
|
||||
AutoVacuumShmemInit();
|
||||
ReplicationSlotsShmemInit();
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ InitLatch(Latch *latch)
|
|||
* current process.
|
||||
*
|
||||
* InitSharedLatch needs to be called in postmaster before forking child
|
||||
* processes, usually right after allocating the shared memory block
|
||||
* containing the latch with ShmemInitStruct. (The Unix implementation
|
||||
* doesn't actually require that, but the Windows one does.) Because of
|
||||
* this restriction, we have no concurrency issues to worry about here.
|
||||
* processes, usually right after initializing the shared memory block
|
||||
* containing the latch. (The Unix implementation doesn't actually require
|
||||
* that, but the Windows one does.) Because of this restriction, we have no
|
||||
* concurrency issues to worry about here.
|
||||
*
|
||||
* Note that other handles created in this module are never marked as
|
||||
* inheritable. Thus we do not need to worry about cleaning up child
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "storage/ipc.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
|
||||
|
|
@ -83,6 +84,14 @@ struct PMSignalData
|
|||
/* PMSignalState pointer is valid in both postmaster and child processes */
|
||||
NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL;
|
||||
|
||||
static void PMSignalShmemRequest(void *);
|
||||
static void PMSignalShmemInit(void *);
|
||||
|
||||
const ShmemCallbacks PMSignalShmemCallbacks = {
|
||||
.request_fn = PMSignalShmemRequest,
|
||||
.init_fn = PMSignalShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Local copy of PMSignalState->num_child_flags, only valid in the
|
||||
* postmaster. Postmaster keeps a local copy so that it doesn't need to
|
||||
|
|
@ -123,39 +132,29 @@ postmaster_death_handler(SIGNAL_ARGS)
|
|||
static void MarkPostmasterChildInactive(int code, Datum arg);
|
||||
|
||||
/*
|
||||
* PMSignalShmemSize
|
||||
* Compute space needed for pmsignal.c's shared memory
|
||||
* PMSignalShmemRequest - Register pmsignal.c's shared memory needs
|
||||
*/
|
||||
Size
|
||||
PMSignalShmemSize(void)
|
||||
static void
|
||||
PMSignalShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
size_t size;
|
||||
|
||||
size = offsetof(PMSignalData, PMChildFlags);
|
||||
size = add_size(size, mul_size(MaxLivePostmasterChildren(),
|
||||
sizeof(sig_atomic_t)));
|
||||
num_child_flags = MaxLivePostmasterChildren();
|
||||
|
||||
return size;
|
||||
size = add_size(offsetof(PMSignalData, PMChildFlags),
|
||||
mul_size(num_child_flags, sizeof(sig_atomic_t)));
|
||||
ShmemRequestStruct(.name = "PMSignalState",
|
||||
.size = size,
|
||||
.ptr = (void **) &PMSignalState,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* PMSignalShmemInit - initialize during shared-memory creation
|
||||
*/
|
||||
void
|
||||
PMSignalShmemInit(void)
|
||||
static void
|
||||
PMSignalShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
PMSignalState = (PMSignalData *)
|
||||
ShmemInitStruct("PMSignalState", PMSignalShmemSize(), &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* initialize all flags to zeroes */
|
||||
MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize());
|
||||
num_child_flags = MaxLivePostmasterChildren();
|
||||
PMSignalState->num_child_flags = num_child_flags;
|
||||
}
|
||||
Assert(PMSignalState);
|
||||
Assert(num_child_flags > 0);
|
||||
PMSignalState->num_child_flags = num_child_flags;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
|
@ -103,6 +104,18 @@ typedef struct ProcArrayStruct
|
|||
int pgprocnos[FLEXIBLE_ARRAY_MEMBER];
|
||||
} ProcArrayStruct;
|
||||
|
||||
static void ProcArrayShmemRequest(void *arg);
|
||||
static void ProcArrayShmemInit(void *arg);
|
||||
static void ProcArrayShmemAttach(void *arg);
|
||||
|
||||
static ProcArrayStruct *procArray;
|
||||
|
||||
const struct ShmemCallbacks ProcArrayShmemCallbacks = {
|
||||
.request_fn = ProcArrayShmemRequest,
|
||||
.init_fn = ProcArrayShmemInit,
|
||||
.attach_fn = ProcArrayShmemAttach,
|
||||
};
|
||||
|
||||
/*
|
||||
* State for the GlobalVisTest* family of functions. Those functions can
|
||||
* e.g. be used to decide if a deleted row can be removed without violating
|
||||
|
|
@ -269,9 +282,6 @@ typedef enum KAXCompressReason
|
|||
KAX_STARTUP_PROCESS_IDLE, /* startup process is about to sleep */
|
||||
} KAXCompressReason;
|
||||
|
||||
|
||||
static ProcArrayStruct *procArray;
|
||||
|
||||
static PGPROC *allProcs;
|
||||
|
||||
/*
|
||||
|
|
@ -282,8 +292,11 @@ static TransactionId cachedXidIsNotInProgress = InvalidTransactionId;
|
|||
/*
|
||||
* Bookkeeping for tracking emulated transactions in recovery
|
||||
*/
|
||||
|
||||
static TransactionId *KnownAssignedXids;
|
||||
|
||||
static bool *KnownAssignedXidsValid;
|
||||
|
||||
static TransactionId latestObservedXid = InvalidTransactionId;
|
||||
|
||||
/*
|
||||
|
|
@ -374,19 +387,13 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
|
|||
static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by ProcArrayShmemInit
|
||||
* Register the shared PGPROC array during postmaster startup.
|
||||
*/
|
||||
Size
|
||||
ProcArrayShmemSize(void)
|
||||
static void
|
||||
ProcArrayShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
/* Size of the ProcArray structure itself */
|
||||
#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
|
||||
|
||||
size = offsetof(ProcArrayStruct, pgprocnos);
|
||||
size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS));
|
||||
|
||||
/*
|
||||
* During Hot Standby processing we have a data structure called
|
||||
* KnownAssignedXids, created in shared memory. Local data structures are
|
||||
|
|
@ -405,64 +412,49 @@ ProcArrayShmemSize(void)
|
|||
|
||||
if (EnableHotStandby)
|
||||
{
|
||||
size = add_size(size,
|
||||
mul_size(sizeof(TransactionId),
|
||||
TOTAL_MAX_CACHED_SUBXIDS));
|
||||
size = add_size(size,
|
||||
mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
|
||||
ShmemRequestStruct(.name = "KnownAssignedXids",
|
||||
.size = mul_size(sizeof(TransactionId), TOTAL_MAX_CACHED_SUBXIDS),
|
||||
.ptr = (void **) &KnownAssignedXids,
|
||||
);
|
||||
|
||||
ShmemRequestStruct(.name = "KnownAssignedXidsValid",
|
||||
.size = mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
|
||||
.ptr = (void **) &KnownAssignedXidsValid,
|
||||
);
|
||||
}
|
||||
|
||||
return size;
|
||||
/* Register the ProcArray shared structure */
|
||||
ShmemRequestStruct(.name = "Proc Array",
|
||||
.size = add_size(offsetof(ProcArrayStruct, pgprocnos),
|
||||
mul_size(sizeof(int), PROCARRAY_MAXPROCS)),
|
||||
.ptr = (void **) &procArray,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the shared PGPROC array during postmaster startup.
|
||||
*/
|
||||
void
|
||||
ProcArrayShmemInit(void)
|
||||
static void
|
||||
ProcArrayShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
/* Create or attach to the ProcArray shared structure */
|
||||
procArray = (ProcArrayStruct *)
|
||||
ShmemInitStruct("Proc Array",
|
||||
add_size(offsetof(ProcArrayStruct, pgprocnos),
|
||||
mul_size(sizeof(int),
|
||||
PROCARRAY_MAXPROCS)),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/*
|
||||
* We're the first - initialize.
|
||||
*/
|
||||
procArray->numProcs = 0;
|
||||
procArray->maxProcs = PROCARRAY_MAXPROCS;
|
||||
procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
|
||||
procArray->numKnownAssignedXids = 0;
|
||||
procArray->tailKnownAssignedXids = 0;
|
||||
procArray->headKnownAssignedXids = 0;
|
||||
procArray->lastOverflowedXid = InvalidTransactionId;
|
||||
procArray->replication_slot_xmin = InvalidTransactionId;
|
||||
procArray->replication_slot_catalog_xmin = InvalidTransactionId;
|
||||
TransamVariables->xactCompletionCount = 1;
|
||||
}
|
||||
procArray->numProcs = 0;
|
||||
procArray->maxProcs = PROCARRAY_MAXPROCS;
|
||||
procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
|
||||
procArray->numKnownAssignedXids = 0;
|
||||
procArray->tailKnownAssignedXids = 0;
|
||||
procArray->headKnownAssignedXids = 0;
|
||||
procArray->lastOverflowedXid = InvalidTransactionId;
|
||||
procArray->replication_slot_xmin = InvalidTransactionId;
|
||||
procArray->replication_slot_catalog_xmin = InvalidTransactionId;
|
||||
TransamVariables->xactCompletionCount = 1;
|
||||
|
||||
allProcs = ProcGlobal->allProcs;
|
||||
}
|
||||
|
||||
/* Create or attach to the KnownAssignedXids arrays too, if needed */
|
||||
if (EnableHotStandby)
|
||||
{
|
||||
KnownAssignedXids = (TransactionId *)
|
||||
ShmemInitStruct("KnownAssignedXids",
|
||||
mul_size(sizeof(TransactionId),
|
||||
TOTAL_MAX_CACHED_SUBXIDS),
|
||||
&found);
|
||||
KnownAssignedXidsValid = (bool *)
|
||||
ShmemInitStruct("KnownAssignedXidsValid",
|
||||
mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
|
||||
&found);
|
||||
}
|
||||
static void
|
||||
ProcArrayShmemAttach(void *arg)
|
||||
{
|
||||
allProcs = ProcGlobal->allProcs;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "storage/shmem.h"
|
||||
#include "storage/sinval.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
|
@ -106,7 +107,16 @@ struct ProcSignalHeader
|
|||
#define BARRIER_CLEAR_BIT(flags, type) \
|
||||
((flags) &= ~(((uint32) 1) << (uint32) (type)))
|
||||
|
||||
static void ProcSignalShmemRequest(void *arg);
|
||||
static void ProcSignalShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks ProcSignalShmemCallbacks = {
|
||||
.request_fn = ProcSignalShmemRequest,
|
||||
.init_fn = ProcSignalShmemInit,
|
||||
};
|
||||
|
||||
NON_EXEC_STATIC ProcSignalHeader *ProcSignal = NULL;
|
||||
|
||||
static ProcSignalSlot *MyProcSignalSlot = NULL;
|
||||
|
||||
static bool CheckProcSignal(ProcSignalReason reason);
|
||||
|
|
@ -114,51 +124,39 @@ static void CleanupProcSignalState(int status, Datum arg);
|
|||
static void ResetProcSignalBarrierBits(uint32 flags);
|
||||
|
||||
/*
|
||||
* ProcSignalShmemSize
|
||||
* Compute space needed for ProcSignal's shared memory
|
||||
* ProcSignalShmemRequest
|
||||
* Register ProcSignal's shared memory needs at postmaster startup
|
||||
*/
|
||||
Size
|
||||
ProcSignalShmemSize(void)
|
||||
static void
|
||||
ProcSignalShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
size = mul_size(NumProcSignalSlots, sizeof(ProcSignalSlot));
|
||||
size = add_size(size, offsetof(ProcSignalHeader, psh_slot));
|
||||
return size;
|
||||
|
||||
ShmemRequestStruct(.name = "ProcSignal",
|
||||
.size = size,
|
||||
.ptr = (void **) &ProcSignal,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* ProcSignalShmemInit
|
||||
* Allocate and initialize ProcSignal's shared memory
|
||||
*/
|
||||
void
|
||||
ProcSignalShmemInit(void)
|
||||
static void
|
||||
ProcSignalShmemInit(void *arg)
|
||||
{
|
||||
Size size = ProcSignalShmemSize();
|
||||
bool found;
|
||||
pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0);
|
||||
|
||||
ProcSignal = (ProcSignalHeader *)
|
||||
ShmemInitStruct("ProcSignal", size, &found);
|
||||
|
||||
/* If we're first, initialize. */
|
||||
if (!found)
|
||||
for (int i = 0; i < NumProcSignalSlots; ++i)
|
||||
{
|
||||
int i;
|
||||
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||
|
||||
pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0);
|
||||
|
||||
for (i = 0; i < NumProcSignalSlots; ++i)
|
||||
{
|
||||
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||
|
||||
SpinLockInit(&slot->pss_mutex);
|
||||
pg_atomic_init_u32(&slot->pss_pid, 0);
|
||||
slot->pss_cancel_key_len = 0;
|
||||
MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags));
|
||||
pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX);
|
||||
pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0);
|
||||
ConditionVariableInit(&slot->pss_barrierCV);
|
||||
}
|
||||
SpinLockInit(&slot->pss_mutex);
|
||||
pg_atomic_init_u32(&slot->pss_pid, 0);
|
||||
slot->pss_cancel_key_len = 0;
|
||||
MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags));
|
||||
pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX);
|
||||
pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0);
|
||||
ConditionVariableInit(&slot->pss_barrierCV);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "storage/shmem.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/subsystems.h"
|
||||
|
||||
/*
|
||||
* Conceptually, the shared cache invalidation messages are stored in an
|
||||
|
|
@ -205,6 +206,14 @@ typedef struct SISeg
|
|||
|
||||
static SISeg *shmInvalBuffer; /* pointer to the shared inval buffer */
|
||||
|
||||
static void SharedInvalShmemRequest(void *arg);
|
||||
static void SharedInvalShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks SharedInvalShmemCallbacks = {
|
||||
.request_fn = SharedInvalShmemRequest,
|
||||
.init_fn = SharedInvalShmemInit,
|
||||
};
|
||||
|
||||
|
||||
static LocalTransactionId nextLocalTransactionId;
|
||||
|
||||
|
|
@ -212,10 +221,11 @@ static void CleanupInvalidationState(int status, Datum arg);
|
|||
|
||||
|
||||
/*
|
||||
* SharedInvalShmemSize --- return shared-memory space needed
|
||||
* SharedInvalShmemRequest
|
||||
* Register shared memory needs for the SI message buffer
|
||||
*/
|
||||
Size
|
||||
SharedInvalShmemSize(void)
|
||||
static void
|
||||
SharedInvalShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -223,26 +233,18 @@ SharedInvalShmemSize(void)
|
|||
size = add_size(size, mul_size(sizeof(ProcState), NumProcStateSlots)); /* procState */
|
||||
size = add_size(size, mul_size(sizeof(int), NumProcStateSlots)); /* pgprocnos */
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "shmInvalBuffer",
|
||||
.size = size,
|
||||
.ptr = (void **) &shmInvalBuffer,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* SharedInvalShmemInit
|
||||
* Create and initialize the SI message buffer
|
||||
*/
|
||||
void
|
||||
SharedInvalShmemInit(void)
|
||||
static void
|
||||
SharedInvalShmemInit(void *arg)
|
||||
{
|
||||
int i;
|
||||
bool found;
|
||||
|
||||
/* Allocate space in shared memory */
|
||||
shmInvalBuffer = (SISeg *)
|
||||
ShmemInitStruct("shmInvalBuffer", SharedInvalShmemSize(), &found);
|
||||
if (found)
|
||||
return;
|
||||
|
||||
/* Clear message counters, save size of procState array, init spinlock */
|
||||
/* Clear message counters, init spinlock */
|
||||
shmInvalBuffer->minMsgNum = 0;
|
||||
shmInvalBuffer->maxMsgNum = 0;
|
||||
shmInvalBuffer->nextThreshold = CLEANUP_MIN;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "storage/procsignal.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/standby.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/timeout.h"
|
||||
#include "utils/timestamp.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
|
@ -70,9 +71,23 @@ PGPROC *MyProc = NULL;
|
|||
|
||||
/* Pointers to shared-memory structures */
|
||||
PROC_HDR *ProcGlobal = NULL;
|
||||
static void *AllProcsShmemPtr;
|
||||
static void *FastPathLockArrayShmemPtr;
|
||||
NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL;
|
||||
PGPROC *PreparedXactProcs = NULL;
|
||||
|
||||
static void ProcGlobalShmemRequest(void *arg);
|
||||
static void ProcGlobalShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks ProcGlobalShmemCallbacks = {
|
||||
.request_fn = ProcGlobalShmemRequest,
|
||||
.init_fn = ProcGlobalShmemInit,
|
||||
};
|
||||
|
||||
static uint32 TotalProcs;
|
||||
static size_t ProcGlobalAllProcsShmemSize;
|
||||
static size_t FastPathLockArrayShmemSize;
|
||||
|
||||
/* Is a deadlock check pending? */
|
||||
static volatile sig_atomic_t got_deadlock_timeout;
|
||||
|
||||
|
|
@ -83,32 +98,12 @@ static DeadLockState CheckDeadLock(void);
|
|||
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by PGPROC.
|
||||
* Calculate shared-memory space needed by Fast-Path locks.
|
||||
*/
|
||||
static Size
|
||||
PGProcShmemSize(void)
|
||||
CalculateFastPathLockShmemSize(void)
|
||||
{
|
||||
Size size = 0;
|
||||
Size TotalProcs =
|
||||
add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
|
||||
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by Fast-Path locks.
|
||||
*/
|
||||
static Size
|
||||
FastPathLockShmemSize(void)
|
||||
{
|
||||
Size size = 0;
|
||||
Size TotalProcs =
|
||||
add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
|
||||
Size fpLockBitsSize,
|
||||
fpRelIdSize;
|
||||
|
||||
|
|
@ -128,26 +123,7 @@ FastPathLockShmemSize(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by InitProcGlobal.
|
||||
*/
|
||||
Size
|
||||
ProcGlobalShmemSize(void)
|
||||
{
|
||||
Size size = 0;
|
||||
|
||||
/* ProcGlobal */
|
||||
size = add_size(size, sizeof(PROC_HDR));
|
||||
size = add_size(size, sizeof(slock_t));
|
||||
|
||||
size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas()));
|
||||
size = add_size(size, PGProcShmemSize());
|
||||
size = add_size(size, FastPathLockShmemSize());
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report number of semaphores needed by InitProcGlobal.
|
||||
* Report number of semaphores needed by ProcGlobalShmemInit.
|
||||
*/
|
||||
int
|
||||
ProcGlobalSemas(void)
|
||||
|
|
@ -160,7 +136,67 @@ ProcGlobalSemas(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* InitProcGlobal -
|
||||
* ProcGlobalShmemRequest
|
||||
* Register shared memory needs.
|
||||
*
|
||||
* This is called during postmaster or standalone backend startup, and also
|
||||
* during backend startup in EXEC_BACKEND mode.
|
||||
*/
|
||||
static void
|
||||
ProcGlobalShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
/*
|
||||
* Reserve all the PGPROC structures we'll need. There are six separate
|
||||
* consumers: (1) normal backends, (2) autovacuum workers and special
|
||||
* workers, (3) background workers, (4) walsenders, (5) auxiliary
|
||||
* processes, and (6) prepared transactions. (For largely-historical
|
||||
* reasons, we combine autovacuum and special workers into one category
|
||||
* with a single freelist.) Each PGPROC structure is dedicated to exactly
|
||||
* one of these purposes, and they do not move between groups.
|
||||
*/
|
||||
TotalProcs =
|
||||
add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
|
||||
|
||||
size = 0;
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
|
||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
|
||||
ProcGlobalAllProcsShmemSize = size;
|
||||
ShmemRequestStruct(.name = "PGPROC structures",
|
||||
.size = ProcGlobalAllProcsShmemSize,
|
||||
.ptr = &AllProcsShmemPtr,
|
||||
);
|
||||
|
||||
if (!IsUnderPostmaster)
|
||||
size = FastPathLockArrayShmemSize = CalculateFastPathLockShmemSize();
|
||||
else
|
||||
size = SHMEM_ATTACH_UNKNOWN_SIZE;
|
||||
ShmemRequestStruct(.name = "Fast-Path Lock Array",
|
||||
.size = size,
|
||||
.ptr = &FastPathLockArrayShmemPtr,
|
||||
);
|
||||
|
||||
/*
|
||||
* ProcGlobal is registered here in .ptr as usual, but it needs to be
|
||||
* propagated specially in EXEC_BACKEND mode, because ProcGlobal needs to
|
||||
* be accessed early at backend startup, before ShmemAttachRequested() has
|
||||
* been called.
|
||||
*/
|
||||
ShmemRequestStruct(.name = "Proc Header",
|
||||
.size = sizeof(PROC_HDR),
|
||||
.ptr = (void **) &ProcGlobal,
|
||||
);
|
||||
|
||||
/* Let the semaphore implementation register its shared memory needs */
|
||||
PGSemaphoreShmemRequest(ProcGlobalSemas());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ProcGlobalShmemInit -
|
||||
* Initialize the global process table during postmaster or standalone
|
||||
* backend startup.
|
||||
*
|
||||
|
|
@ -179,36 +215,23 @@ ProcGlobalSemas(void)
|
|||
* Another reason for creating semaphores here is that the semaphore
|
||||
* implementation typically requires us to create semaphores in the
|
||||
* postmaster, not in backends.
|
||||
*
|
||||
* Note: this is NOT called by individual backends under a postmaster,
|
||||
* not even in the EXEC_BACKEND case. The ProcGlobal and AuxiliaryProcs
|
||||
* pointers must be propagated specially for EXEC_BACKEND operation.
|
||||
*/
|
||||
void
|
||||
InitProcGlobal(void)
|
||||
static void
|
||||
ProcGlobalShmemInit(void *arg)
|
||||
{
|
||||
char *ptr;
|
||||
size_t requestSize;
|
||||
PGPROC *procs;
|
||||
int i,
|
||||
j;
|
||||
bool found;
|
||||
uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
|
||||
|
||||
/* Used for setup of per-backend fast-path slots. */
|
||||
char *fpPtr,
|
||||
*fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
|
||||
Size fpLockBitsSize,
|
||||
fpRelIdSize;
|
||||
Size requestSize;
|
||||
char *ptr;
|
||||
|
||||
/* Create the ProcGlobal shared structure */
|
||||
ProcGlobal = (PROC_HDR *)
|
||||
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
|
||||
Assert(!found);
|
||||
|
||||
/*
|
||||
* Initialize the data structures.
|
||||
*/
|
||||
Assert(ProcGlobal);
|
||||
ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
|
||||
SpinLockInit(&ProcGlobal->freeProcsLock);
|
||||
dlist_init(&ProcGlobal->freeProcs);
|
||||
|
|
@ -221,23 +244,11 @@ InitProcGlobal(void)
|
|||
pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
|
||||
pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
|
||||
|
||||
/*
|
||||
* Create and initialize all the PGPROC structures we'll need. There are
|
||||
* six separate consumers: (1) normal backends, (2) autovacuum workers and
|
||||
* special workers, (3) background workers, (4) walsenders, (5) auxiliary
|
||||
* processes, and (6) prepared transactions. (For largely-historical
|
||||
* reasons, we combine autovacuum and special workers into one category
|
||||
* with a single freelist.) Each PGPROC structure is dedicated to exactly
|
||||
* one of these purposes, and they do not move between groups.
|
||||
*/
|
||||
requestSize = PGProcShmemSize();
|
||||
|
||||
ptr = ShmemInitStruct("PGPROC structures",
|
||||
requestSize,
|
||||
&found);
|
||||
|
||||
ptr = AllProcsShmemPtr;
|
||||
requestSize = ProcGlobalAllProcsShmemSize;
|
||||
MemSet(ptr, 0, requestSize);
|
||||
|
||||
/* Carve out the allProcs array from the shared memory area */
|
||||
procs = (PGPROC *) ptr;
|
||||
ptr = ptr + TotalProcs * sizeof(PGPROC);
|
||||
|
||||
|
|
@ -246,7 +257,7 @@ InitProcGlobal(void)
|
|||
ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
|
||||
|
||||
/*
|
||||
* Allocate arrays mirroring PGPROC fields in a dense manner. See
|
||||
* Carve out arrays mirroring PGPROC fields in a dense manner. See
|
||||
* PROC_HDR.
|
||||
*
|
||||
* XXX: It might make sense to increase padding for these arrays, given
|
||||
|
|
@ -261,30 +272,26 @@ InitProcGlobal(void)
|
|||
ProcGlobal->statusFlags = (uint8 *) ptr;
|
||||
ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
|
||||
|
||||
/* make sure wer didn't overflow */
|
||||
/* make sure we didn't overflow */
|
||||
Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
|
||||
|
||||
/*
|
||||
* Allocate arrays for fast-path locks. Those are variable-length, so
|
||||
* Initialize arrays for fast-path locks. Those are variable-length, so
|
||||
* can't be included in PGPROC directly. We allocate a separate piece of
|
||||
* shared memory and then divide that between backends.
|
||||
*/
|
||||
fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
|
||||
fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
|
||||
|
||||
requestSize = FastPathLockShmemSize();
|
||||
|
||||
fpPtr = ShmemInitStruct("Fast-Path Lock Array",
|
||||
requestSize,
|
||||
&found);
|
||||
|
||||
MemSet(fpPtr, 0, requestSize);
|
||||
fpPtr = FastPathLockArrayShmemPtr;
|
||||
requestSize = FastPathLockArrayShmemSize;
|
||||
memset(fpPtr, 0, requestSize);
|
||||
|
||||
/* For asserts checking we did not overflow. */
|
||||
fpEndPtr = fpPtr + requestSize;
|
||||
|
||||
/* Reserve space for semaphores. */
|
||||
PGReserveSemaphores(ProcGlobalSemas());
|
||||
/* Initialize semaphores */
|
||||
PGSemaphoreInit(ProcGlobalSemas());
|
||||
|
||||
for (i = 0; i < TotalProcs; i++)
|
||||
{
|
||||
|
|
@ -405,7 +412,7 @@ InitProcess(void)
|
|||
|
||||
/*
|
||||
* Decide which list should supply our PGPROC. This logic must match the
|
||||
* way the freelists were constructed in InitProcGlobal().
|
||||
* way the freelists were constructed in ProcGlobalShmemInit().
|
||||
*/
|
||||
if (AmAutoVacuumWorkerProcess() || AmSpecialWorkerProcess())
|
||||
procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||
|
|
@ -460,7 +467,7 @@ InitProcess(void)
|
|||
|
||||
/*
|
||||
* Initialize all fields of MyProc, except for those previously
|
||||
* initialized by InitProcGlobal.
|
||||
* initialized by ProcGlobalShmemInit.
|
||||
*/
|
||||
dlist_node_init(&MyProc->freeProcsLink);
|
||||
MyProc->waitStatus = PROC_WAIT_STATUS_OK;
|
||||
|
|
@ -593,7 +600,7 @@ InitProcessPhase2(void)
|
|||
* This is called by bgwriter and similar processes so that they will have a
|
||||
* MyProc value that's real enough to let them wait for LWLocks. The PGPROC
|
||||
* and sema that are assigned are one of the extra ones created during
|
||||
* InitProcGlobal.
|
||||
* ProcGlobalShmemInit.
|
||||
*
|
||||
* Auxiliary processes are presently not expected to wait for real (lockmgr)
|
||||
* locks, so we need not set up the deadlock checker. They are never added
|
||||
|
|
@ -662,7 +669,7 @@ InitAuxiliaryProcess(void)
|
|||
|
||||
/*
|
||||
* Initialize all fields of MyProc, except for those previously
|
||||
* initialized by InitProcGlobal.
|
||||
* initialized by ProcGlobalShmemInit.
|
||||
*/
|
||||
dlist_node_init(&MyProc->freeProcsLink);
|
||||
MyProc->waitStatus = PROC_WAIT_STATUS_OK;
|
||||
|
|
|
|||
|
|
@ -338,7 +338,8 @@ string_compare(const char *key1, const char *key2, Size keysize)
|
|||
* under info->hcxt rather than under TopMemoryContext; the default
|
||||
* behavior is only suitable for session-lifespan hash tables.
|
||||
* Other flags bits are special-purpose and seldom used, except for those
|
||||
* associated with shared-memory hash tables, for which see ShmemInitHash().
|
||||
* associated with shared-memory hash tables, for which see
|
||||
* ShmemRequestHash().
|
||||
*
|
||||
* Fields in *info are read only when the associated flags bit is set.
|
||||
* It is not necessary to initialize other fields of *info.
|
||||
|
|
|
|||
|
|
@ -345,8 +345,6 @@ extern TransactionId TransactionIdLatest(TransactionId mainxid,
|
|||
extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
|
||||
|
||||
/* in transam/varsup.c */
|
||||
extern Size VarsupShmemSize(void);
|
||||
extern void VarsupShmemInit(void);
|
||||
extern FullTransactionId GetNewTransactionId(bool isSubXact);
|
||||
extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid);
|
||||
extern FullTransactionId ReadNextFullTransactionId(void);
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ extern void dsm_postmaster_startup(PGShmemHeader *);
|
|||
extern void dsm_backend_shutdown(void);
|
||||
extern void dsm_detach_all(void);
|
||||
|
||||
extern size_t dsm_estimate_size(void);
|
||||
extern void dsm_shmem_init(void);
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
extern void dsm_set_control_handle(dsm_handle h);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,7 +22,5 @@ extern dsa_area *GetNamedDSA(const char *name, bool *found);
|
|||
extern dshash_table *GetNamedDSHash(const char *name,
|
||||
const dshash_parameters *params,
|
||||
bool *found);
|
||||
extern Size DSMRegistryShmemSize(void);
|
||||
extern void DSMRegistryShmemInit(void);
|
||||
|
||||
#endif /* DSM_REGISTRY_H */
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ typedef HANDLE PGSemaphore;
|
|||
#endif
|
||||
|
||||
|
||||
/* Report amount of shared memory needed */
|
||||
extern Size PGSemaphoreShmemSize(int maxSemas);
|
||||
/* Request shared memory needed for semaphores */
|
||||
extern void PGSemaphoreShmemRequest(int maxSemas);
|
||||
|
||||
/* Module initialization (called during postmaster start or shmem reinit) */
|
||||
extern void PGReserveSemaphores(int maxSemas);
|
||||
extern void PGSemaphoreInit(int maxSemas);
|
||||
|
||||
/* Allocate a PGSemaphore structure with initial count 1 */
|
||||
extern PGSemaphore PGSemaphoreCreate(void);
|
||||
|
|
|
|||
|
|
@ -66,8 +66,6 @@ extern PGDLLIMPORT volatile PMSignalData *PMSignalState;
|
|||
/*
|
||||
* prototypes for functions in pmsignal.c
|
||||
*/
|
||||
extern Size PMSignalShmemSize(void);
|
||||
extern void PMSignalShmemInit(void);
|
||||
extern void SendPostmasterSignal(PMSignalReason reason);
|
||||
extern bool CheckPostmasterSignal(PMSignalReason reason);
|
||||
extern void SetQuitSignalReason(QuitSignalReason reason);
|
||||
|
|
|
|||
|
|
@ -552,8 +552,6 @@ extern PGDLLIMPORT PGPROC *AuxiliaryProcs;
|
|||
* Function Prototypes
|
||||
*/
|
||||
extern int ProcGlobalSemas(void);
|
||||
extern Size ProcGlobalShmemSize(void);
|
||||
extern void InitProcGlobal(void);
|
||||
extern void InitProcess(void);
|
||||
extern void InitProcessPhase2(void);
|
||||
extern void InitAuxiliaryProcess(void);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
#include "utils/snapshot.h"
|
||||
|
||||
|
||||
extern Size ProcArrayShmemSize(void);
|
||||
extern void ProcArrayShmemInit(void);
|
||||
extern void ProcArrayAdd(PGPROC *proc);
|
||||
extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,9 +67,6 @@ typedef enum
|
|||
/*
|
||||
* prototypes for functions in procsignal.c
|
||||
*/
|
||||
extern Size ProcSignalShmemSize(void);
|
||||
extern void ProcSignalShmemInit(void);
|
||||
|
||||
extern void ProcSignalInit(const uint8 *cancel_key, int cancel_key_len);
|
||||
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
|
||||
ProcNumber procNumber);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
/*
|
||||
* prototypes for functions in sinvaladt.c
|
||||
*/
|
||||
extern Size SharedInvalShmemSize(void);
|
||||
extern void SharedInvalShmemInit(void);
|
||||
extern void SharedInvalBackendInit(bool sendOnly);
|
||||
|
||||
extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n);
|
||||
|
|
|
|||
|
|
@ -27,4 +27,19 @@
|
|||
*/
|
||||
PG_SHMEM_SUBSYSTEM(LWLockCallbacks)
|
||||
|
||||
/* TODO: nothing else for now */
|
||||
PG_SHMEM_SUBSYSTEM(dsm_shmem_callbacks)
|
||||
PG_SHMEM_SUBSYSTEM(DSMRegistryShmemCallbacks)
|
||||
|
||||
/* xlog, clog, and buffers */
|
||||
PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks)
|
||||
|
||||
/* process table */
|
||||
PG_SHMEM_SUBSYSTEM(ProcGlobalShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ProcArrayShmemCallbacks)
|
||||
|
||||
/* shared-inval messaging */
|
||||
PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks)
|
||||
|
||||
/* interprocess signaling mechanisms */
|
||||
PG_SHMEM_SUBSYSTEM(PMSignalShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ProcSignalShmemCallbacks)
|
||||
|
|
|
|||
Loading…
Reference in a new issue