lwshared2.patch
application/octet-stream
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/twophase.c | 1 | 1 |
| src/backend/storage/ipc/procarray.c | 1 | 1 |
| src/backend/storage/lmgr/lwlock.c | 54 | 22 |
| src/backend/storage/lmgr/proc.c | 2 | 2 |
| src/include/storage/lwlock.h | 2 | 1 |
| src/include/storage/proc.h | 1 | 1 |
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 477982d..a555c91 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -319,7 +319,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
gxact->proc.inCommit = false;
gxact->proc.vacuumFlags = 0;
gxact->proc.lwWaiting = false;
- gxact->proc.lwExclusive = false;
+ gxact->proc.lwMode = LW_SHARED;
gxact->proc.lwWaitLink = NULL;
gxact->proc.waitLock = NULL;
gxact->proc.waitProcLock = NULL;
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 1a48485..5b60029 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -359,7 +359,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
*/
Assert(TransactionIdIsValid(proc->xid));
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ LWLockAcquire(ProcArrayLock, LW_SHARED2);
proc->xid = InvalidTransactionId;
proc->lxid = InvalidLocalTransactionId;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 079eb29..8658c83 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -32,6 +32,7 @@
#include "storage/proc.h"
#include "storage/spin.h"
+#define LWLOCK_STATS 1
/* We use the ShmemLock spinlock to protect LWLockAssign */
extern slock_t *ShmemLock;
@@ -42,7 +43,8 @@ typedef struct LWLock
slock_t mutex; /* Protects LWLock and queue of PGPROCs */
bool releaseOK; /* T if ok to release waiters */
char exclusive; /* # of exclusive holders (0 or 1) */
- int shared; /* # of shared holders (0..MaxBackends) */
+ int shared1; /* # of shared1 holders (0..MaxBackends) */
+ int shared2; /* # of shared2 holders (0..MaxBackends) */
PGPROC *head; /* head of list of waiting PGPROCs */
PGPROC *tail; /* tail of list of waiting PGPROCs */
/* tail is undefined when head is NULL */
@@ -92,7 +94,8 @@ static bool lock_addin_request_allowed = true;
#ifdef LWLOCK_STATS
static int counts_for_pid = 0;
-static int *sh_acquire_counts;
+static int *sh1_acquire_counts;
+static int *sh2_acquire_counts;
static int *ex_acquire_counts;
static int *block_counts;
#endif
@@ -104,9 +107,9 @@ inline static void
PRINT_LWDEBUG(const char *where, LWLockId lockid, const volatile LWLock *lock)
{
if (Trace_lwlocks)
- elog(LOG, "%s(%d): excl %d shared %d head %p rOK %d",
+ elog(LOG, "%s(%d): excl %d shared1 %d shared2 %d head %p rOK %d",
where, (int) lockid,
- (int) lock->exclusive, lock->shared, lock->head,
+ (int) lock->exclusive, lock->shared1, lock->shared2, lock->head,
(int) lock->releaseOK);
}
@@ -135,9 +138,9 @@ print_lwlock_stats(int code, Datum arg)
for (i = 0; i < numLocks; i++)
{
- if (sh_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i])
- fprintf(stderr, "PID %d lwlock %d: shacq %u exacq %u blk %u\n",
- MyProcPid, i, sh_acquire_counts[i], ex_acquire_counts[i],
+ if (sh1_acquire_counts[i] || sh2_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i])
+ fprintf(stderr, "PID %d lwlock %d: shacq1 %u shacq2 %u exacq %u blk %u\n",
+ MyProcPid, i, sh1_acquire_counts[i], sh2_acquire_counts[i], ex_acquire_counts[i],
block_counts[i]);
}
@@ -268,7 +271,8 @@ CreateLWLocks(void)
SpinLockInit(&lock->lock.mutex);
lock->lock.releaseOK = true;
lock->lock.exclusive = 0;
- lock->lock.shared = 0;
+ lock->lock.shared1 = 0;
+ lock->lock.shared2 = 0;
lock->lock.head = NULL;
lock->lock.tail = NULL;
}
@@ -336,7 +340,8 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
int *LWLockCounter = (int *) ((char *) LWLockArray - 2 * sizeof(int));
int numLocks = LWLockCounter[1];
- sh_acquire_counts = calloc(numLocks, sizeof(int));
+ sh1_acquire_counts = calloc(numLocks, sizeof(int));
+ sh2_acquire_counts = calloc(numLocks, sizeof(int));
ex_acquire_counts = calloc(numLocks, sizeof(int));
block_counts = calloc(numLocks, sizeof(int));
counts_for_pid = MyProcPid;
@@ -345,8 +350,10 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
/* Count lock acquisition attempts */
if (mode == LW_EXCLUSIVE)
ex_acquire_counts[lockid]++;
+ else if (mode == LW_SHARED)
+ sh1_acquire_counts[lockid]++;
else
- sh_acquire_counts[lockid]++;
+ sh2_acquire_counts[lockid]++;
#endif /* LWLOCK_STATS */
/*
@@ -397,7 +404,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
/* If I can get the lock, do so quickly. */
if (mode == LW_EXCLUSIVE)
{
- if (lock->exclusive == 0 && lock->shared == 0)
+ if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0)
{
lock->exclusive++;
mustwait = false;
@@ -405,11 +412,21 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
else
mustwait = true;
}
+ else if (mode == LW_SHARED)
+ {
+ if (lock->exclusive == 0 && lock->shared2 == 0)
+ {
+ lock->shared1++;
+ mustwait = false;
+ }
+ else
+ mustwait = true;
+ }
else
{
- if (lock->exclusive == 0)
+ if (lock->exclusive == 0 && lock->shared1 == 0)
{
- lock->shared++;
+ lock->shared2++;
mustwait = false;
}
else
@@ -430,7 +447,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
elog(PANIC, "cannot wait without a PGPROC structure");
proc->lwWaiting = true;
- proc->lwExclusive = (mode == LW_EXCLUSIVE);
+ proc->lwMode = mode;
proc->lwWaitLink = NULL;
if (lock->head == NULL)
lock->head = proc;
@@ -525,7 +542,7 @@ LWLockConditionalAcquire(LWLockId lockid, LWLockMode mode)
/* If I can get the lock, do so quickly. */
if (mode == LW_EXCLUSIVE)
{
- if (lock->exclusive == 0 && lock->shared == 0)
+ if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0)
{
lock->exclusive++;
mustwait = false;
@@ -533,11 +550,21 @@ LWLockConditionalAcquire(LWLockId lockid, LWLockMode mode)
else
mustwait = true;
}
+ else if (mode == LW_SHARED)
+ {
+ if (lock->exclusive == 0 && lock->shared2 == 0)
+ {
+ lock->shared1++;
+ mustwait = false;
+ }
+ else
+ mustwait = true;
+ }
else
{
- if (lock->exclusive == 0)
+ if (lock->exclusive == 0 && lock->shared1 == 0)
{
- lock->shared++;
+ lock->shared2++;
mustwait = false;
}
else
@@ -598,10 +625,12 @@ LWLockRelease(LWLockId lockid)
/* Release my hold on lock */
if (lock->exclusive > 0)
lock->exclusive--;
+ else if (lock->shared1 > 0)
+ lock->shared1--;
else
{
- Assert(lock->shared > 0);
- lock->shared--;
+ Assert(lock->shared2 > 0);
+ lock->shared2--;
}
/*
@@ -613,7 +642,8 @@ LWLockRelease(LWLockId lockid)
head = lock->head;
if (head != NULL)
{
- if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK)
+ if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0
+ && lock->releaseOK)
{
/*
* Remove the to-be-awakened PGPROCs from the queue. If the front
@@ -621,10 +651,12 @@ LWLockRelease(LWLockId lockid)
* as many waiters as want shared access.
*/
proc = head;
- if (!proc->lwExclusive)
+ if (proc->lwMode != LW_EXCLUSIVE)
{
+ LWLockMode wake_mode = proc->lwMode;
+
while (proc->lwWaitLink != NULL &&
- !proc->lwWaitLink->lwExclusive)
+ proc->lwWaitLink->lwMode == wake_mode)
proc = proc->lwWaitLink;
}
/* proc is now the last PGPROC to be released */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index eda3a98..be48a47 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -326,7 +326,7 @@ InitProcess(void)
if (IsAutoVacuumWorkerProcess())
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
MyProc->lwWaiting = false;
- MyProc->lwExclusive = false;
+ MyProc->lwMode = LW_SHARED;
MyProc->lwWaitLink = NULL;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
@@ -480,7 +480,7 @@ InitAuxiliaryProcess(void)
MyProc->inCommit = false;
MyProc->vacuumFlags = 0;
MyProc->lwWaiting = false;
- MyProc->lwExclusive = false;
+ MyProc->lwMode = LW_SHARED;
MyProc->lwWaitLink = NULL;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 438a48d..3b1c1c0 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -94,7 +94,8 @@ typedef enum LWLockId
typedef enum LWLockMode
{
LW_EXCLUSIVE,
- LW_SHARED
+ LW_SHARED,
+ LW_SHARED2
} LWLockMode;
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 6e798b1..d4220a7 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -116,7 +116,7 @@ struct PGPROC
/* Info about LWLock the process is currently waiting for, if any. */
bool lwWaiting; /* true if waiting for an LW lock */
- bool lwExclusive; /* true if waiting for exclusive access */
+ LWLockMode lwMode; /* mode we're waiting for */
struct PGPROC *lwWaitLink; /* next waiter for same LW lock */
/* Info about lock the process is currently waiting for, if any. */