Use separate lwlock tranches for buffer, lock, and predicate lock managers.

This finishes the work - spread across many commits over the last
several months - of putting each type of lock other than the named
individual locks into a separate tranche.

Amit Kapila
This commit is contained in:
Robert Haas 2016-02-11 14:07:33 -05:00
parent b11d07b6a3
commit c319991bca
2 changed files with 105 additions and 42 deletions

View File

@ -125,6 +125,9 @@ static int LWLockTranchesAllocated = 0;
*/ */
LWLockPadded *MainLWLockArray = NULL; LWLockPadded *MainLWLockArray = NULL;
static LWLockTranche MainLWLockTranche; static LWLockTranche MainLWLockTranche;
static LWLockTranche BufMappingLWLockTranche;
static LWLockTranche LockManagerLWLockTranche;
static LWLockTranche PredicateLockManagerLWLockTranche;
/* /*
* We use this structure to keep track of locked LWLocks for release * We use this structure to keep track of locked LWLocks for release
@ -159,6 +162,9 @@ NamedLWLockTranche *NamedLWLockTrancheArray = NULL;
static bool lock_named_request_allowed = true; static bool lock_named_request_allowed = true;
static void InitializeLWLocks(void);
static void RegisterLWLockTranches(void);
#ifdef LWLOCK_STATS #ifdef LWLOCK_STATS
typedef struct lwlock_stats_key typedef struct lwlock_stats_key
{ {
@ -395,14 +401,12 @@ LWLockShmemSize(void)
} }
/* /*
* Allocate shmem space for the main LWLock array and named tranches and * Allocate shmem space for the main LWLock array and all tranches and
* initialize it. We also register the main and named tranche here. * initialize it. We also register all the LWLock tranches here.
*/ */
void void
CreateLWLocks(void) CreateLWLocks(void)
{ {
int i;
StaticAssertExpr(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS, StaticAssertExpr(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
"MAX_BACKENDS too big for lwlock.c"); "MAX_BACKENDS too big for lwlock.c");
@ -412,14 +416,9 @@ CreateLWLocks(void)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
int numLocks = NUM_FIXED_LWLOCKS;
int numNamedLocks = NumLWLocksByNamedTranches();
Size spaceLocks = LWLockShmemSize(); Size spaceLocks = LWLockShmemSize();
LWLockPadded *lock;
int *LWLockCounter; int *LWLockCounter;
char *ptr; char *ptr;
int id;
int j;
/* Allocate space */ /* Allocate space */
ptr = (char *) ShmemAlloc(spaceLocks); ptr = (char *) ShmemAlloc(spaceLocks);
@ -432,10 +431,6 @@ CreateLWLocks(void)
MainLWLockArray = (LWLockPadded *) ptr; MainLWLockArray = (LWLockPadded *) ptr;
/* Initialize all fixed LWLocks in main array */
for (id = 0, lock = MainLWLockArray; id < numLocks; id++, lock++)
LWLockInitialize(&lock->lock, LWTRANCHE_MAIN);
/* /*
* Initialize the dynamic-allocation counter for tranches, which is * Initialize the dynamic-allocation counter for tranches, which is
* stored just before the first LWLock. * stored just before the first LWLock.
@ -443,44 +438,92 @@ CreateLWLocks(void)
LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int)); LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int));
*LWLockCounter = LWTRANCHE_FIRST_USER_DEFINED; *LWLockCounter = LWTRANCHE_FIRST_USER_DEFINED;
/* Initialize named tranches. */ /* Initialize all LWLocks */
if (NamedLWLockTrancheRequests > 0) InitializeLWLocks();
}
/* Register all LWLock tranches */
RegisterLWLockTranches();
}
/*
* Initialize LWLocks that are fixed and those belonging to named tranches.
*/
static void
InitializeLWLocks(void)
{
int numNamedLocks = NumLWLocksByNamedTranches();
int id;
int i;
int j;
LWLockPadded *lock;
/* Initialize all individual LWLocks in main array */
for (id = 0, lock = MainLWLockArray; id < NUM_INDIVIDUAL_LWLOCKS; id++, lock++)
LWLockInitialize(&lock->lock, LWTRANCHE_MAIN);
/* Initialize buffer mapping LWLocks in main array */
lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS;
for (id = 0; id < NUM_BUFFER_PARTITIONS; id++, lock++)
LWLockInitialize(&lock->lock, LWTRANCHE_BUFFER_MAPPING);
/* Initialize lmgrs' LWLocks in main array */
lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS + NUM_BUFFER_PARTITIONS;
for (id = 0; id < NUM_LOCK_PARTITIONS; id++, lock++)
LWLockInitialize(&lock->lock, LWTRANCHE_LOCK_MANAGER);
/* Initialize predicate lmgrs' LWLocks in main array */
lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS +
NUM_BUFFER_PARTITIONS + NUM_LOCK_PARTITIONS;
for (id = 0; id < NUM_PREDICATELOCK_PARTITIONS; id++, lock++)
LWLockInitialize(&lock->lock, LWTRANCHE_PREDICATE_LOCK_MANAGER);
/* Initialize named tranches. */
if (NamedLWLockTrancheRequests > 0)
{
char *trancheNames;
NamedLWLockTrancheArray = (NamedLWLockTranche *)
&MainLWLockArray[NUM_FIXED_LWLOCKS + numNamedLocks];
trancheNames = (char *) NamedLWLockTrancheArray +
(NamedLWLockTrancheRequests * sizeof(NamedLWLockTranche));
lock = &MainLWLockArray[NUM_FIXED_LWLOCKS];
for (i = 0; i < NamedLWLockTrancheRequests; i++)
{ {
char *trancheNames; NamedLWLockTrancheRequest *request;
NamedLWLockTranche *tranche;
char *name;
NamedLWLockTrancheArray = (NamedLWLockTranche *) request = &NamedLWLockTrancheRequestArray[i];
&MainLWLockArray[numLocks + numNamedLocks]; tranche = &NamedLWLockTrancheArray[i];
trancheNames = (char *) NamedLWLockTrancheArray + name = trancheNames;
(NamedLWLockTrancheRequests * sizeof(NamedLWLockTranche)); trancheNames += strlen(request->tranche_name) + 1;
lock = &MainLWLockArray[numLocks]; strcpy(name, request->tranche_name);
tranche->lwLockTranche.name = name;
tranche->trancheId = LWLockNewTrancheId();
tranche->lwLockTranche.array_base = lock;
tranche->lwLockTranche.array_stride = sizeof(LWLockPadded);
for (i = 0; i < NamedLWLockTrancheRequests; i++) for (j = 0; j < request->num_lwlocks; j++, lock++)
{ LWLockInitialize(&lock->lock, tranche->trancheId);
NamedLWLockTrancheRequest *request;
NamedLWLockTranche *tranche;
char *name;
request = &NamedLWLockTrancheRequestArray[i];
tranche = &NamedLWLockTrancheArray[i];
name = trancheNames;
trancheNames += strlen(request->tranche_name) + 1;
strcpy(name, request->tranche_name);
tranche->lwLockTranche.name = name;
tranche->trancheId = LWLockNewTrancheId();
tranche->lwLockTranche.array_base = lock;
tranche->lwLockTranche.array_stride = sizeof(LWLockPadded);
for (j = 0; j < request->num_lwlocks; j++, lock++)
LWLockInitialize(&lock->lock, tranche->trancheId);
}
} }
} }
}
/*
* Register named tranches and tranches for fixed LWLocks.
*/
static void
RegisterLWLockTranches(void)
{
int i;
if (LWLockTrancheArray == NULL) if (LWLockTrancheArray == NULL)
{ {
LWLockTranchesAllocated = 16; LWLockTranchesAllocated = 32;
LWLockTrancheArray = (LWLockTranche **) LWLockTrancheArray = (LWLockTranche **)
MemoryContextAlloc(TopMemoryContext, MemoryContextAlloc(TopMemoryContext,
LWLockTranchesAllocated * sizeof(LWLockTranche *)); LWLockTranchesAllocated * sizeof(LWLockTranche *));
@ -492,6 +535,23 @@ CreateLWLocks(void)
MainLWLockTranche.array_stride = sizeof(LWLockPadded); MainLWLockTranche.array_stride = sizeof(LWLockPadded);
LWLockRegisterTranche(LWTRANCHE_MAIN, &MainLWLockTranche); LWLockRegisterTranche(LWTRANCHE_MAIN, &MainLWLockTranche);
BufMappingLWLockTranche.name = "buffer_mapping";
BufMappingLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS;
BufMappingLWLockTranche.array_stride = sizeof(LWLockPadded);
LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, &BufMappingLWLockTranche);
LockManagerLWLockTranche.name = "lock_manager";
LockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS +
NUM_BUFFER_PARTITIONS;
LockManagerLWLockTranche.array_stride = sizeof(LWLockPadded);
LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, &LockManagerLWLockTranche);
PredicateLockManagerLWLockTranche.name = "predicate_lock_manager";
PredicateLockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS +
NUM_BUFFER_PARTITIONS + NUM_LOCK_PARTITIONS;
PredicateLockManagerLWLockTranche.array_stride = sizeof(LWLockPadded);
LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER, &PredicateLockManagerLWLockTranche);
/* Register named tranches. */ /* Register named tranches. */
for (i = 0; i < NamedLWLockTrancheRequests; i++) for (i = 0; i < NamedLWLockTrancheRequests; i++)
LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId, LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId,

View File

@ -233,6 +233,9 @@ typedef enum BuiltinTrancheIds
LWTRANCHE_REPLICATION_ORIGIN, LWTRANCHE_REPLICATION_ORIGIN,
LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS, LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS,
LWTRANCHE_PROC, LWTRANCHE_PROC,
LWTRANCHE_BUFFER_MAPPING,
LWTRANCHE_LOCK_MANAGER,
LWTRANCHE_PREDICATE_LOCK_MANAGER,
LWTRANCHE_FIRST_USER_DEFINED LWTRANCHE_FIRST_USER_DEFINED
} BuiltinTrancheIds; } BuiltinTrancheIds;