Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit119c23e

Browse files
Replace known_assigned_xids_lck with memory barriers.
This lock was introduced before memory barrier support was added,and it is only used to guarantee proper memory ordering whenKnownAssignedXidsAdd() appends to the array without a lock. Nowthat such memory barrier support exists, we can remove the lock anduse barriers instead.Suggested-by: Tom LaneAuthor: Michail NikolaevReviewed-by: Robert HaasDiscussion:https://postgr.es/m/CANtu0oh0si%3DjG5z_fLeFtmYcETssQ08kLEa8b6TQqDm_cinroA%40mail.gmail.com
1 parenta899d07 commit119c23e

File tree

1 file changed

+28
-48
lines changed

1 file changed

+28
-48
lines changed

‎src/backend/storage/ipc/procarray.c

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
#include"port/pg_lfind.h"
6262
#include"storage/proc.h"
6363
#include"storage/procarray.h"
64-
#include"storage/spin.h"
6564
#include"utils/acl.h"
6665
#include"utils/builtins.h"
6766
#include"utils/rel.h"
@@ -82,7 +81,6 @@ typedef struct ProcArrayStruct
8281
intnumKnownAssignedXids;/* current # of valid entries */
8382
inttailKnownAssignedXids;/* index of oldest valid element */
8483
intheadKnownAssignedXids;/* index of newest element, + 1 */
85-
slock_tknown_assigned_xids_lck;/* protects head/tail pointers */
8684

8785
/*
8886
* Highest subxid that has been removed from KnownAssignedXids array to
@@ -441,7 +439,6 @@ CreateSharedProcArray(void)
441439
procArray->numKnownAssignedXids=0;
442440
procArray->tailKnownAssignedXids=0;
443441
procArray->headKnownAssignedXids=0;
444-
SpinLockInit(&procArray->known_assigned_xids_lck);
445442
procArray->lastOverflowedXid=InvalidTransactionId;
446443
procArray->replication_slot_xmin=InvalidTransactionId;
447444
procArray->replication_slot_catalog_xmin=InvalidTransactionId;
@@ -4533,22 +4530,19 @@ KnownAssignedTransactionIdsIdleMaintenance(void)
45334530
* during normal running). Compressing unused entries out of the array
45344531
* likewise requires exclusive lock. To add XIDs to the array, we just insert
45354532
* them into slots to the right of the head pointer and then advance the head
4536-
* pointer. This wouldn't require any lock at all, except that on machines
4537-
* with weak memory ordering we need to be careful that other processors
4538-
* see the array element changes before they see the head pointer change.
4539-
* We handle this by using a spinlock to protect reads and writes of the
4540-
* head/tail pointers. (We could dispense with the spinlock if we were to
4541-
* create suitable memory access barrier primitives and use those instead.)
4542-
* The spinlock must be taken to read or write the head/tail pointers unless
4543-
* the caller holds ProcArrayLock exclusively.
4533+
* pointer. This doesn't require any lock at all, but on machines with weak
4534+
* memory ordering, we need to be careful that other processors see the array
4535+
* element changes before they see the head pointer change. We handle this by
4536+
* using memory barriers when reading or writing the head/tail pointers (unless
4537+
* the caller holds ProcArrayLock exclusively).
45444538
*
45454539
* Algorithmic analysis:
45464540
*
45474541
* If we have a maximum of M slots, with N XIDs currently spread across
45484542
* S elements then we have N <= S <= M always.
45494543
*
4550-
** Adding a new XID is O(1) and needslittle locking (unless compression
4551-
*musthappen)
4544+
** Adding a new XID is O(1) and needsno lock (unless compression must
4545+
*happen)
45524546
** Compressing the array is O(S) and requires exclusive lock
45534547
** Removing an XID is O(logS) and requires exclusive lock
45544548
** Taking a snapshot is O(S) and requires shared lock
@@ -4778,22 +4772,15 @@ KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid,
47784772
pArray->numKnownAssignedXids+=nxids;
47794773

47804774
/*
4781-
* Now update the head pointer. We use a spinlock to protect this
4782-
* pointer, not because the update is likely to be non-atomic, but to
4783-
* ensure that other processors see the above array updates before they
4784-
* see the head pointer change.
4785-
*
4786-
* If we're holding ProcArrayLock exclusively, there's no need to take the
4787-
* spinlock.
4775+
* Now update the head pointer. We use a write barrier to ensure that
4776+
* other processors see the above array updates before they see the head
4777+
* pointer change. The barrier isn't required if we're holding
4778+
* ProcArrayLock exclusively.
47884779
*/
4789-
if (exclusive_lock)
4790-
pArray->headKnownAssignedXids=head;
4791-
else
4792-
{
4793-
SpinLockAcquire(&pArray->known_assigned_xids_lck);
4794-
pArray->headKnownAssignedXids=head;
4795-
SpinLockRelease(&pArray->known_assigned_xids_lck);
4796-
}
4780+
if (!exclusive_lock)
4781+
pg_write_barrier();
4782+
4783+
pArray->headKnownAssignedXids=head;
47974784
}
47984785

