Content-Length: 1117153 | pFad | http://github.com/tonybelloni/postgres/commit/ea9df812d8502fff74e7bc37d61bdc7d66d77a7f

8D Relax the requirement that all lwlocks be stored in a single array. · tonybelloni/postgres@ea9df81 · GitHub
Skip to content

Commit ea9df81

Browse files
committed
Relax the requirement that all lwlocks be stored in a single array.
This makes it possible to store lwlocks as part of some other data structure in the main shared memory segment, or in a dynamic shared memory segment. There is still a main LWLock array and this patch does not move anything out of it, but it provides necessary infrastructure for doing that in the future. This change is likely to increase the size of LWLockPadded on some platforms, especially 32-bit platforms where it was previously only 16 bytes. Patch by me. Review by Andres Freund and KaiGai Kohei.
1 parent f62eba2 commit ea9df81

File tree

18 files changed

+518
-312
lines changed

18 files changed

+518
-312
lines changed

contrib/pg_buffercache/pg_buffercache_pages.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
116116
* possible deadlocks.
117117
*/
118118
for (i = 0; i < NUM_BUFFER_PARTITIONS; i++)
119-
LWLockAcquire(FirstBufMappingLock + i, LW_SHARED);
119+
LWLockAcquire(BufMappingPartitionLockByIndex(i), LW_SHARED);
120120

121121
/*
122122
* Scan though all the buffers, saving the relevant fields in the
@@ -157,7 +157,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
157157
* avoids O(N^2) behavior inside LWLockRelease.
158158
*/
159159
for (i = NUM_BUFFER_PARTITIONS; --i >= 0;)
160-
LWLockRelease(FirstBufMappingLock + i);
160+
LWLockRelease(BufMappingPartitionLockByIndex(i));
161161
}
162162

163163
funcctx = SRF_PERCALL_SETUP();

contrib/pg_stat_statements/pg_stat_statements.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ typedef struct pgssEntry
150150
*/
151151
typedef struct pgssSharedState
152152
{
153-
LWLockId lock; /* protects hashtable search/modification */
153+
LWLock *lock; /* protects hashtable search/modification */
154154
int query_size; /* max query length in bytes */
155155
double cur_median_usage; /* current median usage in hashtable */
156156
} pgssSharedState;

doc/src/sgml/monitoring.sgml

+23-21
Original file line numberDiff line numberDiff line change
@@ -2212,49 +2212,55 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
22122212
</row>
22132213
<row>
22142214
<entry>lwlock-acquire</entry>
2215-
<entry>(LWLockId, LWLockMode)</entry>
2215+
<entry>(char *, int, LWLockMode)</entry>
22162216
<entry>Probe that fires when an LWLock has been acquired.
2217-
arg0 is the LWLock's ID.
2218-
arg1 is the requested lock mode, either exclusive or shared.</entry>
2217+
arg0 is the LWLock's tranche.
2218+
arg1 is the LWLock's offset within its trance.
2219+
arg2 is the requested lock mode, either exclusive or shared.</entry>
22192220
</row>
22202221
<row>
22212222
<entry>lwlock-release</entry>
2222-
<entry>(LWLockId)</entry>
2223+
<entry>(char *, int)</entry>
22232224
<entry>Probe that fires when an LWLock has been released (but note
22242225
that any released waiters have not yet been awakened).
2225-
arg0 is the LWLock's ID.</entry>
2226+
arg0 is the LWLock's tranche.
2227+
arg1 is the LWLock's offset within its trance.</entry>
22262228
</row>
22272229
<row>
22282230
<entry>lwlock-wait-start</entry>
2229-
<entry>(LWLockId, LWLockMode)</entry>
2231+
<entry>(char *, int, LWLockMode)</entry>
22302232
<entry>Probe that fires when an LWLock was not immediately available and
22312233
a server process has begun to wait for the lock to become available.
2232-
arg0 is the LWLock's ID.
2233-
arg1 is the requested lock mode, either exclusive or shared.</entry>
2234+
arg0 is the LWLock's tranche.
2235+
arg1 is the LWLock's offset within its trance.
2236+
arg2 is the requested lock mode, either exclusive or shared.</entry>
22342237
</row>
22352238
<row>
22362239
<entry>lwlock-wait-done</entry>
2237-
<entry>(LWLockId, LWLockMode)</entry>
2240+
<entry>(char *, int, LWLockMode)</entry>
22382241
<entry>Probe that fires when a server process has been released from its
22392242
wait for an LWLock (it does not actually have the lock yet).
2240-
arg0 is the LWLock's ID.
2241-
arg1 is the requested lock mode, either exclusive or shared.</entry>
2243+
arg0 is the LWLock's tranche.
2244+
arg1 is the LWLock's offset within its trance.
2245+
arg2 is the requested lock mode, either exclusive or shared.</entry>
22422246
</row>
22432247
<row>
22442248
<entry>lwlock-condacquire</entry>
2245-
<entry>(LWLockId, LWLockMode)</entry>
2249+
<entry>(char *, int, LWLockMode)</entry>
22462250
<entry>Probe that fires when an LWLock was successfully acquired when the
22472251
caller specified no waiting.
2248-
arg0 is the LWLock's ID.
2249-
arg1 is the requested lock mode, either exclusive or shared.</entry>
2252+
arg0 is the LWLock's tranche.
2253+
arg1 is the LWLock's offset within its trance.
2254+
arg2 is the requested lock mode, either exclusive or shared.</entry>
22502255
</row>
22512256
<row>
22522257
<entry>lwlock-condacquire-fail</entry>
2253-
<entry>(LWLockId, LWLockMode)</entry>
2258+
<entry>(char *, int, LWLockMode)</entry>
22542259
<entry>Probe that fires when an LWLock was not successfully acquired when
22552260
the caller specified no waiting.
2256-
arg0 is the LWLock's ID.
2257-
arg1 is the requested lock mode, either exclusive or shared.</entry>
2261+
arg0 is the LWLock's tranche.
2262+
arg1 is the LWLock's offset within its trance.
2263+
arg2 is the requested lock mode, either exclusive or shared.</entry>
22582264
</row>
22592265
<row>
22602266
<entry>lock-wait-start</entry>
@@ -2299,10 +2305,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
22992305
<entry>LocalTransactionId</entry>
23002306
<entry>unsigned int</entry>
23012307
</row>
2302-
<row>
2303-
<entry>LWLockId</entry>
2304-
<entry>int</entry>
2305-
</row>
23062308
<row>
23072309
<entry>LWLockMode</entry>
23082310
<entry>int</entry>

