mirror of
https://github.com/postgres/postgres.git
synced 2025-06-22 02:52:08 +03:00
Rename locking structure names to be clearer. Add narrative to
backend flowchart.
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.31 1998/06/28 21:17:34 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.32 1998/06/30 02:33:31 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Outside modules can create a lock table and acquire/release
|
* Outside modules can create a lock table and acquire/release
|
||||||
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
* Interface:
|
* Interface:
|
||||||
*
|
*
|
||||||
* LockAcquire(), LockRelease(), LockTableInit().
|
* LockAcquire(), LockRelease(), LockMethodTableInit().
|
||||||
*
|
*
|
||||||
* LockReplace() is called only within this module and by the
|
* LockReplace() is called only within this module and by the
|
||||||
* lkchain module. It releases a lock without looking
|
* lkchain module. It releases a lock without looking
|
||||||
@ -51,8 +51,7 @@
|
|||||||
#include "access/transam.h"
|
#include "access/transam.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock,
|
WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode);
|
||||||
LOCKTYPE locktype);
|
|
||||||
|
|
||||||
/*#define LOCK_MGR_DEBUG*/
|
/*#define LOCK_MGR_DEBUG*/
|
||||||
|
|
||||||
@ -134,8 +133,8 @@ SPINLOCK LockMgrLock; /* in Shmem or created in
|
|||||||
|
|
||||||
/* This is to simplify/speed up some bit arithmetic */
|
/* This is to simplify/speed up some bit arithmetic */
|
||||||
|
|
||||||
static MASK BITS_OFF[MAX_LOCKTYPES];
|
static MASK BITS_OFF[MAX_LOCKMODES];
|
||||||
static MASK BITS_ON[MAX_LOCKTYPES];
|
static MASK BITS_ON[MAX_LOCKMODES];
|
||||||
|
|
||||||
/* -----------------
|
/* -----------------
|
||||||
* XXX Want to move this to this file
|
* XXX Want to move this to this file
|
||||||
@ -144,16 +143,12 @@ static MASK BITS_ON[MAX_LOCKTYPES];
|
|||||||
static bool LockingIsDisabled;
|
static bool LockingIsDisabled;
|
||||||
|
|
||||||
/* -------------------
|
/* -------------------
|
||||||
* map from tableId to the lock table structure
|
* map from lockmethod to the lock table structure
|
||||||
* -------------------
|
* -------------------
|
||||||
*/
|
*/
|
||||||
static LOCKTAB *AllTables[MAX_TABLES];
|
static LOCKMETHODTABLE *LockMethodTable[MAX_LOCK_METHODS];
|
||||||
|
|
||||||
/* -------------------
|
static int NumLockMethods;
|
||||||
* no zero-th table
|
|
||||||
* -------------------
|
|
||||||
*/
|
|
||||||
static int NumTables;
|
|
||||||
|
|
||||||
/* -------------------
|
/* -------------------
|
||||||
* InitLocks -- Init the lock module. Create a private data
|
* InitLocks -- Init the lock module. Create a private data
|
||||||
@ -168,10 +163,10 @@ InitLocks()
|
|||||||
|
|
||||||
bit = 1;
|
bit = 1;
|
||||||
/* -------------------
|
/* -------------------
|
||||||
* remember 0th locktype is invalid
|
* remember 0th lockmode is invalid
|
||||||
* -------------------
|
* -------------------
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < MAX_LOCKTYPES; i++, bit <<= 1)
|
for (i = 0; i < MAX_LOCKMODES; i++, bit <<= 1)
|
||||||
{
|
{
|
||||||
BITS_ON[i] = bit;
|
BITS_ON[i] = bit;
|
||||||
BITS_OFF[i] = ~bit;
|
BITS_OFF[i] = ~bit;
|
||||||
@ -190,30 +185,30 @@ LockDisable(int status)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockTypeInit -- initialize the lock table's lock type
|
* LockMethodInit -- initialize the lock table's lock type
|
||||||
* structures
|
* structures
|
||||||
*
|
*
|
||||||
* Notes: just copying. Should only be called once.
|
* Notes: just copying. Should only be called once.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
LockTypeInit(LOCKTAB *ltable,
|
LockMethodInit(LOCKMETHODTABLE *lockMethodTable,
|
||||||
MASK *conflictsP,
|
MASK *conflictsP,
|
||||||
int *prioP,
|
int *prioP,
|
||||||
int ntypes)
|
int numModes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ltable->ctl->nLockTypes = ntypes;
|
lockMethodTable->ctl->numLockModes = numModes;
|
||||||
ntypes++;
|
numModes++;
|
||||||
for (i = 0; i < ntypes; i++, prioP++, conflictsP++)
|
for (i = 0; i < numModes; i++, prioP++, conflictsP++)
|
||||||
{
|
{
|
||||||
ltable->ctl->conflictTab[i] = *conflictsP;
|
lockMethodTable->ctl->conflictTab[i] = *conflictsP;
|
||||||
ltable->ctl->prio[i] = *prioP;
|
lockMethodTable->ctl->prio[i] = *prioP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockTableInit -- initialize a lock table structure
|
* LockMethodTableInit -- initialize a lock table structure
|
||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
* (a) a lock table has four separate entries in the shmem index
|
* (a) a lock table has four separate entries in the shmem index
|
||||||
@ -222,23 +217,23 @@ LockTypeInit(LOCKTAB *ltable,
|
|||||||
* is wasteful, in this case, but not much space is involved.
|
* is wasteful, in this case, but not much space is involved.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
LockTableId
|
LOCKMETHOD
|
||||||
LockTableInit(char *tabName,
|
LockMethodTableInit(char *tabName,
|
||||||
MASK *conflictsP,
|
MASK *conflictsP,
|
||||||
int *prioP,
|
int *prioP,
|
||||||
int ntypes)
|
int numModes)
|
||||||
{
|
{
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
char *shmemName;
|
char *shmemName;
|
||||||
HASHCTL info;
|
HASHCTL info;
|
||||||
int hash_flags;
|
int hash_flags;
|
||||||
bool found;
|
bool found;
|
||||||
int status = TRUE;
|
int status = TRUE;
|
||||||
|
|
||||||
if (ntypes > MAX_LOCKTYPES)
|
if (numModes > MAX_LOCKMODES)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "LockTableInit: too many lock types %d greater than %d",
|
elog(NOTICE, "LockMethodTableInit: too many lock types %d greater than %d",
|
||||||
ntypes, MAX_LOCKTYPES);
|
numModes, MAX_LOCKMODES);
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,15 +241,15 @@ LockTableInit(char *tabName,
|
|||||||
shmemName = (char *) palloc((unsigned) (strlen(tabName) + 32));
|
shmemName = (char *) palloc((unsigned) (strlen(tabName) + 32));
|
||||||
if (!shmemName)
|
if (!shmemName)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "LockTableInit: couldn't malloc string %s \n", tabName);
|
elog(NOTICE, "LockMethodTableInit: couldn't malloc string %s \n", tabName);
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* each lock table has a non-shared header */
|
/* each lock table has a non-shared header */
|
||||||
ltable = (LOCKTAB *) palloc((unsigned) sizeof(LOCKTAB));
|
lockMethodTable = (LOCKMETHODTABLE *) palloc((unsigned) sizeof(LOCKMETHODTABLE));
|
||||||
if (!ltable)
|
if (!lockMethodTable)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "LockTableInit: couldn't malloc lock table %s\n", tabName);
|
elog(NOTICE, "LockMethodTableInit: couldn't malloc lock table %s\n", tabName);
|
||||||
pfree(shmemName);
|
pfree(shmemName);
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
}
|
}
|
||||||
@ -272,16 +267,20 @@ LockTableInit(char *tabName,
|
|||||||
* -----------------------
|
* -----------------------
|
||||||
*/
|
*/
|
||||||
sprintf(shmemName, "%s (ctl)", tabName);
|
sprintf(shmemName, "%s (ctl)", tabName);
|
||||||
ltable->ctl = (LOCKCTL *)
|
lockMethodTable->ctl = (LOCKMETHODCTL *)
|
||||||
ShmemInitStruct(shmemName, (unsigned) sizeof(LOCKCTL), &found);
|
ShmemInitStruct(shmemName, (unsigned) sizeof(LOCKMETHODCTL), &found);
|
||||||
|
|
||||||
if (!ltable->ctl)
|
if (!lockMethodTable->ctl)
|
||||||
{
|
{
|
||||||
elog(FATAL, "LockTableInit: couldn't initialize %s", tabName);
|
elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName);
|
||||||
status = FALSE;
|
status = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NumTables = 1;
|
/* -------------------
|
||||||
|
* no zero-th table
|
||||||
|
* -------------------
|
||||||
|
*/
|
||||||
|
NumLockMethods = 1;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* we're first - initialize
|
* we're first - initialize
|
||||||
@ -289,18 +288,18 @@ LockTableInit(char *tabName,
|
|||||||
*/
|
*/
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
MemSet(ltable->ctl, 0, sizeof(LOCKCTL));
|
MemSet(lockMethodTable->ctl, 0, sizeof(LOCKMETHODCTL));
|
||||||
ltable->ctl->masterLock = LockMgrLock;
|
lockMethodTable->ctl->masterLock = LockMgrLock;
|
||||||
ltable->ctl->tableId = NumTables;
|
lockMethodTable->ctl->lockmethod = NumLockMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------
|
/* --------------------
|
||||||
* other modules refer to the lock table by a tableId
|
* other modules refer to the lock table by a lockmethod
|
||||||
* --------------------
|
* --------------------
|
||||||
*/
|
*/
|
||||||
AllTables[NumTables] = ltable;
|
LockMethodTable[NumLockMethods] = lockMethodTable;
|
||||||
NumTables++;
|
NumLockMethods++;
|
||||||
Assert(NumTables <= MAX_TABLES);
|
Assert(NumLockMethods <= MAX_LOCK_METHODS);
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
* allocate a hash table for the lock tags. This is used
|
* allocate a hash table for the lock tags. This is used
|
||||||
@ -313,14 +312,14 @@ LockTableInit(char *tabName,
|
|||||||
hash_flags = (HASH_ELEM | HASH_FUNCTION);
|
hash_flags = (HASH_ELEM | HASH_FUNCTION);
|
||||||
|
|
||||||
sprintf(shmemName, "%s (lock hash)", tabName);
|
sprintf(shmemName, "%s (lock hash)", tabName);
|
||||||
ltable->lockHash = (HTAB *) ShmemInitHash(shmemName,
|
lockMethodTable->lockHash = (HTAB *) ShmemInitHash(shmemName,
|
||||||
INIT_TABLE_SIZE, MAX_TABLE_SIZE,
|
INIT_TABLE_SIZE, MAX_TABLE_SIZE,
|
||||||
&info, hash_flags);
|
&info, hash_flags);
|
||||||
|
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
if (!ltable->lockHash)
|
if (!lockMethodTable->lockHash)
|
||||||
{
|
{
|
||||||
elog(FATAL, "LockTableInit: couldn't initialize %s", tabName);
|
elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName);
|
||||||
status = FALSE;
|
status = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,31 +334,31 @@ LockTableInit(char *tabName,
|
|||||||
hash_flags = (HASH_ELEM | HASH_FUNCTION);
|
hash_flags = (HASH_ELEM | HASH_FUNCTION);
|
||||||
|
|
||||||
sprintf(shmemName, "%s (xid hash)", tabName);
|
sprintf(shmemName, "%s (xid hash)", tabName);
|
||||||
ltable->xidHash = (HTAB *) ShmemInitHash(shmemName,
|
lockMethodTable->xidHash = (HTAB *) ShmemInitHash(shmemName,
|
||||||
INIT_TABLE_SIZE, MAX_TABLE_SIZE,
|
INIT_TABLE_SIZE, MAX_TABLE_SIZE,
|
||||||
&info, hash_flags);
|
&info, hash_flags);
|
||||||
|
|
||||||
if (!ltable->xidHash)
|
if (!lockMethodTable->xidHash)
|
||||||
{
|
{
|
||||||
elog(FATAL, "LockTableInit: couldn't initialize %s", tabName);
|
elog(FATAL, "LockMethodTableInit: couldn't initialize %s", tabName);
|
||||||
status = FALSE;
|
status = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init ctl data structures */
|
/* init ctl data structures */
|
||||||
LockTypeInit(ltable, conflictsP, prioP, ntypes);
|
LockMethodInit(lockMethodTable, conflictsP, prioP, numModes);
|
||||||
|
|
||||||
SpinRelease(LockMgrLock);
|
SpinRelease(LockMgrLock);
|
||||||
|
|
||||||
pfree(shmemName);
|
pfree(shmemName);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
return (ltable->ctl->tableId);
|
return (lockMethodTable->ctl->lockmethod);
|
||||||
else
|
else
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockTableRename -- allocate another tableId to the same
|
* LockMethodTableRename -- allocate another lockmethod to the same
|
||||||
* lock table.
|
* lock table.
|
||||||
*
|
*
|
||||||
* NOTES: Both the lock module and the lock chain (lchain.c)
|
* NOTES: Both the lock module and the lock chain (lchain.c)
|
||||||
@ -367,28 +366,27 @@ LockTableInit(char *tabName,
|
|||||||
* kinds of locks. Short term and long term locks look
|
* kinds of locks. Short term and long term locks look
|
||||||
* the same to the lock table, but are handled differently
|
* the same to the lock table, but are handled differently
|
||||||
* by the lock chain manager. This function allows the
|
* by the lock chain manager. This function allows the
|
||||||
* client to use different tableIds when acquiring/releasing
|
* client to use different lockmethods when acquiring/releasing
|
||||||
* short term and long term locks.
|
* short term and long term locks.
|
||||||
*/
|
*/
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
LockTableId
|
LOCKMETHOD
|
||||||
LockTableRename(LockTableId tableId)
|
LockMethodTableRename(LOCKMETHOD lockmethod)
|
||||||
{
|
{
|
||||||
LockTableId newTableId;
|
LOCKMETHOD newLockMethod;
|
||||||
|
|
||||||
if (NumTables >= MAX_TABLES)
|
if (NumLockMethods >= MAX_LOCK_METHODS)
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
if (AllTables[tableId] == INVALID_TABLEID)
|
if (LockMethodTable[lockmethod] == INVALID_TABLEID)
|
||||||
return (INVALID_TABLEID);
|
return (INVALID_TABLEID);
|
||||||
|
|
||||||
/* other modules refer to the lock table by a tableId */
|
/* other modules refer to the lock table by a lockmethod */
|
||||||
newTableId = NumTables;
|
newLockMethod = NumLockMethods;
|
||||||
NumTables++;
|
NumLockMethods++;
|
||||||
|
|
||||||
AllTables[newTableId] = AllTables[tableId];
|
LockMethodTable[newLockMethod] = LockMethodTable[lockmethod];
|
||||||
return (newTableId);
|
return (newLockMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -423,13 +421,13 @@ LockTableRename(LockTableId tableId)
|
|||||||
* acquired if already held by another process. They must be
|
* acquired if already held by another process. They must be
|
||||||
* released explicitly by the application but they are released
|
* released explicitly by the application but they are released
|
||||||
* automatically when a backend terminates.
|
* automatically when a backend terminates.
|
||||||
* They are indicated by a dummy tableId 0 which doesn't have
|
* They are indicated by a dummy lockmethod 0 which doesn't have
|
||||||
* any table allocated but uses the normal lock table, and are
|
* any table allocated but uses the normal lock table, and are
|
||||||
* distinguished from normal locks for the following differences:
|
* distinguished from normal locks for the following differences:
|
||||||
*
|
*
|
||||||
* normal lock user lock
|
* normal lock user lock
|
||||||
*
|
*
|
||||||
* tableId 1 0
|
* lockmethod 1 0
|
||||||
* tag.relId rel oid 0
|
* tag.relId rel oid 0
|
||||||
* tag.ItemPointerData.ip_blkid block id lock id2
|
* tag.ItemPointerData.ip_blkid block id lock id2
|
||||||
* tag.ItemPointerData.ip_posid tuple offset lock id1
|
* tag.ItemPointerData.ip_posid tuple offset lock id1
|
||||||
@ -437,7 +435,7 @@ LockTableRename(LockTableId tableId)
|
|||||||
* xid.xid current xid 0
|
* xid.xid current xid 0
|
||||||
* persistence transaction user or backend
|
* persistence transaction user or backend
|
||||||
*
|
*
|
||||||
* The locktype parameter can have the same values for normal locks
|
* The lockmode parameter can have the same values for normal locks
|
||||||
* although probably only WRITE_LOCK can have some practical use.
|
* although probably only WRITE_LOCK can have some practical use.
|
||||||
*
|
*
|
||||||
* DZ - 4 Oct 1996
|
* DZ - 4 Oct 1996
|
||||||
@ -445,7 +443,7 @@ LockTableRename(LockTableId tableId)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
XIDLookupEnt *result,
|
XIDLookupEnt *result,
|
||||||
item;
|
item;
|
||||||
@ -453,50 +451,50 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
bool found;
|
bool found;
|
||||||
LOCK *lock = NULL;
|
LOCK *lock = NULL;
|
||||||
SPINLOCK masterLock;
|
SPINLOCK masterLock;
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
int status;
|
int status;
|
||||||
TransactionId myXid;
|
TransactionId myXid;
|
||||||
|
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
int is_user_lock;
|
int is_user_lock;
|
||||||
|
|
||||||
is_user_lock = (tableId == 0);
|
is_user_lock = (lockmethod == 0);
|
||||||
if (is_user_lock)
|
if (is_user_lock)
|
||||||
{
|
{
|
||||||
tableId = 1;
|
lockmethod = 1;
|
||||||
#ifdef USER_LOCKS_DEBUG
|
#ifdef USER_LOCKS_DEBUG
|
||||||
elog(NOTICE, "LockAcquire: user lock tag [%u,%u] %d",
|
elog(NOTICE, "LockAcquire: user lock tag [%u,%u] %d",
|
||||||
lockName->tupleId.ip_posid,
|
locktag->tupleId.ip_posid,
|
||||||
((lockName->tupleId.ip_blkid.bi_hi << 16) +
|
((locktag->tupleId.ip_blkid.bi_hi << 16) +
|
||||||
lockName->tupleId.ip_blkid.bi_lo),
|
locktag->tupleId.ip_blkid.bi_lo),
|
||||||
locktype);
|
lockmode);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Assert(tableId < NumTables);
|
Assert(lockmethod < NumLockMethods);
|
||||||
ltable = AllTables[tableId];
|
lockMethodTable = LockMethodTable[lockmethod];
|
||||||
if (!ltable)
|
if (!lockMethodTable)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "LockAcquire: bad lock table %d", tableId);
|
elog(NOTICE, "LockAcquire: bad lock table %d", lockmethod);
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LockingIsDisabled)
|
if (LockingIsDisabled)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
|
|
||||||
LOCK_PRINT("Acquire", lockName, locktype);
|
LOCK_PRINT("Acquire", locktag, lockmode);
|
||||||
masterLock = ltable->ctl->masterLock;
|
masterLock = lockMethodTable->ctl->masterLock;
|
||||||
|
|
||||||
SpinAcquire(masterLock);
|
SpinAcquire(masterLock);
|
||||||
|
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
lock = (LOCK *) hash_search(ltable->lockHash, (Pointer) lockName, HASH_ENTER, &found);
|
lock = (LOCK *) hash_search(lockMethodTable->lockHash, (Pointer) locktag, HASH_ENTER, &found);
|
||||||
|
|
||||||
if (!lock)
|
if (!lock)
|
||||||
{
|
{
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
elog(FATAL, "LockAcquire: lock table %d is corrupted", tableId);
|
elog(FATAL, "LockAcquire: lock table %d is corrupted", lockmethod);
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,13 +506,13 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
{
|
{
|
||||||
lock->mask = 0;
|
lock->mask = 0;
|
||||||
ProcQueueInit(&(lock->waitProcs));
|
ProcQueueInit(&(lock->waitProcs));
|
||||||
MemSet((char *) lock->holders, 0, sizeof(int) * MAX_LOCKTYPES);
|
MemSet((char *) lock->holders, 0, sizeof(int) * MAX_LOCKMODES);
|
||||||
MemSet((char *) lock->activeHolders, 0, sizeof(int) * MAX_LOCKTYPES);
|
MemSet((char *) lock->activeHolders, 0, sizeof(int) * MAX_LOCKMODES);
|
||||||
lock->nHolding = 0;
|
lock->nHolding = 0;
|
||||||
lock->nActive = 0;
|
lock->nActive = 0;
|
||||||
|
|
||||||
Assert(BlockIdEquals(&(lock->tag.tupleId.ip_blkid),
|
Assert(BlockIdEquals(&(lock->tag.tupleId.ip_blkid),
|
||||||
&(lockName->tupleId.ip_blkid)));
|
&(locktag->tupleId.ip_blkid)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,7 +521,7 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* locks at end of transaction.
|
* locks at end of transaction.
|
||||||
* ------------------
|
* ------------------
|
||||||
*/
|
*/
|
||||||
xidTable = ltable->xidHash;
|
xidTable = lockMethodTable->xidHash;
|
||||||
myXid = GetCurrentTransactionId();
|
myXid = GetCurrentTransactionId();
|
||||||
|
|
||||||
/* ------------------
|
/* ------------------
|
||||||
@ -561,7 +559,7 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
XID_PRINT("LockAcquire: queueing XidEnt", result);
|
XID_PRINT("LockAcquire: queueing XidEnt", result);
|
||||||
ProcAddLock(&result->queue);
|
ProcAddLock(&result->queue);
|
||||||
result->nHolding = 0;
|
result->nHolding = 0;
|
||||||
MemSet((char *) result->holders, 0, sizeof(int) * MAX_LOCKTYPES);
|
MemSet((char *) result->holders, 0, sizeof(int) * MAX_LOCKMODES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -571,7 +569,7 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
lock->nHolding++;
|
lock->nHolding++;
|
||||||
lock->holders[locktype]++;
|
lock->holders[lockmode]++;
|
||||||
|
|
||||||
/* --------------------
|
/* --------------------
|
||||||
* If I'm the only one holding a lock, then there
|
* If I'm the only one holding a lock, then there
|
||||||
@ -582,19 +580,19 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
*/
|
*/
|
||||||
if (result->nHolding == lock->nActive)
|
if (result->nHolding == lock->nActive)
|
||||||
{
|
{
|
||||||
result->holders[locktype]++;
|
result->holders[lockmode]++;
|
||||||
result->nHolding++;
|
result->nHolding++;
|
||||||
GrantLock(lock, locktype);
|
GrantLock(lock, lockmode);
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(result->nHolding <= lock->nActive);
|
Assert(result->nHolding <= lock->nActive);
|
||||||
|
|
||||||
status = LockResolveConflicts(ltable, lock, locktype, myXid);
|
status = LockResolveConflicts(lockmethod, lock, lockmode, myXid);
|
||||||
|
|
||||||
if (status == STATUS_OK)
|
if (status == STATUS_OK)
|
||||||
GrantLock(lock, locktype);
|
GrantLock(lock, lockmode);
|
||||||
else if (status == STATUS_FOUND)
|
else if (status == STATUS_FOUND)
|
||||||
{
|
{
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
@ -611,7 +609,7 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
hash_search(xidTable, (Pointer) &item, HASH_REMOVE, &found);
|
hash_search(xidTable, (Pointer) &item, HASH_REMOVE, &found);
|
||||||
}
|
}
|
||||||
lock->nHolding--;
|
lock->nHolding--;
|
||||||
lock->holders[locktype]--;
|
lock->holders[lockmode]--;
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
#ifdef USER_LOCKS_DEBUG
|
#ifdef USER_LOCKS_DEBUG
|
||||||
elog(NOTICE, "LockAcquire: user lock failed");
|
elog(NOTICE, "LockAcquire: user lock failed");
|
||||||
@ -619,7 +617,7 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
status = WaitOnLock(ltable, tableId, lock, locktype);
|
status = WaitOnLock(lockmethod, lock, lockmode);
|
||||||
XID_PRINT("Someone granted me the lock", result);
|
XID_PRINT("Someone granted me the lock", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,23 +643,23 @@ LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* ----------------------------
|
* ----------------------------
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
LockResolveConflicts(LOCKTAB *ltable,
|
LockResolveConflicts(LOCKMETHOD lockmethod,
|
||||||
LOCK *lock,
|
LOCK *lock,
|
||||||
LOCKTYPE locktype,
|
LOCKMODE lockmode,
|
||||||
TransactionId xid)
|
TransactionId xid)
|
||||||
{
|
{
|
||||||
XIDLookupEnt *result,
|
XIDLookupEnt *result,
|
||||||
item;
|
item;
|
||||||
int *myHolders;
|
int *myHolders;
|
||||||
int nLockTypes;
|
int numLockModes;
|
||||||
HTAB *xidTable;
|
HTAB *xidTable;
|
||||||
bool found;
|
bool found;
|
||||||
int bitmask;
|
int bitmask;
|
||||||
int i,
|
int i,
|
||||||
tmpMask;
|
tmpMask;
|
||||||
|
|
||||||
nLockTypes = ltable->ctl->nLockTypes;
|
numLockModes = LockMethodTable[lockmethod]->ctl->numLockModes;
|
||||||
xidTable = ltable->xidHash;
|
xidTable = LockMethodTable[lockmethod]->xidHash;
|
||||||
|
|
||||||
/* ---------------------
|
/* ---------------------
|
||||||
* read my own statistics from the xid table. If there
|
* read my own statistics from the xid table. If there
|
||||||
@ -693,7 +691,7 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
* the lock stats.
|
* the lock stats.
|
||||||
* ---------------
|
* ---------------
|
||||||
*/
|
*/
|
||||||
MemSet(result->holders, 0, nLockTypes * sizeof(*(lock->holders)));
|
MemSet(result->holders, 0, numLockModes * sizeof(*(lock->holders)));
|
||||||
result->nHolding = 0;
|
result->nHolding = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,7 +701,7 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
* do not continue and share the lock, even if we can. bjm
|
* do not continue and share the lock, even if we can. bjm
|
||||||
* ------------------------
|
* ------------------------
|
||||||
*/
|
*/
|
||||||
int myprio = ltable->ctl->prio[locktype];
|
int myprio = LockMethodTable[lockmethod]->ctl->prio[lockmode];
|
||||||
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
||||||
PROC *topproc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
PROC *topproc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
||||||
|
|
||||||
@ -716,15 +714,15 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
* with mine, then I get the lock.
|
* with mine, then I get the lock.
|
||||||
*
|
*
|
||||||
* Checking for conflict: lock->mask represents the types of
|
* Checking for conflict: lock->mask represents the types of
|
||||||
* currently held locks. conflictTable[locktype] has a bit
|
* currently held locks. conflictTable[lockmode] has a bit
|
||||||
* set for each type of lock that conflicts with mine. Bitwise
|
* set for each type of lock that conflicts with mine. Bitwise
|
||||||
* compare tells if there is a conflict.
|
* compare tells if there is a conflict.
|
||||||
* ----------------------------
|
* ----------------------------
|
||||||
*/
|
*/
|
||||||
if (!(ltable->ctl->conflictTab[locktype] & lock->mask))
|
if (!(LockMethodTable[lockmethod]->ctl->conflictTab[lockmode] & lock->mask))
|
||||||
{
|
{
|
||||||
|
|
||||||
result->holders[locktype]++;
|
result->holders[lockmode]++;
|
||||||
result->nHolding++;
|
result->nHolding++;
|
||||||
|
|
||||||
XID_PRINT("Conflict Resolved: updated xid entry stats", result);
|
XID_PRINT("Conflict Resolved: updated xid entry stats", result);
|
||||||
@ -740,7 +738,7 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
*/
|
*/
|
||||||
bitmask = 0;
|
bitmask = 0;
|
||||||
tmpMask = 2;
|
tmpMask = 2;
|
||||||
for (i = 1; i <= nLockTypes; i++, tmpMask <<= 1)
|
for (i = 1; i <= numLockModes; i++, tmpMask <<= 1)
|
||||||
{
|
{
|
||||||
if (lock->activeHolders[i] != myHolders[i])
|
if (lock->activeHolders[i] != myHolders[i])
|
||||||
bitmask |= tmpMask;
|
bitmask |= tmpMask;
|
||||||
@ -753,12 +751,12 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
* conflict and I have to sleep.
|
* conflict and I have to sleep.
|
||||||
* ------------------------
|
* ------------------------
|
||||||
*/
|
*/
|
||||||
if (!(ltable->ctl->conflictTab[locktype] & bitmask))
|
if (!(LockMethodTable[lockmethod]->ctl->conflictTab[lockmode] & bitmask))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* no conflict. Get the lock and go on */
|
/* no conflict. Get the lock and go on */
|
||||||
|
|
||||||
result->holders[locktype]++;
|
result->holders[lockmode]++;
|
||||||
result->nHolding++;
|
result->nHolding++;
|
||||||
|
|
||||||
XID_PRINT("Conflict Resolved: updated xid entry stats", result);
|
XID_PRINT("Conflict Resolved: updated xid entry stats", result);
|
||||||
@ -771,11 +769,13 @@ LockResolveConflicts(LOCKTAB *ltable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock, LOCKTYPE locktype)
|
WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
||||||
|
LOCKMETHODTABLE *lockMethodTable = LockMethodTable[lockmethod];
|
||||||
|
int prio = lockMethodTable->ctl->prio[lockmode];
|
||||||
|
|
||||||
int prio = ltable->ctl->prio[locktype];
|
Assert(lockmethod < NumLockMethods);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the waitqueue is ordered by priority. I insert myself according to
|
* the waitqueue is ordered by priority. I insert myself according to
|
||||||
@ -785,10 +785,10 @@ WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock, LOCKTYPE locktype)
|
|||||||
* synchronization for this queue. That will not be true if/when
|
* synchronization for this queue. That will not be true if/when
|
||||||
* people can be deleted from the queue by a SIGINT or something.
|
* people can be deleted from the queue by a SIGINT or something.
|
||||||
*/
|
*/
|
||||||
LOCK_DUMP_AUX("WaitOnLock: sleeping on lock", lock, locktype);
|
LOCK_DUMP_AUX("WaitOnLock: sleeping on lock", lock, lockmode);
|
||||||
if (ProcSleep(waitQueue,
|
if (ProcSleep(waitQueue,
|
||||||
ltable->ctl->masterLock,
|
lockMethodTable->ctl->masterLock,
|
||||||
locktype,
|
lockmode,
|
||||||
prio,
|
prio,
|
||||||
lock) != NO_ERROR)
|
lock) != NO_ERROR)
|
||||||
{
|
{
|
||||||
@ -799,18 +799,18 @@ WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock, LOCKTYPE locktype)
|
|||||||
* -------------------
|
* -------------------
|
||||||
*/
|
*/
|
||||||
lock->nHolding--;
|
lock->nHolding--;
|
||||||
lock->holders[locktype]--;
|
lock->holders[lockmode]--;
|
||||||
LOCK_DUMP_AUX("WaitOnLock: aborting on lock", lock, locktype);
|
LOCK_DUMP_AUX("WaitOnLock: aborting on lock", lock, lockmode);
|
||||||
SpinRelease(ltable->ctl->masterLock);
|
SpinRelease(lockMethodTable->ctl->masterLock);
|
||||||
elog(ERROR, "WaitOnLock: error on wakeup - Aborting this transaction");
|
elog(ERROR, "WaitOnLock: error on wakeup - Aborting this transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_DUMP_AUX("WaitOnLock: wakeup on lock", lock, locktype);
|
LOCK_DUMP_AUX("WaitOnLock: wakeup on lock", lock, lockmode);
|
||||||
return (STATUS_OK);
|
return (STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockRelease -- look up 'lockName' in lock table 'tableId' and
|
* LockRelease -- look up 'locktag' in lock table 'lockmethod' and
|
||||||
* release it.
|
* release it.
|
||||||
*
|
*
|
||||||
* Side Effects: if the lock no longer conflicts with the highest
|
* Side Effects: if the lock no longer conflicts with the highest
|
||||||
@ -820,12 +820,12 @@ WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock, LOCKTYPE locktype)
|
|||||||
* come along and request the lock).
|
* come along and request the lock).
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCK *lock = NULL;
|
LOCK *lock = NULL;
|
||||||
SPINLOCK masterLock;
|
SPINLOCK masterLock;
|
||||||
bool found;
|
bool found;
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
XIDLookupEnt *result,
|
XIDLookupEnt *result,
|
||||||
item;
|
item;
|
||||||
HTAB *xidTable;
|
HTAB *xidTable;
|
||||||
@ -834,41 +834,41 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
int is_user_lock;
|
int is_user_lock;
|
||||||
|
|
||||||
is_user_lock = (tableId == 0);
|
is_user_lock = (lockmethod == 0);
|
||||||
if (is_user_lock)
|
if (is_user_lock)
|
||||||
{
|
{
|
||||||
tableId = 1;
|
lockmethod = 1;
|
||||||
#ifdef USER_LOCKS_DEBUG
|
#ifdef USER_LOCKS_DEBUG
|
||||||
elog(NOTICE, "LockRelease: user lock tag [%u,%u] %d",
|
elog(NOTICE, "LockRelease: user lock tag [%u,%u] %d",
|
||||||
lockName->tupleId.ip_posid,
|
locktag->tupleId.ip_posid,
|
||||||
((lockName->tupleId.ip_blkid.bi_hi << 16) +
|
((locktag->tupleId.ip_blkid.bi_hi << 16) +
|
||||||
lockName->tupleId.ip_blkid.bi_lo),
|
locktag->tupleId.ip_blkid.bi_lo),
|
||||||
locktype);
|
lockmode);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Assert(tableId < NumTables);
|
Assert(lockmethod < NumLockMethods);
|
||||||
ltable = AllTables[tableId];
|
lockMethodTable = LockMethodTable[lockmethod];
|
||||||
if (!ltable)
|
if (!lockMethodTable)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "ltable is null in LockRelease");
|
elog(NOTICE, "lockMethodTable is null in LockRelease");
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LockingIsDisabled)
|
if (LockingIsDisabled)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
|
|
||||||
LOCK_PRINT("Release", lockName, locktype);
|
LOCK_PRINT("Release", locktag, lockmode);
|
||||||
|
|
||||||
masterLock = ltable->ctl->masterLock;
|
masterLock = lockMethodTable->ctl->masterLock;
|
||||||
xidTable = ltable->xidHash;
|
xidTable = lockMethodTable->xidHash;
|
||||||
|
|
||||||
SpinAcquire(masterLock);
|
SpinAcquire(masterLock);
|
||||||
|
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
lock = (LOCK *)
|
lock = (LOCK *)
|
||||||
hash_search(ltable->lockHash, (Pointer) lockName, HASH_FIND_SAVE, &found);
|
hash_search(lockMethodTable->lockHash, (Pointer) locktag, HASH_FIND_SAVE, &found);
|
||||||
|
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
|
|
||||||
@ -919,9 +919,9 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* fix the general lock stats
|
* fix the general lock stats
|
||||||
*/
|
*/
|
||||||
lock->nHolding--;
|
lock->nHolding--;
|
||||||
lock->holders[locktype]--;
|
lock->holders[lockmode]--;
|
||||||
lock->nActive--;
|
lock->nActive--;
|
||||||
lock->activeHolders[locktype]--;
|
lock->activeHolders[lockmode]--;
|
||||||
|
|
||||||
Assert(lock->nActive >= 0);
|
Assert(lock->nActive >= 0);
|
||||||
|
|
||||||
@ -933,8 +933,8 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* Delete it from the lock table.
|
* Delete it from the lock table.
|
||||||
* ------------------
|
* ------------------
|
||||||
*/
|
*/
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
lock = (LOCK *) hash_search(ltable->lockHash,
|
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
|
||||||
(Pointer) &(lock->tag),
|
(Pointer) &(lock->tag),
|
||||||
HASH_REMOVE_SAVED,
|
HASH_REMOVE_SAVED,
|
||||||
&found);
|
&found);
|
||||||
@ -992,7 +992,7 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* now check to see if I have any private locks. If I do, decrement
|
* now check to see if I have any private locks. If I do, decrement
|
||||||
* the counts associated with them.
|
* the counts associated with them.
|
||||||
*/
|
*/
|
||||||
result->holders[locktype]--;
|
result->holders[lockmode]--;
|
||||||
result->nHolding--;
|
result->nHolding--;
|
||||||
|
|
||||||
XID_PRINT("LockRelease updated xid stats", result);
|
XID_PRINT("LockRelease updated xid stats", result);
|
||||||
@ -1038,9 +1038,9 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* fix the general lock stats
|
* fix the general lock stats
|
||||||
*/
|
*/
|
||||||
lock->nHolding--;
|
lock->nHolding--;
|
||||||
lock->holders[locktype]--;
|
lock->holders[lockmode]--;
|
||||||
lock->nActive--;
|
lock->nActive--;
|
||||||
lock->activeHolders[locktype]--;
|
lock->activeHolders[lockmode]--;
|
||||||
|
|
||||||
Assert(lock->nActive >= 0);
|
Assert(lock->nActive >= 0);
|
||||||
|
|
||||||
@ -1052,8 +1052,8 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* Delete it from the lock table.
|
* Delete it from the lock table.
|
||||||
* ------------------
|
* ------------------
|
||||||
*/
|
*/
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
lock = (LOCK *) hash_search(ltable->lockHash,
|
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
|
||||||
(Pointer) &(lock->tag),
|
(Pointer) &(lock->tag),
|
||||||
HASH_REMOVE,
|
HASH_REMOVE,
|
||||||
&found);
|
&found);
|
||||||
@ -1069,10 +1069,10 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* with the remaining locks.
|
* with the remaining locks.
|
||||||
* --------------------------
|
* --------------------------
|
||||||
*/
|
*/
|
||||||
if (!(lock->activeHolders[locktype]))
|
if (!(lock->activeHolders[lockmode]))
|
||||||
{
|
{
|
||||||
/* change the conflict mask. No more of this lock type. */
|
/* change the conflict mask. No more of this lock type. */
|
||||||
lock->mask &= BITS_OFF[locktype];
|
lock->mask &= BITS_OFF[lockmode];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wakeupNeeded)
|
if (wakeupNeeded)
|
||||||
@ -1083,7 +1083,7 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
* himself.
|
* himself.
|
||||||
* --------------------------
|
* --------------------------
|
||||||
*/
|
*/
|
||||||
ProcLockWakeup(&(lock->waitProcs), (char *) ltable, (char *) lock);
|
ProcLockWakeup(&(lock->waitProcs), lockmethod, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
@ -1091,15 +1091,15 @@ LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GrantLock -- udpate the lock data structure to show
|
* GrantLock -- update the lock data structure to show
|
||||||
* the new lock holder.
|
* the new lock holder.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
GrantLock(LOCK *lock, LOCKTYPE locktype)
|
GrantLock(LOCK *lock, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
lock->nActive++;
|
lock->nActive++;
|
||||||
lock->activeHolders[locktype]++;
|
lock->activeHolders[lockmode]++;
|
||||||
lock->mask |= BITS_ON[locktype];
|
lock->mask |= BITS_ON[lockmode];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
@ -1110,12 +1110,12 @@ GrantLock(LOCK *lock, LOCKTYPE locktype)
|
|||||||
* same queue of user locks which can't be removed from the
|
* same queue of user locks which can't be removed from the
|
||||||
* normal lock queue at the end of a transaction. They must
|
* normal lock queue at the end of a transaction. They must
|
||||||
* however be removed when the backend exits.
|
* however be removed when the backend exits.
|
||||||
* A dummy tableId 0 is used to indicate that we are releasing
|
* A dummy lockmethod 0 is used to indicate that we are releasing
|
||||||
* the user locks, from the code added to ProcKill().
|
* the user locks, from the code added to ProcKill().
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
bool
|
bool
|
||||||
LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
|
||||||
{
|
{
|
||||||
PROC_QUEUE *waitQueue;
|
PROC_QUEUE *waitQueue;
|
||||||
int done;
|
int done;
|
||||||
@ -1123,9 +1123,9 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
XIDLookupEnt *tmp = NULL;
|
XIDLookupEnt *tmp = NULL;
|
||||||
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
||||||
SPINLOCK masterLock;
|
SPINLOCK masterLock;
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
int i,
|
int i,
|
||||||
nLockTypes;
|
numLockModes;
|
||||||
LOCK *lock;
|
LOCK *lock;
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
@ -1134,21 +1134,21 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
count,
|
count,
|
||||||
nskip;
|
nskip;
|
||||||
|
|
||||||
is_user_lock_table = (tableId == 0);
|
is_user_lock_table = (lockmethod == 0);
|
||||||
#ifdef USER_LOCKS_DEBUG
|
#ifdef USER_LOCKS_DEBUG
|
||||||
elog(NOTICE, "LockReleaseAll: tableId=%d, pid=%d", tableId, MyProcPid);
|
elog(NOTICE, "LockReleaseAll: lockmethod=%d, pid=%d", lockmethod, MyProcPid);
|
||||||
#endif
|
#endif
|
||||||
if (is_user_lock_table)
|
if (is_user_lock_table)
|
||||||
tableId = 1;
|
lockmethod = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Assert(tableId < NumTables);
|
Assert(lockmethod < NumLockMethods);
|
||||||
ltable = AllTables[tableId];
|
lockMethodTable = LockMethodTable[lockmethod];
|
||||||
if (!ltable)
|
if (!lockMethodTable)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
nLockTypes = ltable->ctl->nLockTypes;
|
numLockModes = lockMethodTable->ctl->numLockModes;
|
||||||
masterLock = ltable->ctl->masterLock;
|
masterLock = lockMethodTable->ctl->masterLock;
|
||||||
|
|
||||||
if (SHMQueueEmpty(lockQueue))
|
if (SHMQueueEmpty(lockQueue))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -1254,7 +1254,7 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
lock->nHolding -= xidLook->nHolding;
|
lock->nHolding -= xidLook->nHolding;
|
||||||
lock->nActive -= xidLook->nHolding;
|
lock->nActive -= xidLook->nHolding;
|
||||||
Assert(lock->nActive >= 0);
|
Assert(lock->nActive >= 0);
|
||||||
for (i = 1; i <= nLockTypes; i++)
|
for (i = 1; i <= numLockModes; i++)
|
||||||
{
|
{
|
||||||
lock->holders[i] -= xidLook->holders[i];
|
lock->holders[i] -= xidLook->holders[i];
|
||||||
lock->activeHolders[i] -= xidLook->holders[i];
|
lock->activeHolders[i] -= xidLook->holders[i];
|
||||||
@ -1278,7 +1278,7 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
SHMQueueDelete(&xidLook->queue);
|
SHMQueueDelete(&xidLook->queue);
|
||||||
#endif
|
#endif
|
||||||
if ((!hash_search(ltable->xidHash, (Pointer) xidLook, HASH_REMOVE, &found))
|
if ((!hash_search(lockMethodTable->xidHash, (Pointer) xidLook, HASH_REMOVE, &found))
|
||||||
|| !found)
|
|| !found)
|
||||||
{
|
{
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
@ -1294,9 +1294,9 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
* --------------------
|
* --------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Assert(ltable->lockHash->hash == tag_hash);
|
Assert(lockMethodTable->lockHash->hash == tag_hash);
|
||||||
lock = (LOCK *)
|
lock = (LOCK *)
|
||||||
hash_search(ltable->lockHash, (Pointer) &(lock->tag), HASH_REMOVE, &found);
|
hash_search(lockMethodTable->lockHash, (Pointer) &(lock->tag), HASH_REMOVE, &found);
|
||||||
if ((!lock) || (!found))
|
if ((!lock) || (!found))
|
||||||
{
|
{
|
||||||
SpinRelease(masterLock);
|
SpinRelease(masterLock);
|
||||||
@ -1313,7 +1313,7 @@ LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
|
|||||||
* --------------------
|
* --------------------
|
||||||
*/
|
*/
|
||||||
waitQueue = &(lock->waitProcs);
|
waitQueue = &(lock->waitProcs);
|
||||||
ProcLockWakeup(waitQueue, (char *) ltable, (char *) lock);
|
ProcLockWakeup(waitQueue, lockmethod, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
@ -1352,7 +1352,7 @@ LockShmemSize()
|
|||||||
nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
|
nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
|
||||||
|
|
||||||
size += MAXALIGN(NBACKENDS * sizeof(PROC)); /* each MyProc */
|
size += MAXALIGN(NBACKENDS * sizeof(PROC)); /* each MyProc */
|
||||||
size += MAXALIGN(NBACKENDS * sizeof(LOCKCTL)); /* each ltable->ctl */
|
size += MAXALIGN(NBACKENDS * sizeof(LOCKMETHODCTL)); /* each lockMethodTable->ctl */
|
||||||
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
||||||
|
|
||||||
size += MAXALIGN(my_log2(NLOCKENTS) * sizeof(void *));
|
size += MAXALIGN(my_log2(NLOCKENTS) * sizeof(void *));
|
||||||
@ -1404,7 +1404,7 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
|
|||||||
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
||||||
LOCK *lock;
|
LOCK *lock;
|
||||||
|
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
XIDLookupEnt *result,
|
XIDLookupEnt *result,
|
||||||
item;
|
item;
|
||||||
HTAB *xidTable;
|
HTAB *xidTable;
|
||||||
@ -1420,8 +1420,8 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
|
|||||||
checked_procs[0] = MyProc;
|
checked_procs[0] = MyProc;
|
||||||
nprocs = 1;
|
nprocs = 1;
|
||||||
|
|
||||||
ltable = AllTables[1];
|
lockMethodTable = LockMethodTable[1];
|
||||||
xidTable = ltable->xidHash;
|
xidTable = lockMethodTable->xidHash;
|
||||||
|
|
||||||
MemSet(&item, 0, XID_TAGSIZE);
|
MemSet(&item, 0, XID_TAGSIZE);
|
||||||
TransactionIdStore(MyProc->xid, &item.tag.xid);
|
TransactionIdStore(MyProc->xid, &item.tag.xid);
|
||||||
@ -1499,8 +1499,8 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
|
|||||||
Assert(skip_check);
|
Assert(skip_check);
|
||||||
Assert(MyProc->prio == 2);
|
Assert(MyProc->prio == 2);
|
||||||
|
|
||||||
ltable = AllTables[1];
|
lockMethodTable = LockMethodTable[1];
|
||||||
xidTable = ltable->xidHash;
|
xidTable = lockMethodTable->xidHash;
|
||||||
|
|
||||||
MemSet(&item, 0, XID_TAGSIZE);
|
MemSet(&item, 0, XID_TAGSIZE);
|
||||||
TransactionIdStore(proc->xid, &item.tag.xid);
|
TransactionIdStore(proc->xid, &item.tag.xid);
|
||||||
@ -1575,12 +1575,12 @@ DumpLocks()
|
|||||||
XIDLookupEnt *tmp = NULL;
|
XIDLookupEnt *tmp = NULL;
|
||||||
SHMEM_OFFSET end;
|
SHMEM_OFFSET end;
|
||||||
SPINLOCK masterLock;
|
SPINLOCK masterLock;
|
||||||
int nLockTypes;
|
int numLockModes;
|
||||||
LOCK *lock;
|
LOCK *lock;
|
||||||
|
|
||||||
count;
|
count;
|
||||||
int tableId = 1;
|
int lockmethod = 1;
|
||||||
LOCKTAB *ltable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
|
|
||||||
ShmemPIDLookup(MyProcPid, &location);
|
ShmemPIDLookup(MyProcPid, &location);
|
||||||
if (location == INVALID_OFFSET)
|
if (location == INVALID_OFFSET)
|
||||||
@ -1590,13 +1590,13 @@ DumpLocks()
|
|||||||
return;
|
return;
|
||||||
lockQueue = &proc->lockQueue;
|
lockQueue = &proc->lockQueue;
|
||||||
|
|
||||||
Assert(tableId < NumTables);
|
Assert(lockmethod < NumLockMethods);
|
||||||
ltable = AllTables[tableId];
|
lockMethodTable = LockMethodTable[lockmethod];
|
||||||
if (!ltable)
|
if (!lockMethodTable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nLockTypes = ltable->ctl->nLockTypes;
|
numLockModes = lockMethodTable->ctl->numLockModes;
|
||||||
masterLock = ltable->ctl->masterLock;
|
masterLock = lockMethodTable->ctl->masterLock;
|
||||||
|
|
||||||
if (SHMQueueEmpty(lockQueue))
|
if (SHMQueueEmpty(lockQueue))
|
||||||
return;
|
return;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.18 1998/06/28 21:17:35 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.19 1998/06/30 02:33:31 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
* (1) The lock.c module assumes that the caller here is doing
|
* (1) The lock.c module assumes that the caller here is doing
|
||||||
@ -30,10 +30,10 @@
|
|||||||
#include "miscadmin.h" /* MyDatabaseId */
|
#include "miscadmin.h" /* MyDatabaseId */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
MultiAcquire(LockTableId tableId, LOCKTAG *tag, LOCKTYPE locktype,
|
MultiAcquire(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
||||||
PG_LOCK_LEVEL level);
|
PG_LOCK_LEVEL level);
|
||||||
static bool
|
static bool
|
||||||
MultiRelease(LockTableId tableId, LOCKTAG *tag, LOCKTYPE locktype,
|
MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
||||||
PG_LOCK_LEVEL level);
|
PG_LOCK_LEVEL level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -78,25 +78,27 @@ static int MultiPrios[] = {
|
|||||||
* Lock table identifier for this lock table. The multi-level
|
* Lock table identifier for this lock table. The multi-level
|
||||||
* lock table is ONE lock table, not three.
|
* lock table is ONE lock table, not three.
|
||||||
*/
|
*/
|
||||||
LockTableId MultiTableId = (LockTableId) NULL;
|
LOCKMETHOD MultiTableId = (LOCKMETHOD) NULL;
|
||||||
LockTableId ShortTermTableId = (LockTableId) NULL;
|
#ifdef NOT_USED
|
||||||
|
LOCKMETHOD ShortTermTableId = (LOCKMETHOD) NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the lock table described by MultiConflicts and Multiprio.
|
* Create the lock table described by MultiConflicts and Multiprio.
|
||||||
*/
|
*/
|
||||||
LockTableId
|
LOCKMETHOD
|
||||||
InitMultiLevelLocks()
|
InitMultiLevelLocks()
|
||||||
{
|
{
|
||||||
int tableId;
|
int lockmethod;
|
||||||
|
|
||||||
tableId = LockTableInit("LockTable", MultiConflicts, MultiPrios, 5);
|
lockmethod = LockMethodTableInit("MultiLevelLockTable", MultiConflicts, MultiPrios, 5);
|
||||||
MultiTableId = tableId;
|
MultiTableId = lockmethod;
|
||||||
if (!(MultiTableId))
|
if (!(MultiTableId))
|
||||||
elog(ERROR, "InitMultiLocks: couldnt initialize lock table");
|
elog(ERROR, "InitMultiLocks: couldnt initialize lock table");
|
||||||
/* -----------------------
|
/* -----------------------
|
||||||
* No short term lock table for now. -Jeff 15 July 1991
|
* No short term lock table for now. -Jeff 15 July 1991
|
||||||
*
|
*
|
||||||
* ShortTermTableId = LockTableRename(tableId);
|
* ShortTermTableId = LockTableRename(lockmethod);
|
||||||
* if (! (ShortTermTableId)) {
|
* if (! (ShortTermTableId)) {
|
||||||
* elog(ERROR,"InitMultiLocks: couldnt rename lock table");
|
* elog(ERROR,"InitMultiLocks: couldnt rename lock table");
|
||||||
* }
|
* }
|
||||||
@ -111,7 +113,7 @@ InitMultiLevelLocks()
|
|||||||
* Returns: TRUE if the lock can be set, FALSE otherwise.
|
* Returns: TRUE if the lock can be set, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
MultiLockReln(LockInfo linfo, LOCKTYPE locktype)
|
MultiLockReln(LockInfo linfo, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ MultiLockReln(LockInfo linfo, LOCKTYPE locktype)
|
|||||||
MemSet(&tag, 0, sizeof(tag));
|
MemSet(&tag, 0, sizeof(tag));
|
||||||
tag.relId = linfo->lRelId.relId;
|
tag.relId = linfo->lRelId.relId;
|
||||||
tag.dbId = linfo->lRelId.dbId;
|
tag.dbId = linfo->lRelId.dbId;
|
||||||
return (MultiAcquire(MultiTableId, &tag, locktype, RELN_LEVEL));
|
return (MultiAcquire(MultiTableId, &tag, lockmode, RELN_LEVEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -134,7 +136,7 @@ MultiLockReln(LockInfo linfo, LOCKTYPE locktype)
|
|||||||
* at the page and relation level.
|
* at the page and relation level.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -149,14 +151,14 @@ MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
|||||||
|
|
||||||
/* not locking any valid Tuple, just the page */
|
/* not locking any valid Tuple, just the page */
|
||||||
tag.tupleId = *tidPtr;
|
tag.tupleId = *tidPtr;
|
||||||
return (MultiAcquire(MultiTableId, &tag, locktype, TUPLE_LEVEL));
|
return (MultiAcquire(MultiTableId, &tag, lockmode, TUPLE_LEVEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* same as above at page level
|
* same as above at page level
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -179,7 +181,7 @@ MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
|||||||
tag.relId = linfo->lRelId.relId;
|
tag.relId = linfo->lRelId.relId;
|
||||||
tag.dbId = linfo->lRelId.dbId;
|
tag.dbId = linfo->lRelId.dbId;
|
||||||
BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
|
BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
|
||||||
return (MultiAcquire(MultiTableId, &tag, locktype, PAGE_LEVEL));
|
return (MultiAcquire(MultiTableId, &tag, lockmode, PAGE_LEVEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -189,12 +191,12 @@ MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
|||||||
* Side Effects:
|
* Side Effects:
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
MultiAcquire(LockTableId tableId,
|
MultiAcquire(LOCKMETHOD lockmethod,
|
||||||
LOCKTAG *tag,
|
LOCKTAG *tag,
|
||||||
LOCKTYPE locktype,
|
LOCKMODE lockmode,
|
||||||
PG_LOCK_LEVEL level)
|
PG_LOCK_LEVEL level)
|
||||||
{
|
{
|
||||||
LOCKTYPE locks[N_LEVELS];
|
LOCKMODE locks[N_LEVELS];
|
||||||
int i,
|
int i,
|
||||||
status;
|
status;
|
||||||
LOCKTAG xxTag,
|
LOCKTAG xxTag,
|
||||||
@ -213,19 +215,19 @@ MultiAcquire(LockTableId tableId,
|
|||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case RELN_LEVEL:
|
case RELN_LEVEL:
|
||||||
locks[0] = locktype;
|
locks[0] = lockmode;
|
||||||
locks[1] = NO_LOCK;
|
locks[1] = NO_LOCK;
|
||||||
locks[2] = NO_LOCK;
|
locks[2] = NO_LOCK;
|
||||||
break;
|
break;
|
||||||
case PAGE_LEVEL:
|
case PAGE_LEVEL:
|
||||||
locks[0] = locktype + INTENT;
|
locks[0] = lockmode + INTENT;
|
||||||
locks[1] = locktype;
|
locks[1] = lockmode;
|
||||||
locks[2] = NO_LOCK;
|
locks[2] = NO_LOCK;
|
||||||
break;
|
break;
|
||||||
case TUPLE_LEVEL:
|
case TUPLE_LEVEL:
|
||||||
locks[0] = locktype + INTENT;
|
locks[0] = lockmode + INTENT;
|
||||||
locks[1] = locktype + INTENT;
|
locks[1] = lockmode + INTENT;
|
||||||
locks[2] = locktype;
|
locks[2] = lockmode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "MultiAcquire: bad lock level");
|
elog(ERROR, "MultiAcquire: bad lock level");
|
||||||
@ -274,7 +276,7 @@ MultiAcquire(LockTableId tableId,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = LockAcquire(tableId, tmpTag, locks[i]);
|
status = LockAcquire(lockmethod, tmpTag, locks[i]);
|
||||||
if (!status)
|
if (!status)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -285,7 +287,7 @@ MultiAcquire(LockTableId tableId,
|
|||||||
* the last level lock we successfully acquired
|
* the last level lock we successfully acquired
|
||||||
*/
|
*/
|
||||||
retStatus = FALSE;
|
retStatus = FALSE;
|
||||||
MultiRelease(tableId, tag, locktype, i);
|
MultiRelease(lockmethod, tag, lockmode, i);
|
||||||
/* now leave the loop. Don't try for any more locks */
|
/* now leave the loop. Don't try for any more locks */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -300,7 +302,7 @@ MultiAcquire(LockTableId tableId,
|
|||||||
*/
|
*/
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
bool
|
bool
|
||||||
MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -316,7 +318,7 @@ MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
|||||||
tag.dbId = linfo->lRelId.dbId;
|
tag.dbId = linfo->lRelId.dbId;
|
||||||
BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
|
BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
|
||||||
|
|
||||||
return (MultiRelease(MultiTableId, &tag, locktype, PAGE_LEVEL));
|
return (MultiRelease(MultiTableId, &tag, lockmode, PAGE_LEVEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -326,7 +328,7 @@ MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype)
|
|||||||
* ------------------
|
* ------------------
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
MultiReleaseReln(LockInfo linfo, LOCKTYPE locktype)
|
MultiReleaseReln(LockInfo linfo, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -340,7 +342,7 @@ MultiReleaseReln(LockInfo linfo, LOCKTYPE locktype)
|
|||||||
tag.relId = linfo->lRelId.relId;
|
tag.relId = linfo->lRelId.relId;
|
||||||
tag.dbId = linfo->lRelId.dbId;
|
tag.dbId = linfo->lRelId.dbId;
|
||||||
|
|
||||||
return (MultiRelease(MultiTableId, &tag, locktype, RELN_LEVEL));
|
return (MultiRelease(MultiTableId, &tag, lockmode, RELN_LEVEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -349,12 +351,12 @@ MultiReleaseReln(LockInfo linfo, LOCKTYPE locktype)
|
|||||||
* Returns: TRUE if successful, FALSE otherwise.
|
* Returns: TRUE if successful, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
MultiRelease(LockTableId tableId,
|
MultiRelease(LOCKMETHOD lockmethod,
|
||||||
LOCKTAG *tag,
|
LOCKTAG *tag,
|
||||||
LOCKTYPE locktype,
|
LOCKMODE lockmode,
|
||||||
PG_LOCK_LEVEL level)
|
PG_LOCK_LEVEL level)
|
||||||
{
|
{
|
||||||
LOCKTYPE locks[N_LEVELS];
|
LOCKMODE locks[N_LEVELS];
|
||||||
int i,
|
int i,
|
||||||
status;
|
status;
|
||||||
LOCKTAG xxTag,
|
LOCKTAG xxTag,
|
||||||
@ -366,22 +368,22 @@ MultiRelease(LockTableId tableId,
|
|||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case RELN_LEVEL:
|
case RELN_LEVEL:
|
||||||
locks[0] = locktype;
|
locks[0] = lockmode;
|
||||||
locks[1] = NO_LOCK;
|
locks[1] = NO_LOCK;
|
||||||
locks[2] = NO_LOCK;
|
locks[2] = NO_LOCK;
|
||||||
break;
|
break;
|
||||||
case PAGE_LEVEL:
|
case PAGE_LEVEL:
|
||||||
locks[0] = locktype + INTENT;
|
locks[0] = lockmode + INTENT;
|
||||||
locks[1] = locktype;
|
locks[1] = lockmode;
|
||||||
locks[2] = NO_LOCK;
|
locks[2] = NO_LOCK;
|
||||||
break;
|
break;
|
||||||
case TUPLE_LEVEL:
|
case TUPLE_LEVEL:
|
||||||
locks[0] = locktype + INTENT;
|
locks[0] = lockmode + INTENT;
|
||||||
locks[1] = locktype + INTENT;
|
locks[1] = lockmode + INTENT;
|
||||||
locks[2] = locktype;
|
locks[2] = lockmode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "MultiRelease: bad locktype");
|
elog(ERROR, "MultiRelease: bad lockmode");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -423,7 +425,7 @@ MultiRelease(LockTableId tableId,
|
|||||||
ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
|
ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
status = LockRelease(tableId, tmpTag, locks[i]);
|
status = LockRelease(lockmethod, tmpTag, locks[i]);
|
||||||
if (!status)
|
if (!status)
|
||||||
elog(ERROR, "MultiRelease: couldn't release after error");
|
elog(ERROR, "MultiRelease: couldn't release after error");
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.38 1998/06/27 15:47:46 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.39 1998/06/30 02:33:32 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -46,7 +46,7 @@
|
|||||||
* This is so that we can support more backends. (system-wide semaphore
|
* This is so that we can support more backends. (system-wide semaphore
|
||||||
* sets run out pretty fast.) -ay 4/95
|
* sets run out pretty fast.) -ay 4/95
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.38 1998/06/27 15:47:46 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.39 1998/06/30 02:33:32 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -580,7 +580,7 @@ ProcWakeup(PROC *proc, int errType)
|
|||||||
* released.
|
* released.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
|
ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
|
||||||
{
|
{
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
int count;
|
int count;
|
||||||
@ -590,8 +590,8 @@ ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
|
|||||||
|
|
||||||
proc = (PROC *) MAKE_PTR(queue->links.prev);
|
proc = (PROC *) MAKE_PTR(queue->links.prev);
|
||||||
count = 0;
|
count = 0;
|
||||||
while ((LockResolveConflicts((LOCKTAB *) ltable,
|
while ((LockResolveConflicts(lockmethod,
|
||||||
(LOCK *) lock,
|
lock,
|
||||||
proc->token,
|
proc->token,
|
||||||
proc->xid) == STATUS_OK))
|
proc->xid) == STATUS_OK))
|
||||||
{
|
{
|
||||||
@ -602,7 +602,7 @@ ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
|
|||||||
* between the time we release the lock master (spinlock) and the
|
* between the time we release the lock master (spinlock) and the
|
||||||
* time that the awoken process begins executing again.
|
* time that the awoken process begins executing again.
|
||||||
*/
|
*/
|
||||||
GrantLock((LOCK *) lock, proc->token);
|
GrantLock(lock, proc->token);
|
||||||
queue->size--;
|
queue->size--;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/single.c,v 1.6 1998/06/28 21:17:35 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/single.c,v 1.7 1998/06/30 02:33:32 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -32,7 +32,7 @@
|
|||||||
* Returns: TRUE if the lock can be set, FALSE otherwise.
|
* Returns: TRUE if the lock can be set, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
SingleLockReln(LockInfo linfo, LOCKTYPE locktype, int action)
|
SingleLockReln(LockInfo linfo, LOCKMODE lockmode, int action)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
|
|
||||||
@ -47,9 +47,9 @@ SingleLockReln(LockInfo linfo, LOCKTYPE locktype, int action)
|
|||||||
tag.tupleId.ip_posid = InvalidOffsetNumber;
|
tag.tupleId.ip_posid = InvalidOffsetNumber;
|
||||||
|
|
||||||
if (action == UNLOCK)
|
if (action == UNLOCK)
|
||||||
return (LockRelease(MultiTableId, &tag, locktype));
|
return (LockRelease(MultiTableId, &tag, lockmode));
|
||||||
else
|
else
|
||||||
return (LockAcquire(MultiTableId, &tag, locktype));
|
return (LockAcquire(MultiTableId, &tag, lockmode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -63,7 +63,7 @@ SingleLockReln(LockInfo linfo, LOCKTYPE locktype, int action)
|
|||||||
bool
|
bool
|
||||||
SingleLockPage(LockInfo linfo,
|
SingleLockPage(LockInfo linfo,
|
||||||
ItemPointer tidPtr,
|
ItemPointer tidPtr,
|
||||||
LOCKTYPE locktype,
|
LOCKMODE lockmode,
|
||||||
int action)
|
int action)
|
||||||
{
|
{
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
@ -80,7 +80,7 @@ SingleLockPage(LockInfo linfo,
|
|||||||
|
|
||||||
|
|
||||||
if (action == UNLOCK)
|
if (action == UNLOCK)
|
||||||
return (LockRelease(MultiTableId, &tag, locktype));
|
return (LockRelease(MultiTableId, &tag, lockmode));
|
||||||
else
|
else
|
||||||
return (LockAcquire(MultiTableId, &tag, locktype));
|
return (LockAcquire(MultiTableId, &tag, lockmode));
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lmgr.h,v 1.11 1998/06/28 21:17:35 momjian Exp $
|
* $Id: lmgr.h,v 1.12 1998/06/30 02:33:32 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -72,10 +72,10 @@ extern void RelationSetWIntentLock(Relation relation);
|
|||||||
extern void RelationUnsetWIntentLock(Relation relation);
|
extern void RelationUnsetWIntentLock(Relation relation);
|
||||||
|
|
||||||
/* single.c */
|
/* single.c */
|
||||||
extern bool SingleLockReln(LockInfo linfo, LOCKTYPE locktype, int action);
|
extern bool SingleLockReln(LockInfo linfo, LOCKMODE lockmode, int action);
|
||||||
extern bool
|
extern bool
|
||||||
SingleLockPage(LockInfo linfo, ItemPointer tidPtr,
|
SingleLockPage(LockInfo linfo, ItemPointer tidPtr,
|
||||||
LOCKTYPE locktype, int action);
|
LOCKMODE lockmode, int action);
|
||||||
|
|
||||||
/* proc.c */
|
/* proc.c */
|
||||||
extern void InitProcGlobal(IPCKey key);
|
extern void InitProcGlobal(IPCKey key);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lock.h,v 1.14 1998/06/28 21:17:35 momjian Exp $
|
* $Id: lock.h,v 1.15 1998/06/30 02:33:33 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -36,26 +36,25 @@ typedef int MASK;
|
|||||||
#define NLOCKS_PER_XACT 40
|
#define NLOCKS_PER_XACT 40
|
||||||
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
|
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
|
||||||
|
|
||||||
typedef int LOCK_TYPE;
|
typedef int LOCKMODE;
|
||||||
typedef int LOCKTYPE;
|
typedef int LOCKMETHOD;
|
||||||
typedef int LockTableId;
|
|
||||||
|
|
||||||
/* MAX_LOCKTYPES cannot be larger than the bits in MASK */
|
/* MAX_LOCKMODES cannot be larger than the bits in MASK */
|
||||||
#define MAX_LOCKTYPES 6
|
#define MAX_LOCKMODES 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MAX_TABLES corresponds to the number of spin locks allocated in
|
* MAX_LOCK_METHODS corresponds to the number of spin locks allocated in
|
||||||
* CreateSpinLocks() or the number of shared memory locations allocated
|
* CreateSpinLocks() or the number of shared memory locations allocated
|
||||||
* for lock table spin locks in the case of machines with TAS instructions.
|
* for lock table spin locks in the case of machines with TAS instructions.
|
||||||
*/
|
*/
|
||||||
#define MAX_TABLES 2
|
#define MAX_LOCK_METHODS 2
|
||||||
|
|
||||||
#define INVALID_TABLEID 0
|
#define INVALID_TABLEID 0
|
||||||
|
|
||||||
/*typedef struct LOCK LOCK; */
|
/*typedef struct LOCK LOCK; */
|
||||||
|
|
||||||
|
|
||||||
typedef struct ltag
|
typedef struct LTAG
|
||||||
{
|
{
|
||||||
Oid relId;
|
Oid relId;
|
||||||
Oid dbId;
|
Oid dbId;
|
||||||
@ -67,31 +66,31 @@ typedef struct ltag
|
|||||||
/* This is the control structure for a lock table. It
|
/* This is the control structure for a lock table. It
|
||||||
* lives in shared memory:
|
* lives in shared memory:
|
||||||
*
|
*
|
||||||
* tableID -- the handle used by the lock table's clients to
|
* lockmethod -- the handle used by the lock table's clients to
|
||||||
* refer to the table.
|
* refer to the type of lock table being used.
|
||||||
*
|
*
|
||||||
* nLockTypes -- number of lock types (READ,WRITE,etc) that
|
* numLockModes -- number of lock types (READ,WRITE,etc) that
|
||||||
* are defined on this lock table
|
* are defined on this lock table
|
||||||
*
|
*
|
||||||
* conflictTab -- this is an array of bitmasks showing lock
|
* conflictTab -- this is an array of bitmasks showing lock
|
||||||
* type conflicts. conflictTab[i] is a mask with the j-th bit
|
* type conflicts. conflictTab[i] is a mask with the j-th bit
|
||||||
* turned on if lock types i and j conflict.
|
* turned on if lock types i and j conflict.
|
||||||
*
|
*
|
||||||
* prio -- each locktype has a priority, so, for example, waiting
|
* prio -- each lockmode has a priority, so, for example, waiting
|
||||||
* writers can be given priority over readers (to avoid
|
* writers can be given priority over readers (to avoid
|
||||||
* starvation).
|
* starvation).
|
||||||
*
|
*
|
||||||
* masterlock -- synchronizes access to the table
|
* masterlock -- synchronizes access to the table
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct lockctl
|
typedef struct LOCKMETHODCTL
|
||||||
{
|
{
|
||||||
LockTableId tableId;
|
LOCKMETHOD lockmethod;
|
||||||
int nLockTypes;
|
int numLockModes;
|
||||||
int conflictTab[MAX_LOCKTYPES];
|
int conflictTab[MAX_LOCKMODES];
|
||||||
int prio[MAX_LOCKTYPES];
|
int prio[MAX_LOCKMODES];
|
||||||
SPINLOCK masterLock;
|
SPINLOCK masterLock;
|
||||||
} LOCKCTL;
|
} LOCKMETHODCTL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lockHash -- hash table on lock Ids,
|
* lockHash -- hash table on lock Ids,
|
||||||
@ -99,12 +98,12 @@ typedef struct lockctl
|
|||||||
* multiple processes are holding the lock
|
* multiple processes are holding the lock
|
||||||
* ctl - control structure described above.
|
* ctl - control structure described above.
|
||||||
*/
|
*/
|
||||||
typedef struct ltable
|
typedef struct LOCKMETHODTABLE
|
||||||
{
|
{
|
||||||
HTAB *lockHash;
|
HTAB *lockHash;
|
||||||
HTAB *xidHash;
|
HTAB *xidHash;
|
||||||
LOCKCTL *ctl;
|
LOCKMETHODCTL *ctl;
|
||||||
} LOCKTAB;
|
} LOCKMETHODTABLE;
|
||||||
|
|
||||||
/* -----------------------
|
/* -----------------------
|
||||||
* A transaction never conflicts with its own locks. Hence, if
|
* A transaction never conflicts with its own locks. Hence, if
|
||||||
@ -148,7 +147,7 @@ typedef struct XIDLookupEnt
|
|||||||
XIDTAG tag;
|
XIDTAG tag;
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
int holders[MAX_LOCKTYPES];
|
int holders[MAX_LOCKMODES];
|
||||||
int nHolding;
|
int nHolding;
|
||||||
SHM_QUEUE queue;
|
SHM_QUEUE queue;
|
||||||
} XIDLookupEnt;
|
} XIDLookupEnt;
|
||||||
@ -156,7 +155,7 @@ typedef struct XIDLookupEnt
|
|||||||
#define XID_TAGSIZE (sizeof(XIDTAG))
|
#define XID_TAGSIZE (sizeof(XIDTAG))
|
||||||
|
|
||||||
/* originally in procq.h */
|
/* originally in procq.h */
|
||||||
typedef struct procQueue
|
typedef struct PROC_QUEUE
|
||||||
{
|
{
|
||||||
SHM_QUEUE links;
|
SHM_QUEUE links;
|
||||||
int size;
|
int size;
|
||||||
@ -174,7 +173,7 @@ typedef struct procQueue
|
|||||||
* lock.
|
* lock.
|
||||||
* nHolding -- total locks of all types.
|
* nHolding -- total locks of all types.
|
||||||
*/
|
*/
|
||||||
typedef struct Lock
|
typedef struct LOCK
|
||||||
{
|
{
|
||||||
/* hash key */
|
/* hash key */
|
||||||
LOCKTAG tag;
|
LOCKTAG tag;
|
||||||
@ -182,18 +181,18 @@ typedef struct Lock
|
|||||||
/* data */
|
/* data */
|
||||||
int mask;
|
int mask;
|
||||||
PROC_QUEUE waitProcs;
|
PROC_QUEUE waitProcs;
|
||||||
int holders[MAX_LOCKTYPES];
|
int holders[MAX_LOCKMODES];
|
||||||
int nHolding;
|
int nHolding;
|
||||||
int activeHolders[MAX_LOCKTYPES];
|
int activeHolders[MAX_LOCKMODES];
|
||||||
int nActive;
|
int nActive;
|
||||||
} LOCK;
|
} LOCK;
|
||||||
|
|
||||||
#define LockGetLock_nHolders(l) l->nHolders
|
#define LockGetLock_nHolders(l) l->nHolders
|
||||||
|
|
||||||
#define LockDecrWaitHolders(lock, locktype) \
|
#define LockDecrWaitHolders(lock, lockmode) \
|
||||||
( \
|
( \
|
||||||
lock->nHolding--, \
|
lock->nHolding--, \
|
||||||
lock->holders[locktype]-- \
|
lock->holders[lockmode]-- \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define LockLockTable() SpinAcquire(LockMgrLock);
|
#define LockLockTable() SpinAcquire(LockMgrLock);
|
||||||
@ -206,16 +205,16 @@ extern SPINLOCK LockMgrLock;
|
|||||||
*/
|
*/
|
||||||
extern void InitLocks(void);
|
extern void InitLocks(void);
|
||||||
extern void LockDisable(int status);
|
extern void LockDisable(int status);
|
||||||
extern LockTableId
|
extern LOCKMETHOD
|
||||||
LockTableInit(char *tabName, MASK *conflictsP, int *prioP,
|
LockMethodTableInit(char *tabName, MASK *conflictsP, int *prioP,
|
||||||
int ntypes);
|
int numModes);
|
||||||
extern bool LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype);
|
extern bool LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode);
|
||||||
extern int
|
extern int
|
||||||
LockResolveConflicts(LOCKTAB *ltable, LOCK *lock, LOCKTYPE locktype,
|
LockResolveConflicts(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode,
|
||||||
TransactionId xid);
|
TransactionId xid);
|
||||||
extern bool LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKTYPE locktype);
|
extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode);
|
||||||
extern void GrantLock(LOCK *lock, LOCKTYPE locktype);
|
extern void GrantLock(LOCK *lock, LOCKMODE lockmode);
|
||||||
extern bool LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue);
|
extern bool LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue);
|
||||||
extern int LockShmemSize(void);
|
extern int LockShmemSize(void);
|
||||||
extern bool LockingDisabled(void);
|
extern bool LockingDisabled(void);
|
||||||
extern bool DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check);
|
extern bool DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: multilev.h,v 1.9 1998/06/28 21:17:36 momjian Exp $
|
* $Id: multilev.h,v 1.10 1998/06/30 02:33:33 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -43,16 +43,18 @@ typedef int PG_LOCK_LEVEL;
|
|||||||
|
|
||||||
/* multi.c */
|
/* multi.c */
|
||||||
|
|
||||||
extern LockTableId MultiTableId;
|
extern LOCKMETHOD MultiTableId;
|
||||||
extern LockTableId ShortTermTableId;
|
#ifdef NOT_USED
|
||||||
|
extern LOCKMETHOD ShortTermTableId;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* function prototypes
|
* function prototypes
|
||||||
*/
|
*/
|
||||||
extern LockTableId InitMultiLevelLocks(void);
|
extern LOCKMETHOD InitMultiLevelLocks(void);
|
||||||
extern bool MultiLockReln(LockInfo linfo, LOCKTYPE locktype);
|
extern bool MultiLockReln(LockInfo linfo, LOCKMODE lockmode);
|
||||||
extern bool MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype);
|
extern bool MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKMODE lockmode);
|
||||||
extern bool MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKTYPE locktype);
|
extern bool MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKMODE lockmode);
|
||||||
extern bool MultiReleaseReln(LockInfo linfo, LOCKTYPE locktype);
|
extern bool MultiReleaseReln(LockInfo linfo, LOCKMODE lockmode);
|
||||||
|
|
||||||
#endif /* MULTILEV_H */
|
#endif /* MULTILEV_H */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: proc.h,v 1.11 1998/02/26 04:43:31 momjian Exp $
|
* $Id: proc.h,v 1.12 1998/06/30 02:33:33 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -100,7 +100,7 @@ extern void ProcQueueInit(PROC_QUEUE *queue);
|
|||||||
extern int
|
extern int
|
||||||
ProcSleep(PROC_QUEUE *queue, SPINLOCK spinlock, int token,
|
ProcSleep(PROC_QUEUE *queue, SPINLOCK spinlock, int token,
|
||||||
int prio, LOCK *lock);
|
int prio, LOCK *lock);
|
||||||
extern int ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock);
|
extern int ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock);
|
||||||
extern void ProcAddLock(SHM_QUEUE *elem);
|
extern void ProcAddLock(SHM_QUEUE *elem);
|
||||||
extern void ProcReleaseSpins(PROC *proc);
|
extern void ProcReleaseSpins(PROC *proc);
|
||||||
extern void ProcFreeAllSemaphores(void);
|
extern void ProcFreeAllSemaphores(void);
|
||||||
|
@ -25,13 +25,13 @@ structure, like
|
|||||||
The query is then identified as a <I>Utility</I> function or a more
|
The query is then identified as a <I>Utility</I> function or a more
|
||||||
complex query. A <I>Utility</I> query is processed by a
|
complex query. A <I>Utility</I> query is processed by a
|
||||||
query-specific function in <A HREF="../../backend/commands">
|
query-specific function in <A HREF="../../backend/commands">
|
||||||
commands.</A> A complex query, like <B>SELECT, UPDATE,</B> and
|
commands.</A> A complex query, like <CODE>SELECT, UPDATE,</CODE> and
|
||||||
<B>DELETE</B> requires much more handling.
|
<CODE>DELETE</CODE> requires much more handling.
|
||||||
<P>
|
<P>
|
||||||
The parser takes a complex query, and creates a
|
The parser takes a complex query, and creates a
|
||||||
<A HREF="../../include/nodes/parsenodes.h">Query</A> structure that
|
<A HREF="../../include/nodes/parsenodes.h">Query</A> structure that
|
||||||
contains all the elements used by complex queries. Query.qual holds the
|
contains all the elements used by complex queries. Query.qual holds the
|
||||||
<B>WHERE</B> clause qualification, which is filled in by
|
<CODE>WHERE</CODE> clause qualification, which is filled in by
|
||||||
<A HREF="../../backend/parser/parse_clause.c">transformWhereClause().</A>
|
<A HREF="../../backend/parser/parse_clause.c">transformWhereClause().</A>
|
||||||
Each table referenced in the query is represented by a <A
|
Each table referenced in the query is represented by a <A
|
||||||
HREF="../../include/nodes/parsenodes.h"> RangeTableEntry,</A> and they
|
HREF="../../include/nodes/parsenodes.h"> RangeTableEntry,</A> and they
|
||||||
@ -39,19 +39,19 @@ are linked together to form the <I>range table</I> of the query, which is
|
|||||||
generated by <A HREF="../../backend/parser/parse_clause.c">
|
generated by <A HREF="../../backend/parser/parse_clause.c">
|
||||||
makeRangeTable().</A> Query.rtable holds the queries range table.
|
makeRangeTable().</A> Query.rtable holds the queries range table.
|
||||||
<P>
|
<P>
|
||||||
Certain queries, like <B>SELECT,</B> return columns of data. Other
|
Certain queries, like <CODE>SELECT,</CODE> return columns of data. Other
|
||||||
queries, like <B>INSERT</B> and <B>UPDATE,</B> specify the columns
|
queries, like <CODE>INSERT</CODE> and <CODE>UPDATE,</CODE> specify the columns
|
||||||
modified by the query. These column references are converted to <A
|
modified by the query. These column references are converted to <A
|
||||||
HREF="../../include/nodes/primnodes.h">Resdom</A> entries, which are
|
HREF="../../include/nodes/primnodes.h">Resdom</A> entries, which are
|
||||||
linked together to make up the <I>target list</I> of the query. The
|
linked together to make up the <I>target list</I> of the query. The
|
||||||
target list is stored in Query.targetList, which is generated by
|
target list is stored in Query.targetList, which is generated by
|
||||||
<A HREF="../../backend/parser/parse_target.c">transformTargetList().</A>
|
<A HREF="../../backend/parser/parse_target.c">transformTargetList().</A>
|
||||||
<P>
|
<P>
|
||||||
Other query elements, like aggregates(<B>SUM()</B>), <B>GROUP BY,</B>
|
Other query elements, like aggregates(<CODE>SUM()</CODE>), <CODE>GROUP BY,</CODE>
|
||||||
<B>ORDER BY</B> are also stored in their own Query fields.
|
<CODE>ORDER BY</CODE> are also stored in their own Query fields.
|
||||||
<P>
|
<P>
|
||||||
The next step is for the Query to be modified by any <B>VIEWS</B> or
|
The next step is for the Query to be modified by any <CODE>VIEWS</CODE> or
|
||||||
<B>RULES</B> that may apply to the query. This is performed by the <A
|
<CODE>RULES</CODE> that may apply to the query. This is performed by the <A
|
||||||
HREF="../../backend/rewrite">rewrite</A> system.
|
HREF="../../backend/rewrite">rewrite</A> system.
|
||||||
<P>
|
<P>
|
||||||
The <A HREF="../../backend/optimizer">optimizer</A> takes the Query
|
The <A HREF="../../backend/optimizer">optimizer</A> takes the Query
|
||||||
@ -60,7 +60,7 @@ HREF="../..//include/nodes/plannodes.h">Plan,</A> which contains the
|
|||||||
operations to be performed to execute the query. The <A
|
operations to be performed to execute the query. The <A
|
||||||
HREF="../../backend/optimizer/path">path</A> module determines the best
|
HREF="../../backend/optimizer/path">path</A> module determines the best
|
||||||
table join order and join type of each table in the RangeTable, using
|
table join order and join type of each table in the RangeTable, using
|
||||||
Query.qual(<B>WHERE</B> clause) to consider optimal index usage.
|
Query.qual(<CODE>WHERE</CODE> clause) to consider optimal index usage.
|
||||||
<P>
|
<P>
|
||||||
The Plan is then passed to the <A
|
The Plan is then passed to the <A
|
||||||
HREF="../../backend/executor">executor</A> for execution, and the result
|
HREF="../../backend/executor">executor</A> for execution, and the result
|
||||||
@ -81,13 +81,23 @@ data/index buffer cache block
|
|||||||
<LI>Shared Buf Lookup Table - lookup of buffer cache block address using
|
<LI>Shared Buf Lookup Table - lookup of buffer cache block address using
|
||||||
table name and block number(<A HREF="../../include/storage/buf_internals.h">
|
table name and block number(<A HREF="../../include/storage/buf_internals.h">
|
||||||
BufferTag</A>)
|
BufferTag</A>)
|
||||||
<LI><A HREF="../../include/storage/lock.h">LockTable (ctl)</A> - lock table
|
<LI>MultiLevelLockTable (ctl) - <A
|
||||||
structure, specifiying table, lock types, and backends holding or
|
HREF="../../include/storage/lock.h">LOCKCTL</A> control structure for
|
||||||
waiting on lock
|
each locking method. Currently, only multi-level locking is used.
|
||||||
<LI>LockTable (lock hash) - lookup of LockTable structures using relation,
|
<LI>MultiLevelLockTable (lock hash) - the <A
|
||||||
database object ids
|
HREF="../../include/storage/lock.h">LOCK</A> structure, looked up using
|
||||||
<LI>LockTable (xid hash) - lookup of LockTable structures using
|
relation, database object ids(<A
|
||||||
transaction id, LockTable address
|
HREF="../../include/storage/lock.h">LOCKTAG)</A>. The lock table structure contains the
|
||||||
|
lock modes(read, write) and circular linked list of backends (<A
|
||||||
|
HREF="../../include/storage/proc.h">PROC</A> structure pointers) waiting
|
||||||
|
on the lock.
|
||||||
|
<LI>MultiLevelLockTable (xid hash) - lookup of LOCK structure address
|
||||||
|
using transaction id, LOCK address. It is used to quickly check if the
|
||||||
|
current transaction already has any locks on a table, rather than having
|
||||||
|
to search through all the held locks. It also stores the modes
|
||||||
|
(read/write) of the locks held by the current transaction. The returned
|
||||||
|
<A HREF="../../include/storage/lock.h">XIDLookupEnt</A> structure also
|
||||||
|
contains a pointer to the backend's PROC.lockQueue.
|
||||||
<LI><A HREF="../../include/storage/proc.h">Proc Header</A> - information
|
<LI><A HREF="../../include/storage/proc.h">Proc Header</A> - information
|
||||||
about each backend, including locks held/waiting, indexed by process id
|
about each backend, including locks held/waiting, indexed by process id
|
||||||
</UL>
|
</UL>
|
||||||
|
Reference in New Issue
Block a user