Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5764f61

Browse files
committed
Use dlist/dclist instead of PROC_QUEUE / SHM_QUEUE for heavyweight locks
Part of a series to remove SHM_QUEUE. ilist.h style lists are more widely used and have an easier to use interface. As PROC_QUEUE is now unused, remove it. Reviewed-by: Thomas Munro <thomas.munro@gmail.com> (in an older version) Discussion: https://postgr.es/m/20221120055930.t6kl3tyivzhlrzu2@awork3.anarazel.de Discussion: https://postgr.es/m/20200211042229.msv23badgqljrdg2@alap3.anarazel.de
1 parent 51384cc commit 5764f61

File tree

7 files changed

+183
-339
lines changed

7 files changed

+183
-339
lines changed

src/backend/access/transam/twophase.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
461461
/* Initialize the PGPROC entry */
462462
MemSet(proc, 0, sizeof(PGPROC));
463463
proc->pgprocno = gxact->pgprocno;
464-
SHMQueueElemInit(&(proc->links));
464+
dlist_node_init(&proc->links);
465465
proc->waitStatus = PROC_WAIT_STATUS_OK;
466466
if (LocalTransactionIdIsValid(MyProc->lxid))
467467
{
@@ -491,7 +491,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
491491
proc->waitProcLock = NULL;
492492
pg_atomic_init_u64(&proc->waitStart, 0);
493493
for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
494-
SHMQueueInit(&(proc->myProcLocks[i]));
494+
dlist_init(&proc->myProcLocks[i]);
495495
/* subxid data must be filled later by GXactLoadSubxactData */
496496
proc->subxidStatus.overflowed = false;
497497
proc->subxidStatus.count = 0;

src/backend/storage/lmgr/deadlock.c

+35-52
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,6 @@ InitDeadLockChecking(void)
216216
DeadLockState
217217
DeadLockCheck(PGPROC *proc)
218218
{
219-
int i,
220-
j;
221-
222219
/* Initialize to "no constraints" */
223220
nCurConstraints = 0;
224221
nPossibleConstraints = 0;
@@ -246,26 +243,23 @@ DeadLockCheck(PGPROC *proc)
246243
}
247244

248245
/* Apply any needed rearrangements of wait queues */
249-
for (i = 0; i < nWaitOrders; i++)
246+
for (int i = 0; i < nWaitOrders; i++)
250247
{
251248
LOCK *lock = waitOrders[i].lock;
252249
PGPROC **procs = waitOrders[i].procs;
253250
int nProcs = waitOrders[i].nProcs;
254-
PROC_QUEUE *waitQueue = &(lock->waitProcs);
251+
dclist_head *waitQueue = &lock->waitProcs;
255252

256-
Assert(nProcs == waitQueue->size);
253+
Assert(nProcs == dclist_count(waitQueue));
257254

258255
#ifdef DEBUG_DEADLOCK
259256
PrintLockQueue(lock, "DeadLockCheck:");
260257
#endif
261258

262259
/* Reset the queue and re-add procs in the desired order */
263-
ProcQueueInit(waitQueue);
264-
for (j = 0; j < nProcs; j++)
265-
{
266-
SHMQueueInsertBefore(&(waitQueue->links), &(procs[j]->links));
267-
waitQueue->size++;
268-
}
260+
dclist_init(waitQueue);
261+
for (int j = 0; j < nProcs; j++)
262+
dclist_push_tail(waitQueue, &procs[j]->links);
269263

270264
#ifdef DEBUG_DEADLOCK
271265
PrintLockQueue(lock, "rearranged to:");
@@ -544,11 +538,8 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
544538
{
545539
PGPROC *proc;
546540
LOCK *lock = checkProc->waitLock;
547-
PROCLOCK *proclock;
548-
SHM_QUEUE *procLocks;
541+
dlist_iter proclock_iter;
549542
LockMethod lockMethodTable;
550-
PROC_QUEUE *waitQueue;
551-
int queue_size;
552543
int conflictMask;
553544
int i;
554545
int numLockModes,
@@ -571,13 +562,9 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
571562
* Scan for procs that already hold conflicting locks. These are "hard"
572563
* edges in the waits-for graph.
573564
*/
574-
procLocks = &(lock->procLocks);
575-
576-
proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
577-
offsetof(PROCLOCK, lockLink));
578-
579-
while (proclock)
565+
dlist_foreach(proclock_iter, &lock->procLocks)
580566
{
567+
PROCLOCK *proclock = dlist_container(PROCLOCK, lockLink, proclock_iter.cur);
581568
PGPROC *leader;
582569

583570
proc = proclock->tag.myProc;
@@ -636,9 +623,6 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
636623
}
637624
}
638625
}
639-
640-
proclock = (PROCLOCK *) SHMQueueNext(procLocks, &proclock->lockLink,
641-
offsetof(PROCLOCK, lockLink));
642626
}
643627

644628
/*
@@ -660,8 +644,7 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
660644
{
661645
/* Use the given hypothetical wait queue order */
662646
PGPROC **procs = waitOrders[i].procs;
663-
664-
queue_size = waitOrders[i].nProcs;
647+
int queue_size = waitOrders[i].nProcs;
665648