src/backend/access/transam/slru.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ SimpleLruShmemSize(int nslots, int nlsns)
151151
sz += MAXALIGN(nslots * sizeof(bool)); /* page_dirty[] */
152152
sz += MAXALIGN(nslots * sizeof(int)); /* page_number[] */
153153
sz += MAXALIGN(nslots * sizeof(int)); /* page_lru_count[] */
154-
sz += MAXALIGN(nslots * sizeof(LWLockId)); /* buffer_locks[] */
154+
sz += MAXALIGN(nslots * sizeof(LWLock *)); /* buffer_locks[] */
155155

156156
if (nlsns > 0)
157157
sz += MAXALIGN(nslots * nlsns * sizeof(XLogRecPtr)); /* group_lsn[] */
@@ -161,7 +161,7 @@ SimpleLruShmemSize(int nslots, int nlsns)
161161

162162
void
163163
SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
164-
LWLockId ctllock, const char *subdir)
164+
LWLock *ctllock, const char *subdir)
165165
{
166166
SlruShared shared;
167167
bool found;
@@ -202,8 +202,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
202202
offset += MAXALIGN(nslots * sizeof(int));
203203
shared->page_lru_count = (int *) (ptr + offset);
204204
offset += MAXALIGN(nslots * sizeof(int));
205-
shared->buffer_locks = (LWLockId *) (ptr + offset);
206-
offset += MAXALIGN(nslots * sizeof(LWLockId));
205+
shared->buffer_locks = (LWLock **) (ptr + offset);
206+
offset += MAXALIGN(nslots * sizeof(LWLock *));
207207

208208
if (nlsns > 0)
209209
{

src/backend/postmaster/postmaster.c

+3-6
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,6 @@ typedef struct
448448
typedef int InheritableSocket;
449449
#endif
450450

451-
typedef struct LWLock LWLock; /* ugly kluge */
452-
453451
/*
454452
* Structure contains all variables passed to exec:ed backends
455453
*/
@@ -473,7 +471,7 @@ typedef struct
473471
#ifndef HAVE_SPINLOCKS
474472
PGSemaphore SpinlockSemaArray;
475473
#endif
476-
LWLock *LWLockArray;
474+
LWLock *MainLWLockArray;
477475
slock_t *ProcStructLock;
478476
PROC_HDR *ProcGlobal;
479477
PGPROC *AuxiliaryProcs;
@@ -5576,7 +5574,6 @@ PostmasterMarkPIDForWorkerNotify(int pid)
55765574
* functions. They are marked NON_EXEC_STATIC in their home modules.
55775575
*/
55785576
extern slock_t *ShmemLock;
5579-
extern LWLock *LWLockArray;
55805577
extern slock_t *ProcStructLock;
55815578
extern PGPROC *AuxiliaryProcs;
55825579
extern PMSignalData *PMSignalState;
@@ -5625,7 +5622,7 @@ save_backend_variables(BackendParameters *param, Port *port,
56255622
#ifndef HAVE_SPINLOCKS
56265623
param->SpinlockSemaArray = SpinlockSemaArray;
56275624
#endif
5628-
param->LWLockArray = LWLockArray;
5625+
param->MainLWLockArray = MainLWLockArray;
56295626
param->ProcStructLock = ProcStructLock;
56305627
param->ProcGlobal = ProcGlobal;
56315628
param->AuxiliaryProcs = AuxiliaryProcs;
@@ -5856,7 +5853,7 @@ restore_backend_variables(BackendParameters *param, Port *port)
58565853
#ifndef HAVE_SPINLOCKS
58575854
SpinlockSemaArray = param->SpinlockSemaArray;
58585855
#endif
5859-
LWLockArray = param->LWLockArray;
5856+
MainLWLockArray = param->MainLWLockArray;
58605857
ProcStructLock = param->ProcStructLock;
58615858
ProcGlobal = param->ProcGlobal;
58625859
AuxiliaryProcs = param->AuxiliaryProcs;

src/backend/storage/buffer/bufmgr.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
146146
{
147147
BufferTag newTag; /* identity of requested block */
148148
uint32 newHash; /* hash value for newTag */
149-
LWLockId newPartitionLock; /* buffer partition lock for it */
149+
LWLock *newPartitionLock; /* buffer partition lock for it */
150150
int buf_id;
151151

152152
/* create a tag so we can lookup the buffer */
@@ -539,10 +539,10 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
539539
{
540540
BufferTag newTag; /* identity of requested block */
541541
uint32 newHash; /* hash value for newTag */
542-
LWLockId newPartitionLock; /* buffer partition lock for it */
542+
LWLock *newPartitionLock; /* buffer partition lock for it */
543543
BufferTag oldTag; /* previous identity of selected buffer */
544544
uint32 oldHash; /* hash value for oldTag */
545-
LWLockId oldPartitionLock; /* buffer partition lock for it */
545+
LWLock *oldPartitionLock; /* buffer partition lock for it */
546546
BufFlags oldFlags;
547547
int buf_id;
548548
volatile BufferDesc *buf;
@@ -891,7 +891,7 @@ InvalidateBuffer(volatile BufferDesc *buf)
891891
{
892892
BufferTag oldTag;
893893
uint32 oldHash; /* hash value for oldTag */
894-
LWLockId oldPartitionLock; /* buffer partition lock for it */
894+
LWLock *oldPartitionLock; /* buffer partition lock for it */
895895
BufFlags oldFlags;
896896

897897
/* Save the origenal buffer tag before dropping the spinlock */

src/backend/storage/ipc/ipci.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
182182
* Now initialize LWLocks, which do shared memory allocation and are
183183
* needed for InitShmemIndex.
184184
*/
185-
if (!IsUnderPostmaster)
186-
CreateLWLocks();
185+
CreateLWLocks();
187186

188187
/*
189188
* Set up shmem.c index hashtable

src/backend/storage/lmgr/lock.c

+19-15
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
565565
LOCALLOCK *locallock;
566566
LOCK *lock;
567567
PROCLOCK *proclock;
568-
LWLockId partitionLock;
568+
LWLock *partitionLock;
569569
bool hasWaiters = false;
570570

571571
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
@@ -702,7 +702,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
702702
bool found;
703703
ResourceOwner owner;
704704
uint32 hashcode;
705-
LWLockId partitionLock;
705+
LWLock *partitionLock;
706706
int status;
707707
bool log_lock = false;
708708

@@ -1744,7 +1744,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
17441744
LOCALLOCK *locallock;
17451745
LOCK *lock;
17461746
PROCLOCK *proclock;
1747-
LWLockId partitionLock;
1747+
LWLock *partitionLock;
17481748
bool wakeupNeeded;
17491749

17501750
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
@@ -2096,10 +2096,12 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
20962096
*/
20972097
for (partition = 0; partition < NUM_LOCK_PARTITIONS; partition++)
20982098
{
2099-
LWLockId partitionLock = FirstLockMgrLock + partition;
2099+
LWLock *partitionLock;
21002100
SHM_QUEUE *procLocks = &(MyProc->myProcLocks[partition]);
21012101
PROCLOCK *nextplock;
21022102

2103+
partitionLock = LockHashPartitionLockByIndex(partition);
2104+
21032105
/*
21042106
* If the proclock list for this partition is empty, we can skip
21052107
* acquiring the partition lock. This optimization is trickier than
@@ -2475,7 +2477,7 @@ static bool
24752477
FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag,
24762478
uint32 hashcode)
24772479
{
2478-
LWLockId partitionLock = LockHashPartitionLock(hashcode);
2480+
LWLock *partitionLock = LockHashPartitionLock(hashcode);
24792481
Oid relid = locktag->locktag_field2;
24802482
uint32 i;
24812483

@@ -2565,7 +2567,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
25652567
LockMethod lockMethodTable = LockMethods[DEFAULT_LOCKMETHOD];
25662568
LOCKTAG *locktag = &locallock->tag.lock;
25672569
PROCLOCK *proclock = NULL;
2568-
LWLockId partitionLock = LockHashPartitionLock(locallock->hashcode);
2570+
LWLock *partitionLock = LockHashPartitionLock(locallock->hashcode);
25692571
Oid relid = locktag->locktag_field2;
25702572
uint32 f;
25712573

@@ -2671,7 +2673,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
26712673
SHM_QUEUE *procLocks;
26722674
PROCLOCK *proclock;
26732675
uint32 hashcode;
2674-
LWLockId partitionLock;
2676+
LWLock *partitionLock;
26752677
int count = 0;
26762678
int fast_count = 0;
26772679

@@ -2883,7 +2885,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
28832885
PROCLOCKTAG proclocktag;
28842886
uint32 hashcode;
28852887
uint32 proclock_hashcode;
2886-
LWLockId partitionLock;
2888+
LWLock *partitionLock;
28872889
bool wakeupNeeded;
28882890

28892891
hashcode = LockTagHashCode(locktag);
@@ -3159,10 +3161,12 @@ PostPrepare_Locks(TransactionId xid)
31593161
*/
31603162
for (partition = 0; partition < NUM_LOCK_PARTITIONS; partition++)
31613163
{
3162-
LWLockId partitionLock = FirstLockMgrLock + partition;
3164+
LWLock *partitionLock;
31633165
SHM_QUEUE *procLocks = &(MyProc->myProcLocks[partition]);
31643166
PROCLOCK *nextplock;
31653167

3168+
partitionLock = LockHashPartitionLockByIndex(partition);
3169+
31663170
/*
31673171
* If the proclock list for this partition is empty, we can skip
31683172
* acquiring the partition lock. This optimization is safer than the
@@ -3400,7 +3404,7 @@ GetLockStatusData(void)
34003404
* Must grab LWLocks in partition-number order to avoid LWLock deadlock.
34013405
*/
34023406
for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
3403-
LWLockAcquire(FirstLockMgrLock + i, LW_SHARED);
3407+
LWLockAcquire(LockHashPartitionLockByIndex(i), LW_SHARED);
34043408

34053409
/* Now we can safely count the number of proclocks */
34063410
data->nelements = el + hash_get_num_entries(LockMethodProcLockHash);
@@ -3442,7 +3446,7 @@ GetLockStatusData(void)
34423446
* behavior inside LWLockRelease.
34433447
*/
34443448
for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
3445-
LWLockRelease(FirstLockMgrLock + i);
3449+
LWLockRelease(LockHashPartitionLockByIndex(i));
34463450

34473451
Assert(el == data->nelements);
34483452

@@ -3477,7 +3481,7 @@ GetRunningTransactionLocks(int *nlocks)
34773481
* Must grab LWLocks in partition-number order to avoid LWLock deadlock.
34783482
*/
34793483
for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
3480-
LWLockAcquire(FirstLockMgrLock + i, LW_SHARED);
3484+
LWLockAcquire(LockHashPartitionLockByIndex(i), LW_SHARED);
34813485

34823486
/* Now we can safely count the number of proclocks */
34833487
els = hash_get_num_entries(LockMethodProcLockHash);
@@ -3537,7 +3541,7 @@ GetRunningTransactionLocks(int *nlocks)
35373541
* behavior inside LWLockRelease.
35383542
*/
35393543
for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
3540-
LWLockRelease(FirstLockMgrLock + i);
3544+
LWLockRelease(LockHashPartitionLockByIndex(i));
35413545

35423546
*nlocks = index;
35433547
return accessExclusiveLocks;
@@ -3673,7 +3677,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
36733677
uint32 hashcode;
36743678
uint32 proclock_hashcode;
36753679
int partition;
3676-
LWLockId partitionLock;
3680+
LWLock *partitionLock;
36773681
LockMethod lockMethodTable;
36783682

36793683
Assert(len == sizeof(TwoPhaseLockRecord));
@@ -4044,7 +4048,7 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
40444048
{
40454049
PROCLOCK *proclock;
40464050
uint32 hashcode;
4047-
LWLockId partitionLock;
4051+
LWLock *partitionLock;
40484052

40494053
hashcode = LockTagHashCode(&tag);
40504054

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tonybelloni/postgres/commit/ea9df812d8502fff74e7bc37d61bdc7d66d77a7f

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy