mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
From: Massimo Dal Zotto <dz@cs.unitn.it>
lock.patch I have rewritten lock.c cleaning up the code and adding better assert checking I have also added some fields to the lock and xid tags for better support of user locks. There is also a new function which returns an array of pids owning a lock. I'm using this code from over six months and it works fine.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.22 1998/08/19 02:02:44 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.23 1998/08/25 21:20:28 scrappy 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
|
||||||
@ -29,12 +29,10 @@
|
|||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "miscadmin.h" /* MyDatabaseId */
|
#include "miscadmin.h" /* MyDatabaseId */
|
||||||
|
|
||||||
static bool
|
static bool MultiAcquire(LOCKMETHOD lockmethod, LOCKTAG *tag,
|
||||||
MultiAcquire(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
LOCKMODE lockmode, PG_LOCK_LEVEL level);
|
||||||
PG_LOCK_LEVEL level);
|
static bool MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag,
|
||||||
static bool
|
LOCKMODE lockmode, PG_LOCK_LEVEL level);
|
||||||
MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
|
||||||
PG_LOCK_LEVEL level);
|
|
||||||
|
|
||||||
#ifdef LowLevelLocking
|
#ifdef LowLevelLocking
|
||||||
|
|
||||||
@ -130,6 +128,7 @@ static int MultiPrios[] = {
|
|||||||
* lock table is ONE lock table, not three.
|
* lock table is ONE lock table, not three.
|
||||||
*/
|
*/
|
||||||
LOCKMETHOD MultiTableId = (LOCKMETHOD) NULL;
|
LOCKMETHOD MultiTableId = (LOCKMETHOD) NULL;
|
||||||
|
LOCKMETHOD LongTermTableId = (LOCKMETHOD) NULL;
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
LOCKMETHOD ShortTermTableId = (LOCKMETHOD) NULL;
|
LOCKMETHOD ShortTermTableId = (LOCKMETHOD) NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -150,12 +149,25 @@ InitMultiLevelLocks()
|
|||||||
/* -----------------------
|
/* -----------------------
|
||||||
* No short term lock table for now. -Jeff 15 July 1991
|
* No short term lock table for now. -Jeff 15 July 1991
|
||||||
*
|
*
|
||||||
* ShortTermTableId = LockTableRename(lockmethod);
|
* ShortTermTableId = LockMethodTableRename(lockmethod);
|
||||||
* if (! (ShortTermTableId)) {
|
* if (! (ShortTermTableId)) {
|
||||||
* elog(ERROR,"InitMultiLocks: couldnt rename lock table");
|
* elog(ERROR,"InitMultiLocks: couldnt rename lock table");
|
||||||
* }
|
* }
|
||||||
* -----------------------
|
* -----------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef USER_LOCKS
|
||||||
|
/*
|
||||||
|
* Allocate another tableId for long-term locks
|
||||||
|
*/
|
||||||
|
LongTermTableId = LockMethodTableRename(MultiTableId);
|
||||||
|
if (!(LongTermTableId))
|
||||||
|
{
|
||||||
|
elog(ERROR,
|
||||||
|
"InitMultiLevelLocks: couldn't rename long-term lock table");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return MultiTableId;
|
return MultiTableId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.40 1998/07/27 19:38:15 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.41 1998/08/25 21:20:29 scrappy 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.40 1998/07/27 19:38:15 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.41 1998/08/25 21:20:29 scrappy Exp $
|
||||||
*/
|
*/
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -75,10 +75,13 @@
|
|||||||
#include "storage/shmem.h"
|
#include "storage/shmem.h"
|
||||||
#include "storage/spin.h"
|
#include "storage/spin.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
|
#include "utils/trace.h"
|
||||||
|
|
||||||
static void HandleDeadLock(int sig);
|
static void HandleDeadLock(int sig);
|
||||||
static PROC *ProcWakeup(PROC *proc, int errType);
|
static PROC *ProcWakeup(PROC *proc, int errType);
|
||||||
|
|
||||||
|
#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
|
||||||
|
|
||||||
/* --------------------
|
/* --------------------
|
||||||
* Spin lock for manipulating the shared process data structure:
|
* Spin lock for manipulating the shared process data structure:
|
||||||
* ProcGlobal.... Adding an extra spin lock seemed like the smallest
|
* ProcGlobal.... Adding an extra spin lock seemed like the smallest
|
||||||
@ -247,10 +250,7 @@ InitProcess(IPCKey key)
|
|||||||
*/
|
*/
|
||||||
SpinRelease(ProcStructLock);
|
SpinRelease(ProcStructLock);
|
||||||
|
|
||||||
MyProc->pid = 0;
|
|
||||||
#if 0
|
|
||||||
MyProc->pid = MyProcPid;
|
MyProc->pid = MyProcPid;
|
||||||
#endif
|
|
||||||
MyProc->xid = InvalidTransactionId;
|
MyProc->xid = InvalidTransactionId;
|
||||||
#ifdef LowLevelLocking
|
#ifdef LowLevelLocking
|
||||||
MyProc->xmin = InvalidTransactionId;
|
MyProc->xmin = InvalidTransactionId;
|
||||||
@ -361,10 +361,13 @@ ProcKill(int exitStatus, int pid)
|
|||||||
* ---------------
|
* ---------------
|
||||||
*/
|
*/
|
||||||
ProcReleaseSpins(proc);
|
ProcReleaseSpins(proc);
|
||||||
LockReleaseAll(1, &proc->lockQueue);
|
LockReleaseAll(DEFAULT_LOCKMETHOD, &proc->lockQueue);
|
||||||
|
|
||||||
#ifdef USER_LOCKS
|
#ifdef USER_LOCKS
|
||||||
LockReleaseAll(0, &proc->lockQueue);
|
/*
|
||||||
|
* Assume we have a second lock table.
|
||||||
|
*/
|
||||||
|
LockReleaseAll(USER_LOCKMETHOD, &proc->lockQueue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -437,11 +440,12 @@ ProcQueueInit(PROC_QUEUE *queue)
|
|||||||
* NOTES: The process queue is now a priority queue for locking.
|
* NOTES: The process queue is now a priority queue for locking.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ProcSleep(PROC_QUEUE *waitQueue,
|
ProcSleep(PROC_QUEUE *waitQueue, /* lock->waitProcs */
|
||||||
SPINLOCK spinlock,
|
SPINLOCK spinlock,
|
||||||
int token,
|
int token, /* lockmode */
|
||||||
int prio,
|
int prio,
|
||||||
LOCK *lock)
|
LOCK *lock,
|
||||||
|
TransactionId xid) /* needed by user locks, see below */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
@ -470,7 +474,6 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
proc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
proc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
||||||
|
|
||||||
/* If we are a reader, and they are writers, skip past them */
|
/* If we are a reader, and they are writers, skip past them */
|
||||||
|
|
||||||
for (i = 0; i < waitQueue->size && proc->prio > prio; i++)
|
for (i = 0; i < waitQueue->size && proc->prio > prio; i++)
|
||||||
proc = (PROC *) MAKE_PTR(proc->links.prev);
|
proc = (PROC *) MAKE_PTR(proc->links.prev);
|
||||||
|
|
||||||
@ -482,12 +485,22 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
MyProc->token = token;
|
MyProc->token = token;
|
||||||
MyProc->waitLock = lock;
|
MyProc->waitLock = lock;
|
||||||
|
|
||||||
|
#ifdef USER_LOCKS
|
||||||
|
/* -------------------
|
||||||
|
* Currently, we only need this for the ProcWakeup routines.
|
||||||
|
* This must be 0 for user lock, so we can't just use the value
|
||||||
|
* from GetCurrentTransactionId().
|
||||||
|
* -------------------
|
||||||
|
*/
|
||||||
|
TransactionIdStore(xid, &MyProc->xid);
|
||||||
|
#else
|
||||||
#ifndef LowLevelLocking
|
#ifndef LowLevelLocking
|
||||||
/* -------------------
|
/* -------------------
|
||||||
* currently, we only need this for the ProcWakeup routines
|
* currently, we only need this for the ProcWakeup routines
|
||||||
* -------------------
|
* -------------------
|
||||||
*/
|
*/
|
||||||
TransactionIdStore((TransactionId) GetCurrentTransactionId(), &MyProc->xid);
|
TransactionIdStore((TransactionId) GetCurrentTransactionId(), &MyProc->xid);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* -------------------
|
/* -------------------
|
||||||
@ -510,7 +523,8 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
* --------------
|
* --------------
|
||||||
*/
|
*/
|
||||||
MemSet(&timeval, 0, sizeof(struct itimerval));
|
MemSet(&timeval, 0, sizeof(struct itimerval));
|
||||||
timeval.it_value.tv_sec = DEADLOCK_CHECK_TIMER;
|
timeval.it_value.tv_sec = \
|
||||||
|
(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -525,7 +539,8 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
* the semaphore implementation.
|
* the semaphore implementation.
|
||||||
* --------------
|
* --------------
|
||||||
*/
|
*/
|
||||||
IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
|
IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum,
|
||||||
|
IpcExclusiveLock);
|
||||||
} while (MyProc->errType == STATUS_NOT_FOUND); /* sleep after deadlock
|
} while (MyProc->errType == STATUS_NOT_FOUND); /* sleep after deadlock
|
||||||
* check */
|
* check */
|
||||||
|
|
||||||
@ -534,8 +549,6 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
* ---------------
|
* ---------------
|
||||||
*/
|
*/
|
||||||
timeval.it_value.tv_sec = 0;
|
timeval.it_value.tv_sec = 0;
|
||||||
|
|
||||||
|
|
||||||
if (setitimer(ITIMER_REAL, &timeval, &dummy))
|
if (setitimer(ITIMER_REAL, &timeval, &dummy))
|
||||||
elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
|
elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
|
||||||
|
|
||||||
@ -546,6 +559,11 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
|||||||
*/
|
*/
|
||||||
SpinAcquire(spinlock);
|
SpinAcquire(spinlock);
|
||||||
|
|
||||||
|
#ifdef LOCK_MGR_DEBUG
|
||||||
|
/* Just to get meaningful debug messages from DumpLocks() */
|
||||||
|
MyProc->waitLock = (LOCK *)NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
return (MyProc->errType);
|
return (MyProc->errType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,17 +607,39 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
|
|||||||
{
|
{
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
int count;
|
int count;
|
||||||
|
int trace_flag;
|
||||||
|
int last_locktype = -1;
|
||||||
|
int queue_size = queue->size;
|
||||||
|
|
||||||
|
Assert(queue->size >= 0);
|
||||||
|
|
||||||
if (!queue->size)
|
if (!queue->size)
|
||||||
return (STATUS_NOT_FOUND);
|
return (STATUS_NOT_FOUND);
|
||||||
|
|
||||||
proc = (PROC *) MAKE_PTR(queue->links.prev);
|
proc = (PROC *) MAKE_PTR(queue->links.prev);
|
||||||
count = 0;
|
count = 0;
|
||||||
while ((LockResolveConflicts(lockmethod,
|
while ((queue_size--) && (proc))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This proc will conflict as the previous one did, don't even try.
|
||||||
|
*/
|
||||||
|
if (proc->token == last_locktype)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This proc conflicts with locks held by others, ignored.
|
||||||
|
*/
|
||||||
|
if (LockResolveConflicts(lockmethod,
|
||||||
lock,
|
lock,
|
||||||
proc->token,
|
proc->token,
|
||||||
proc->xid) == STATUS_OK))
|
proc->xid,
|
||||||
|
(XIDLookupEnt *) NULL) != STATUS_OK)
|
||||||
{
|
{
|
||||||
|
last_locktype = proc->token;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* there was a waiting process, grant it the lock before waking it
|
* there was a waiting process, grant it the lock before waking it
|
||||||
@ -608,25 +648,35 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
|
|||||||
* time that the awoken process begins executing again.
|
* time that the awoken process begins executing again.
|
||||||
*/
|
*/
|
||||||
GrantLock(lock, proc->token);
|
GrantLock(lock, proc->token);
|
||||||
queue->size--;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcWakeup removes proc from the lock waiting process queue and
|
* ProcWakeup removes proc from the lock waiting process queue and
|
||||||
* returns the next proc in chain.
|
* returns the next proc in chain.
|
||||||
*/
|
*/
|
||||||
proc = ProcWakeup(proc, NO_ERROR);
|
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if (!proc || queue->size == 0)
|
queue->size--;
|
||||||
break;
|
proc = ProcWakeup(proc, NO_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Assert(queue->size >= 0);
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
return (STATUS_OK);
|
return (STATUS_OK);
|
||||||
else
|
else {
|
||||||
/* Something is still blocking us. May have deadlocked. */
|
/* Something is still blocking us. May have deadlocked. */
|
||||||
|
trace_flag = (lock->tag.lockmethod == USER_LOCKMETHOD) ? \
|
||||||
|
TRACE_USERLOCKS : TRACE_LOCKS;
|
||||||
|
TPRINTF(trace_flag,
|
||||||
|
"ProcLockWakeup: lock(%x) can't wake up any process",
|
||||||
|
MAKE_OFFSET(lock));
|
||||||
|
#ifdef DEADLOCK_DEBUG
|
||||||
|
if (pg_options[trace_flag] >= 2)
|
||||||
|
DumpAllLocks();
|
||||||
|
#endif
|
||||||
return (STATUS_NOT_FOUND);
|
return (STATUS_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcAddLock(SHM_QUEUE *elem)
|
ProcAddLock(SHM_QUEUE *elem)
|
||||||
@ -685,7 +735,7 @@ HandleDeadLock(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEADLOCK_DEBUG
|
#ifdef DEADLOCK_DEBUG
|
||||||
DumpLocks();
|
DumpAllLocks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!DeadLockCheck(&(MyProc->lockQueue), MyProc->waitLock, true))
|
if (!DeadLockCheck(&(MyProc->lockQueue), MyProc->waitLock, true))
|
||||||
@ -711,7 +761,8 @@ HandleDeadLock(int sig)
|
|||||||
* I was awoken by a signal, not by someone unlocking my semaphore.
|
* I was awoken by a signal, not by someone unlocking my semaphore.
|
||||||
* ------------------
|
* ------------------
|
||||||
*/
|
*/
|
||||||
IpcSemaphoreUnlock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
|
IpcSemaphoreUnlock(MyProc->sem.semId, MyProc->sem.semNum,
|
||||||
|
IpcExclusiveLock);
|
||||||
|
|
||||||
/* -------------
|
/* -------------
|
||||||
* Set MyProc->errType to STATUS_ERROR so that we abort after
|
* Set MyProc->errType to STATUS_ERROR so that we abort after
|
||||||
|
@ -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.16 1998/08/01 15:26:37 vadim Exp $
|
* $Id: lock.h,v 1.17 1998/08/25 21:20:31 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include <storage/shmem.h>
|
#include <storage/shmem.h>
|
||||||
#include <storage/itemptr.h>
|
#include <storage/itemptr.h>
|
||||||
|
#include <storage/sinvaladt.h>
|
||||||
|
#include <utils/array.h>
|
||||||
|
|
||||||
extern SPINLOCK LockMgrLock;
|
extern SPINLOCK LockMgrLock;
|
||||||
typedef int MASK;
|
typedef int MASK;
|
||||||
@ -32,7 +34,7 @@ typedef int MASK;
|
|||||||
* NLOCKENTS - The maximum number of lock entries in the lock table.
|
* NLOCKENTS - The maximum number of lock entries in the lock table.
|
||||||
* ----------------------
|
* ----------------------
|
||||||
*/
|
*/
|
||||||
#define NBACKENDS 50
|
#define NBACKENDS MaxBackendId
|
||||||
#define NLOCKS_PER_XACT 40
|
#define NLOCKS_PER_XACT 40
|
||||||
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
|
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
|
||||||
|
|
||||||
@ -51,10 +53,15 @@ typedef int LOCKMETHOD;
|
|||||||
* 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_LOCK_METHODS 2
|
#define MAX_LOCK_METHODS 3
|
||||||
|
|
||||||
#define INVALID_TABLEID 0
|
#define INVALID_TABLEID 0
|
||||||
|
|
||||||
|
#define INVALID_LOCKMETHOD INVALID_TABLEID
|
||||||
|
#define DEFAULT_LOCKMETHOD 1
|
||||||
|
#define USER_LOCKMETHOD 2
|
||||||
|
#define MIN_LOCKMETHOD DEFAULT_LOCKMETHOD
|
||||||
|
|
||||||
/*typedef struct LOCK LOCK; */
|
/*typedef struct LOCK LOCK; */
|
||||||
|
|
||||||
|
|
||||||
@ -63,9 +70,11 @@ typedef struct LTAG
|
|||||||
Oid relId;
|
Oid relId;
|
||||||
Oid dbId;
|
Oid dbId;
|
||||||
ItemPointerData tupleId;
|
ItemPointerData tupleId;
|
||||||
|
uint16 lockmethod; /* needed by user locks */
|
||||||
} LOCKTAG;
|
} LOCKTAG;
|
||||||
|
|
||||||
#define TAGSIZE (sizeof(LOCKTAG))
|
#define TAGSIZE (sizeof(LOCKTAG))
|
||||||
|
#define LOCKTAG_LOCKMETHOD(locktag) ((locktag).lockmethod)
|
||||||
|
|
||||||
/* 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:
|
||||||
@ -143,8 +152,18 @@ typedef struct XIDTAG
|
|||||||
SHMEM_OFFSET lock;
|
SHMEM_OFFSET lock;
|
||||||
int pid;
|
int pid;
|
||||||
TransactionId xid;
|
TransactionId xid;
|
||||||
|
#ifdef USE_XIDTAG_LOCKMETHOD
|
||||||
|
uint16 lockmethod; /* for debug or consistency checking */
|
||||||
|
#endif
|
||||||
} XIDTAG;
|
} XIDTAG;
|
||||||
|
|
||||||
|
#ifdef USE_XIDTAG_LOCKMETHOD
|
||||||
|
#define XIDTAG_LOCKMETHOD(xidtag) ((xidtag).lockmethod)
|
||||||
|
#else
|
||||||
|
#define XIDTAG_LOCKMETHOD(xidtag) \
|
||||||
|
(((LOCK*) MAKE_PTR((xidtag).lock))->tag.lockmethod)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct XIDLookupEnt
|
typedef struct XIDLookupEnt
|
||||||
{
|
{
|
||||||
/* tag */
|
/* tag */
|
||||||
@ -157,6 +176,7 @@ typedef struct XIDLookupEnt
|
|||||||
} XIDLookupEnt;
|
} XIDLookupEnt;
|
||||||
|
|
||||||
#define XID_TAGSIZE (sizeof(XIDTAG))
|
#define XID_TAGSIZE (sizeof(XIDTAG))
|
||||||
|
#define XIDENT_LOCKMETHOD(xident) (XIDTAG_LOCKMETHOD((xident).tag))
|
||||||
|
|
||||||
/* originally in procq.h */
|
/* originally in procq.h */
|
||||||
typedef struct PROC_QUEUE
|
typedef struct PROC_QUEUE
|
||||||
@ -191,14 +211,16 @@ typedef struct LOCK
|
|||||||
int nActive;
|
int nActive;
|
||||||
} LOCK;
|
} LOCK;
|
||||||
|
|
||||||
#define LockGetLock_nHolders(l) l->nHolders
|
#define LOCK_LOCKMETHOD(lock) (LOCKTAG_LOCKMETHOD((lock).tag))
|
||||||
|
|
||||||
|
#define LockGetLock_nHolders(l) l->nHolders
|
||||||
|
#ifdef NOT_USED
|
||||||
#define LockDecrWaitHolders(lock, lockmode) \
|
#define LockDecrWaitHolders(lock, lockmode) \
|
||||||
( \
|
( \
|
||||||
lock->nHolding--, \
|
lock->nHolding--, \
|
||||||
lock->holders[lockmode]-- \
|
lock->holders[lockmode]-- \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
#define LockLockTable() SpinAcquire(LockMgrLock);
|
#define LockLockTable() SpinAcquire(LockMgrLock);
|
||||||
#define UnlockLockTable() SpinRelease(LockMgrLock);
|
#define UnlockLockTable() SpinRelease(LockMgrLock);
|
||||||
|
|
||||||
@ -209,23 +231,27 @@ extern SPINLOCK LockMgrLock;
|
|||||||
*/
|
*/
|
||||||
extern void InitLocks(void);
|
extern void InitLocks(void);
|
||||||
extern void LockDisable(int status);
|
extern void LockDisable(int status);
|
||||||
extern LOCKMETHOD
|
extern LOCKMETHOD LockMethodTableInit(char *tabName, MASK *conflictsP,
|
||||||
LockMethodTableInit(char *tabName, MASK *conflictsP, int *prioP,
|
int *prioP, int numModes);
|
||||||
int numModes);
|
extern LOCKMETHOD LockMethodTableRename(LOCKMETHOD lockmethod);
|
||||||
extern bool LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode);
|
extern bool LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
|
||||||
extern int
|
LOCKMODE lockmode);
|
||||||
LockResolveConflicts(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode,
|
extern int LockResolveConflicts(LOCKMETHOD lockmethod, LOCK *lock,
|
||||||
TransactionId xid);
|
LOCKMODE lockmode, TransactionId xid,
|
||||||
extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode);
|
XIDLookupEnt *xidentP);
|
||||||
|
extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
|
||||||
|
LOCKMODE lockmode);
|
||||||
extern void GrantLock(LOCK *lock, LOCKMODE lockmode);
|
extern void GrantLock(LOCK *lock, LOCKMODE lockmode);
|
||||||
extern bool LockReleaseAll(LOCKMETHOD lockmethod, 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);
|
||||||
|
ArrayType* LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag);
|
||||||
|
|
||||||
#ifdef DEADLOCK_DEBUG
|
#ifdef DEADLOCK_DEBUG
|
||||||
extern void DumpLocks(void);
|
extern void DumpLocks(void);
|
||||||
|
extern void DumpAllLocks(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* LOCK_H */
|
#endif /* LOCK_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.13 1998/07/27 19:38:38 vadim Exp $
|
* $Id: proc.h,v 1.14 1998/08/25 21:20:32 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -105,10 +105,10 @@ extern bool ProcRemove(int pid);
|
|||||||
/* make static in storage/lmgr/proc.c -- jolly */
|
/* make static in storage/lmgr/proc.c -- jolly */
|
||||||
|
|
||||||
extern void ProcQueueInit(PROC_QUEUE *queue);
|
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, TransactionId xid);
|
||||||
int prio, LOCK *lock);
|
extern int ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod,
|
||||||
extern int ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock);
|
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);
|
||||||
|
Reference in New Issue
Block a user