666649
for (i = 0; i < queue_size; i++)
667650
{
@@ -711,9 +694,11 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
711694
else
712695
{
713696
PGPROC *lastGroupMember = NULL;
697+
dlist_iter proc_iter;
698+
dclist_head *waitQueue;
714699

715700
/* Use the true lock wait queue order */
716-
waitQueue = &(lock->waitProcs);
701+
waitQueue = &lock->waitProcs;
717702

718703
/*
719704
* Find the last member of the lock group that is present in the wait
@@ -726,26 +711,25 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
726711
lastGroupMember = checkProc;
727712
else
728713
{
729-
proc = (PGPROC *) waitQueue->links.next;
730-
queue_size = waitQueue->size;
731-
while (queue_size-- > 0)
714+
dclist_foreach(proc_iter, waitQueue)
732715
{
716+
proc = dlist_container(PGPROC, links, proc_iter.cur);
717+
733718
if (proc->lockGroupLeader == checkProcLeader)
734719
lastGroupMember = proc;
735-
proc = (PGPROC *) proc->links.next;
736720
}
737721
Assert(lastGroupMember != NULL);
738722
}
739723

740724
/*
741725
* OK, now rescan (or scan) the queue to identify the soft conflicts.
742726
*/
743-
queue_size = waitQueue->size;
744-
proc = (PGPROC *) waitQueue->links.next;
745-
while (queue_size-- > 0)
727+
dclist_foreach(proc_iter, waitQueue)
746728
{
747729
PGPROC *leader;
748730

731+
proc = dlist_container(PGPROC, links, proc_iter.cur);
732+
749733
leader = proc->lockGroupLeader == NULL ? proc :
750734
proc->lockGroupLeader;
751735

@@ -779,8 +763,6 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
779763
return true;
780764
}
781765
}
782-
783-
proc = (PGPROC *) proc->links.next;
784766
}
785767
}
786768

@@ -832,8 +814,8 @@ ExpandConstraints(EDGE *constraints,
832814
/* No, so allocate a new list */
833815
waitOrders[nWaitOrders].lock = lock;
834816
waitOrders[nWaitOrders].procs = waitOrderProcs + nWaitOrderProcs;
835-
waitOrders[nWaitOrders].nProcs = lock->waitProcs.size;
836-
nWaitOrderProcs += lock->waitProcs.size;
817+
waitOrders[nWaitOrders].nProcs = dclist_count(&lock->waitProcs);
818+
nWaitOrderProcs += dclist_count(&lock->waitProcs);
837819
Assert(nWaitOrderProcs <= MaxBackends);
838820

839821
/*
@@ -880,23 +862,25 @@ TopoSort(LOCK *lock,
880862
int nConstraints,
881863
PGPROC **ordering) /* output argument */
882864
{
883-
PROC_QUEUE *waitQueue = &(lock->waitProcs);
884-
int queue_size = waitQueue->size;
865+
dclist_head *waitQueue = &lock->waitProcs;
866+
int queue_size = dclist_count(waitQueue);
885867
PGPROC *proc;
886868
int i,
887869
j,
888870
jj,
889871
k,
890872
kk,
891873
last;
874+
dlist_iter proc_iter;
892875

893876
/* First, fill topoProcs[] array with the procs in their current order */
894-
proc = (PGPROC *) waitQueue->links.next;
895-
for (i = 0; i < queue_size; i++)
877+
i = 0;
878+
dclist_foreach(proc_iter, waitQueue)
896879
{
897-
topoProcs[i] = proc;
898-
proc = (PGPROC *) proc->links.next;
880+
proc = dlist_container(PGPROC, links, proc_iter.cur);
881+
topoProcs[i++] = proc;
899882
}
883+
Assert(i == queue_size);
900884

901885
/*
902886
* Scan the constraints, and for each proc in the array, generate a count
@@ -1066,17 +1050,16 @@ TopoSort(LOCK *lock,
10661050
static void
10671051
PrintLockQueue(LOCK *lock, const char *info)
10681052
{
1069-
PROC_QUEUE *waitQueue = &(lock->waitProcs);
1070-
int queue_size = waitQueue->size;
1071-
PGPROC *proc;
1072-
int i;
1053+
dclist_head *waitQueue = &lock->waitProcs;
1054+
dlist_iter proc_iter;
10731055

10741056
printf("%s lock %p queue ", info, lock);
1075-
proc = (PGPROC *) waitQueue->links.next;
1076-
for (i = 0; i < queue_size; i++)
1057+
1058+
dclist_foreach(proc_iter, waitQueue)
10771059
{
1060+
PGPROC *proc = dlist_container(PGPROC, links, proc_iter.cur);
1061+
10781062
printf(" %d", proc->pid);
1079-
proc = (PGPROC *) proc->links.next;
10801063
}
10811064
printf("\n");
10821065
fflush(stdout);

0 commit comments

Comments
 (0)