47994786
/*
@@ -4815,20 +4802,15 @@ KnownAssignedXidsSearch(TransactionId xid, bool remove)
48154802
inttail;
48164803
intresult_index=-1;
48174804

4818-
if (remove)
4819-
{
4820-
/* we hold ProcArrayLock exclusively, so no need for spinlock */
4821-
tail=pArray->tailKnownAssignedXids;
4822-
head=pArray->headKnownAssignedXids;
4823-
}
4824-
else
4825-
{
4826-
/* take spinlock to ensure we see up-to-date array contents */
4827-
SpinLockAcquire(&pArray->known_assigned_xids_lck);
4828-
tail=pArray->tailKnownAssignedXids;
4829-
head=pArray->headKnownAssignedXids;
4830-
SpinLockRelease(&pArray->known_assigned_xids_lck);
4831-
}
4805+
tail=pArray->tailKnownAssignedXids;
4806+
head=pArray->headKnownAssignedXids;
4807+
4808+
/*
4809+
* Only the startup process removes entries, so we don't need the read
4810+
* barrier in that case.
4811+
*/
4812+
if (!remove)
4813+
pg_read_barrier();/* pairs with KnownAssignedXidsAdd */
48324814

48334815
/*
48344816
* Standard binary search. Note we can ignore the KnownAssignedXidsValid
@@ -5066,13 +5048,11 @@ KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin,
50665048
* cannot enter and then leave the array while we hold ProcArrayLock. We
50675049
* might miss newly-added xids, but they should be >= xmax so irrelevant
50685050
* anyway.
5069-
*
5070-
* Must take spinlock to ensure we see up-to-date array contents.
50715051
*/
5072-
SpinLockAcquire(&procArray->known_assigned_xids_lck);
50735052
tail=procArray->tailKnownAssignedXids;
50745053
head=procArray->headKnownAssignedXids;
5075-
SpinLockRelease(&procArray->known_assigned_xids_lck);
5054+
5055+
pg_read_barrier();/* pairs with KnownAssignedXidsAdd */
50765056

50775057
for (i=tail;i<head;i++)
50785058
{
@@ -5119,10 +5099,10 @@ KnownAssignedXidsGetOldestXmin(void)
51195099
/*
51205100
* Fetch head just once, since it may change while we loop.
51215101
*/
5122-
SpinLockAcquire(&procArray->known_assigned_xids_lck);
51235102
tail=procArray->tailKnownAssignedXids;
51245103
head=procArray->headKnownAssignedXids;
5125-
SpinLockRelease(&procArray->known_assigned_xids_lck);
5104+
5105+
pg_read_barrier();/* pairs with KnownAssignedXidsAdd */
51265106

51275107
for (i=tail;i<head;i++)
51285108
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp