From 981d045e8816f49672c4e1ad1fdc0535c7456c97 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Thu, 18 Jul 2002 23:06:20 +0000 Subject: [PATCH] Complete TODO item: * Merge LockMethodCtl and LockMethodTable into one shared structure (Bruce) --- src/backend/storage/lmgr/deadlock.c | 12 ++---- src/backend/storage/lmgr/lock.c | 65 +++++++++++++---------------- src/backend/storage/lmgr/proc.c | 14 +++---- src/include/storage/lock.h | 32 ++++---------- 4 files changed, 46 insertions(+), 77 deletions(-) diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index 213919cb57..147999dae6 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/deadlock.c,v 1.10 2002/06/20 20:29:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/deadlock.c,v 1.11 2002/07/18 23:06:19 momjian Exp $ * * Interface: * @@ -170,10 +170,6 @@ InitDeadLockChecking(void) * only look at regular locks. * * We must have already locked the master lock before being called. - * NOTE: although the lockctl structure appears to allow each lock - * table to have a different LWLock, all locks that can block had - * better use the same LWLock, else this code will not be adequately - * interlocked! */ bool DeadLockCheck(PGPROC *proc) @@ -384,7 +380,6 @@ FindLockCycleRecurse(PGPROC *checkProc, HOLDER *holder; SHM_QUEUE *lockHolders; LOCKMETHODTABLE *lockMethodTable; - LOCKMETHODCTL *lockctl; PROC_QUEUE *waitQueue; int queue_size; int conflictMask; @@ -423,9 +418,8 @@ FindLockCycleRecurse(PGPROC *checkProc, if (lock == NULL) return false; lockMethodTable = GetLocksMethodTable(lock); - lockctl = lockMethodTable->ctl; - numLockModes = lockctl->numLockModes; - conflictMask = lockctl->conflictTab[checkProc->waitLockMode]; + numLockModes = lockMethodTable->numLockModes; + conflictMask = lockMethodTable->conflictTab[checkProc->waitLockMode]; /* * Scan for procs that already hold conflicting locks. These are diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 5fd619d4f6..16bf0d627a 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.108 2002/06/20 20:29:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.109 2002/07/18 23:06:19 momjian Exp $ * * NOTES * Outside modules can create a lock table and acquire/release @@ -213,12 +213,12 @@ LockMethodInit(LOCKMETHODTABLE *lockMethodTable, { int i; - lockMethodTable->ctl->numLockModes = numModes; + lockMethodTable->numLockModes = numModes; numModes++; for (i = 0; i < numModes; i++, prioP++, conflictsP++) { - lockMethodTable->ctl->conflictTab[i] = *conflictsP; - lockMethodTable->ctl->prio[i] = *prioP; + lockMethodTable->conflictTab[i] = *conflictsP; + lockMethodTable->prio[i] = *prioP; } } @@ -263,24 +263,16 @@ LockMethodTableInit(char *tabName, /* each lock table has a non-shared, permanent header */ lockMethodTable = (LOCKMETHODTABLE *) - MemoryContextAlloc(TopMemoryContext, sizeof(LOCKMETHODTABLE)); + ShmemInitStruct(shmemName, sizeof(LOCKMETHODTABLE), &found); + + if (!lockMethodTable) + elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName); /* * Lock the LWLock for the table (probably not necessary here) */ LWLockAcquire(LockMgrLock, LW_EXCLUSIVE); - /* - * allocate a control structure from shared memory or attach to it if - * it already exists. - */ - sprintf(shmemName, "%s (ctl)", tabName); - lockMethodTable->ctl = (LOCKMETHODCTL *) - ShmemInitStruct(shmemName, sizeof(LOCKMETHODCTL), &found); - - if (!lockMethodTable->ctl) - elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName); - /* * no zero-th table */ @@ -291,9 +283,9 @@ LockMethodTableInit(char *tabName, */ if (!found) { - MemSet(lockMethodTable->ctl, 0, sizeof(LOCKMETHODCTL)); - lockMethodTable->ctl->masterLock = LockMgrLock; - lockMethodTable->ctl->lockmethod = NumLockMethods; + MemSet(lockMethodTable, 0, sizeof(LOCKMETHODTABLE)); + lockMethodTable->masterLock = LockMgrLock; + lockMethodTable->lockmethod = NumLockMethods; } /* @@ -342,14 +334,14 @@ LockMethodTableInit(char *tabName, if (!lockMethodTable->holderHash) elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName); - /* init ctl data structures */ + /* init data structures */ LockMethodInit(lockMethodTable, conflictsP, prioP, numModes); LWLockRelease(LockMgrLock); pfree(shmemName); - return lockMethodTable->ctl->lockmethod; + return lockMethodTable->lockmethod; } /* @@ -476,7 +468,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, return FALSE; } - masterLock = lockMethodTable->ctl->masterLock; + masterLock = lockMethodTable->masterLock; LWLockAcquire(masterLock, LW_EXCLUSIVE); @@ -576,7 +568,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, * XXX Doing numeric comparison on the lockmodes is a hack; it'd be * better to use a table. For now, though, this works. */ - for (i = lockMethodTable->ctl->numLockModes; i > 0; i--) + for (i = lockMethodTable->numLockModes; i > 0; i--) { if (holder->holding[i] > 0) { @@ -631,7 +623,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, * join wait queue. Otherwise, check for conflict with already-held * locks. (That's last because most complex check.) */ - if (lockMethodTable->ctl->conflictTab[lockmode] & lock->waitMask) + if (lockMethodTable->conflictTab[lockmode] & lock->waitMask) status = STATUS_FOUND; else status = LockCheckConflicts(lockMethodTable, lockmode, @@ -683,7 +675,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, int tmpMask; for (i = 1, tmpMask = 2; - i <= lockMethodTable->ctl->numLockModes; + i <= lockMethodTable->numLockModes; i++, tmpMask <<= 1) { if (myHolding[i] > 0) @@ -749,8 +741,7 @@ LockCheckConflicts(LOCKMETHODTABLE *lockMethodTable, PGPROC *proc, int *myHolding) /* myHolding[] array or NULL */ { - LOCKMETHODCTL *lockctl = lockMethodTable->ctl; - int numLockModes = lockctl->numLockModes; + int numLockModes = lockMethodTable->numLockModes; int bitmask; int i, tmpMask; @@ -765,7 +756,7 @@ LockCheckConflicts(LOCKMETHODTABLE *lockMethodTable, * each type of lock that conflicts with request. Bitwise compare * tells if there is a conflict. */ - if (!(lockctl->conflictTab[lockmode] & lock->grantMask)) + if (!(lockMethodTable->conflictTab[lockmode] & lock->grantMask)) { HOLDER_PRINT("LockCheckConflicts: no conflict", holder); return STATUS_OK; @@ -798,7 +789,7 @@ LockCheckConflicts(LOCKMETHODTABLE *lockMethodTable, * locks held by other processes. If one of these conflicts with the * kind of lock that I want, there is a conflict and I have to sleep. */ - if (!(lockctl->conflictTab[lockmode] & bitmask)) + if (!(lockMethodTable->conflictTab[lockmode] & bitmask)) { /* no conflict. OK to get the lock */ HOLDER_PRINT("LockCheckConflicts: resolved", holder); @@ -918,7 +909,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCKMODE lockmode, * needed, will happen in xact cleanup (see above for motivation). */ LOCK_PRINT("WaitOnLock: aborting on lock", lock, lockmode); - LWLockRelease(lockMethodTable->ctl->masterLock); + LWLockRelease(lockMethodTable->masterLock); elog(ERROR, "deadlock detected"); /* not reached */ } @@ -1014,7 +1005,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, return FALSE; } - masterLock = lockMethodTable->ctl->masterLock; + masterLock = lockMethodTable->masterLock; LWLockAcquire(masterLock, LW_EXCLUSIVE); /* @@ -1109,7 +1100,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, * granted locks might belong to some waiter, who could now be * awakened because he doesn't conflict with his own locks. */ - if (lockMethodTable->ctl->conflictTab[lockmode] & lock->waitMask) + if (lockMethodTable->conflictTab[lockmode] & lock->waitMask) wakeupNeeded = true; if (lock->nRequested == 0) @@ -1208,8 +1199,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, PGPROC *proc, return FALSE; } - numLockModes = lockMethodTable->ctl->numLockModes; - masterLock = lockMethodTable->ctl->masterLock; + numLockModes = lockMethodTable->numLockModes; + masterLock = lockMethodTable->masterLock; LWLockAcquire(masterLock, LW_EXCLUSIVE); @@ -1264,7 +1255,7 @@ LockReleaseAll(LOCKMETHOD lockmethod, PGPROC *proc, * Read comments in LockRelease */ if (!wakeupNeeded && - lockMethodTable->ctl->conflictTab[i] & lock->waitMask) + lockMethodTable->conflictTab[i] & lock->waitMask) wakeupNeeded = true; } } @@ -1355,8 +1346,8 @@ LockShmemSize(int maxBackends) size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */ size += maxBackends * MAXALIGN(sizeof(PGPROC)); /* each MyProc */ - size += MAX_LOCK_METHODS * MAXALIGN(sizeof(LOCKMETHODCTL)); /* each - * lockMethodTable->ctl */ + size += MAX_LOCK_METHODS * MAXALIGN(sizeof(LOCKMETHODTABLE)); /* each + * lockMethodTable */ /* lockHash table */ size += hash_estimate_size(max_table_size, sizeof(LOCK)); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 53dffec642..aa55bb1dc7 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.122 2002/07/13 01:02:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.123 2002/07/18 23:06:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -503,8 +503,7 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable, LOCK *lock, HOLDER *holder) { - LOCKMETHODCTL *lockctl = lockMethodTable->ctl; - LWLockId masterLock = lockctl->masterLock; + LWLockId masterLock = lockMethodTable->masterLock; PROC_QUEUE *waitQueue = &(lock->waitProcs); int myHeldLocks = MyProc->heldLocks; bool early_deadlock = false; @@ -537,10 +536,10 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable, for (i = 0; i < waitQueue->size; i++) { /* Must he wait for me? */ - if (lockctl->conflictTab[proc->waitLockMode] & myHeldLocks) + if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks) { /* Must I wait for him ? */ - if (lockctl->conflictTab[lockmode] & proc->heldLocks) + if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks) { /* * Yes, so we have a deadlock. Easiest way to clean @@ -553,7 +552,7 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable, break; } /* I must go before this waiter. Check special case. */ - if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 && + if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 && LockCheckConflicts(lockMethodTable, lockmode, lock, @@ -725,7 +724,6 @@ ProcWakeup(PGPROC *proc, int errType) void ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock) { - LOCKMETHODCTL *lockctl = lockMethodTable->ctl; PROC_QUEUE *waitQueue = &(lock->waitProcs); int queue_size = waitQueue->size; PGPROC *proc; @@ -746,7 +744,7 @@ ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock) * Waken if (a) doesn't conflict with requests of earlier waiters, * and (b) doesn't conflict with already-held locks. */ - if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 && + if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 && LockCheckConflicts(lockMethodTable, lockmode, lock, diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index e303da619c..1977cd7454 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lock.h,v 1.61 2002/06/20 20:29:52 momjian Exp $ + * $Id: lock.h,v 1.62 2002/07/18 23:06:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -62,17 +62,14 @@ typedef int LOCKMETHOD; * There is normally only one lock method, the default one. * If user locks are enabled, an additional lock method is present. * - * LOCKMETHODCTL and LOCKMETHODTABLE are split because the first lives - * in shared memory. (There isn't any really good reason for the split.) - * LOCKMETHODTABLE exists in private memory. Both are created by the - * postmaster and should be the same in all backends. - */ - -/* * This is the control structure for a lock table. It * lives in shared memory. This information is the same * for all backends. * + * lockHash -- hash table holding per-locked-object lock information + * + * holderHash -- hash table holding per-lock-holder lock information + * * lockmethod -- the handle used by the lock table's clients to * refer to the type of lock table being used. * @@ -88,28 +85,17 @@ typedef int LOCKMETHOD; * starvation). XXX this field is not actually used at present! * * masterLock -- synchronizes access to the table + * */ -typedef struct LOCKMETHODCTL +typedef struct LOCKMETHODTABLE { + HTAB *lockHash; + HTAB *holderHash; LOCKMETHOD lockmethod; int numLockModes; int conflictTab[MAX_LOCKMODES]; int prio[MAX_LOCKMODES]; LWLockId masterLock; -} LOCKMETHODCTL; - -/* - * Eack backend has a non-shared lock table header. - * - * lockHash -- hash table holding per-locked-object lock information - * holderHash -- hash table holding per-lock-holder lock information - * ctl - shared control structure described above. - */ -typedef struct LOCKMETHODTABLE -{ - HTAB *lockHash; - HTAB *holderHash; - LOCKMETHODCTL *ctl; } LOCKMETHODTABLE; -- 2.40.0