mirror of
https://github.com/postgres/postgres.git
synced 2025-11-06 07:49:08 +03:00
More cleanups of the include files
- centralizing to simplify the -I's required to compile
This commit is contained in:
32
src/include/storage/backendid.h
Normal file
32
src/include/storage/backendid.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* backendid.h--
|
||||
* POSTGRES backend id communication definitions
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: backendid.h,v 1.1 1996/08/28 01:57:54 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BACKENDID_H
|
||||
#define BACKENDID_H
|
||||
|
||||
/* ----------------
|
||||
* pulled out of sinval.h to temporarily reduce #include nesting.
|
||||
* -cim 8/17/90
|
||||
* ----------------
|
||||
*/
|
||||
typedef int16 BackendId; /* unique currently active backend identifier */
|
||||
|
||||
#define InvalidBackendId (-1)
|
||||
|
||||
typedef int32 BackendTag; /* unique backend identifier */
|
||||
|
||||
#define InvalidBackendTag (-1)
|
||||
|
||||
extern BackendId MyBackendId; /* backend id of this backend */
|
||||
extern BackendTag MyBackendTag; /* backend tag of this backend */
|
||||
|
||||
#endif /* BACKENDID_H */
|
||||
114
src/include/storage/block.h
Normal file
114
src/include/storage/block.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* block.h--
|
||||
* POSTGRES disk block definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: block.h,v 1.1 1996/08/28 01:57:55 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BLOCK_H
|
||||
#define BLOCK_H
|
||||
|
||||
#include "c.h"
|
||||
|
||||
/*
|
||||
* BlockNumber:
|
||||
*
|
||||
* each data file (heap or index) is divided into postgres disk blocks
|
||||
* (which may be thought of as the unit of i/o -- a postgres buffer
|
||||
* contains exactly one disk block). the blocks are numbered
|
||||
* sequentially, 0 to 0xFFFFFFFE.
|
||||
*
|
||||
* InvalidBlockNumber is the same thing as P_NEW in buf.h.
|
||||
*
|
||||
* the access methods, the buffer manager and the storage manager are
|
||||
* more or less the only pieces of code that should be accessing disk
|
||||
* blocks directly.
|
||||
*/
|
||||
typedef uint32 BlockNumber;
|
||||
|
||||
#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF)
|
||||
|
||||
/*
|
||||
* BlockId:
|
||||
*
|
||||
* this is a storage type for BlockNumber. in other words, this type
|
||||
* is used for on-disk structures (e.g., in HeapTupleData) whereas
|
||||
* BlockNumber is the type on which calculations are performed (e.g.,
|
||||
* in access method code).
|
||||
*
|
||||
* there doesn't appear to be any reason to have separate types except
|
||||
* for the fact that BlockIds can be SHORTALIGN'd (and therefore any
|
||||
* structures that contains them, such as ItemPointerData, can also be
|
||||
* SHORTALIGN'd). this is an important consideration for reducing the
|
||||
* space requirements of the line pointer (ItemIdData) array on each
|
||||
* page and the header of each heap or index tuple, so it doesn't seem
|
||||
* wise to change this without good reason.
|
||||
*/
|
||||
typedef struct BlockIdData {
|
||||
uint16 bi_hi;
|
||||
uint16 bi_lo;
|
||||
} BlockIdData;
|
||||
|
||||
typedef BlockIdData *BlockId; /* block identifier */
|
||||
|
||||
/* ----------------
|
||||
* support macros
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* BlockNumberIsValid --
|
||||
* True iff blockNumber is valid.
|
||||
*/
|
||||
#define BlockNumberIsValid(blockNumber) \
|
||||
((bool) ((int32) (blockNumber) != InvalidBlockNumber))
|
||||
|
||||
/*
|
||||
* BlockIdIsValid --
|
||||
* True iff the block identifier is valid.
|
||||
*/
|
||||
#define BlockIdIsValid(blockId) \
|
||||
((bool) PointerIsValid(blockId))
|
||||
|
||||
/*
|
||||
* BlockIdSet --
|
||||
* Sets a block identifier to the specified value.
|
||||
*/
|
||||
#define BlockIdSet(blockId, blockNumber) \
|
||||
Assert(PointerIsValid(blockId)); \
|
||||
(blockId)->bi_hi = (blockNumber) >> 16; \
|
||||
(blockId)->bi_lo = (blockNumber) & 0xffff
|
||||
|
||||
/*
|
||||
* BlockIdCopy --
|
||||
* Copy a block identifier.
|
||||
*/
|
||||
#define BlockIdCopy(toBlockId, fromBlockId) \
|
||||
Assert(PointerIsValid(toBlockId)); \
|
||||
Assert(PointerIsValid(fromBlockId)); \
|
||||
(toBlockId)->bi_hi = (fromBlockId)->bi_hi; \
|
||||
(toBlockId)->bi_lo = (fromBlockId)->bi_lo
|
||||
|
||||
/*
|
||||
* BlockIdEquals --
|
||||
* Check for block number equality.
|
||||
*/
|
||||
#define BlockIdEquals(blockId1, blockId2) \
|
||||
((blockId1)->bi_hi == (blockId2)->bi_hi && \
|
||||
(blockId1)->bi_lo == (blockId2)->bi_lo)
|
||||
|
||||
/*
|
||||
* BlockIdGetBlockNumber --
|
||||
* Retrieve the block number from a block identifier.
|
||||
*/
|
||||
#define BlockIdGetBlockNumber(blockId) \
|
||||
(AssertMacro(BlockIdIsValid(blockId)) ? \
|
||||
(BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) : \
|
||||
(BlockNumber) InvalidBlockNumber)
|
||||
|
||||
#endif /* BLOCK_H */
|
||||
47
src/include/storage/buf.h
Normal file
47
src/include/storage/buf.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* buf.h--
|
||||
* Basic buffer manager data types.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: buf.h,v 1.1 1996/08/28 01:57:57 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BUF_H
|
||||
#define BUF_H
|
||||
|
||||
#define InvalidBuffer (0)
|
||||
#define UnknownBuffer (-99999)
|
||||
|
||||
typedef long Buffer;
|
||||
|
||||
/*
|
||||
* BufferIsInvalid --
|
||||
* True iff the buffer is invalid.
|
||||
*/
|
||||
#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer)
|
||||
|
||||
/*
|
||||
* BufferIsUnknown --
|
||||
* True iff the buffer is unknown.
|
||||
*/
|
||||
#define BufferIsUnknown(buffer) ((buffer) == UnknownBuffer)
|
||||
|
||||
/*
|
||||
* BufferIsLocal --
|
||||
* True iff the buffer is local (not visible to other servers).
|
||||
*/
|
||||
#define BufferIsLocal(buffer) ((buffer) < 0)
|
||||
|
||||
/*
|
||||
* If NO_BUFFERISVALID is defined, all error checking using BufferIsValid()
|
||||
* are suppressed. Decision-making using BufferIsValid is not affected.
|
||||
* This should be set only if one is sure there will be no errors.
|
||||
* - plai 9/10/90
|
||||
*/
|
||||
#undef NO_BUFFERISVALID
|
||||
|
||||
#endif /* BUF_H */
|
||||
244
src/include/storage/buf_internals.h
Normal file
244
src/include/storage/buf_internals.h
Normal file
@@ -0,0 +1,244 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* buf_internals.h--
|
||||
* Internal definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: buf_internals.h,v 1.1 1996/08/28 01:58:00 scrappy Exp $
|
||||
*
|
||||
* NOTE
|
||||
* If BUFFERPAGE0 is defined, then 0 will be used as a
|
||||
* valid buffer page number.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BUFMGR_INTERNALS_H
|
||||
#define BUFMGR_INTERNALS_H
|
||||
|
||||
#include "postgres.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/relcache.h"
|
||||
|
||||
/* Buf Mgr constants */
|
||||
/* in bufmgr.c */
|
||||
extern int NBuffers;
|
||||
extern int Data_Descriptors;
|
||||
extern int Free_List_Descriptor;
|
||||
extern int Lookup_List_Descriptor;
|
||||
extern int Num_Descriptors;
|
||||
|
||||
/*
|
||||
* Flags for buffer descriptors
|
||||
*/
|
||||
#define BM_DIRTY (1 << 0)
|
||||
#define BM_PRIVATE (1 << 1)
|
||||
#define BM_VALID (1 << 2)
|
||||
#define BM_DELETED (1 << 3)
|
||||
#define BM_FREE (1 << 4)
|
||||
#define BM_IO_IN_PROGRESS (1 << 5)
|
||||
#define BM_IO_ERROR (1 << 6)
|
||||
|
||||
typedef bits16 BufFlags;
|
||||
|
||||
typedef struct sbufdesc BufferDesc;
|
||||
typedef struct sbufdesc BufferHdr;
|
||||
typedef struct buftag BufferTag;
|
||||
/* long * so alignment will be correct */
|
||||
typedef long **BufferBlock;
|
||||
|
||||
struct buftag{
|
||||
LRelId relId;
|
||||
BlockNumber blockNum; /* blknum relative to begin of reln */
|
||||
};
|
||||
|
||||
#define CLEAR_BUFFERTAG(a)\
|
||||
(a)->relId.dbId = InvalidOid; \
|
||||
(a)->relId.relId = InvalidOid; \
|
||||
(a)->blockNum = InvalidBlockNumber
|
||||
|
||||
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
||||
{ \
|
||||
(a)->blockNum = xx_blockNum;\
|
||||
(a)->relId = RelationGetLRelId(xx_reln); \
|
||||
}
|
||||
|
||||
#define COPY_BUFFERTAG(a,b)\
|
||||
{ \
|
||||
(a)->blockNum = (b)->blockNum;\
|
||||
LRelIdAssign(*(a),*(b));\
|
||||
}
|
||||
|
||||
#define EQUAL_BUFFERTAG(a,b) \
|
||||
(((a)->blockNum == (b)->blockNum) &&\
|
||||
(OID_Equal((a)->relId.relId,(b)->relId.relId)))
|
||||
|
||||
|
||||
#define BAD_BUFFER_ID(bid) ((bid<1) || (bid>(NBuffers)))
|
||||
#define INVALID_DESCRIPTOR (-3)
|
||||
|
||||
/*
|
||||
* bletch hack -- anyplace that we declare space for relation or
|
||||
* database names, we just use '16', not a symbolic constant, to
|
||||
* specify their lengths. BM_NAMESIZE is the length of these names,
|
||||
* and is used in the buffer manager code. somebody with lots of
|
||||
* spare time should do this for all the other modules, too.
|
||||
*/
|
||||
#define BM_NAMESIZE 16
|
||||
|
||||
/*
|
||||
* struct sbufdesc -- shared buffer cache metadata for a single
|
||||
* shared buffer descriptor.
|
||||
*
|
||||
* We keep the name of the database and relation in which this
|
||||
* buffer appears in order to avoid a catalog lookup on cache
|
||||
* flush if we don't have the reldesc in the cache. It is also
|
||||
* possible that the relation to which this buffer belongs is
|
||||
* not visible to all backends at the time that it gets flushed.
|
||||
* Dbname, relname, dbid, and relid are enough to determine where
|
||||
* to put the buffer, for all storage managers.
|
||||
*/
|
||||
|
||||
struct sbufdesc {
|
||||
Buffer freeNext; /* link for freelist chain */
|
||||
Buffer freePrev;
|
||||
SHMEM_OFFSET data; /* pointer to data in buf pool */
|
||||
|
||||
/* tag and id must be together for table lookup to work */
|
||||
BufferTag tag; /* file/block identifier */
|
||||
int buf_id; /* maps global desc to local desc */
|
||||
|
||||
BufFlags flags; /* described below */
|
||||
int16 bufsmgr; /* storage manager id for buffer */
|
||||
unsigned refcount; /* # of times buffer is pinned */
|
||||
|
||||
char sb_dbname[NAMEDATALEN+1]; /* name of db in which buf belongs */
|
||||
char sb_relname[NAMEDATALEN+1]; /* name of reln */
|
||||
#ifdef HAS_TEST_AND_SET
|
||||
/* can afford a dedicated lock if test-and-set locks are available */
|
||||
slock_t io_in_progress_lock;
|
||||
#endif /* HAS_TEST_AND_SET */
|
||||
|
||||
/*
|
||||
* I padded this structure to a power of 2 (128 bytes on a MIPS) because
|
||||
* BufferDescriptorGetBuffer is called a billion times and it does an
|
||||
* C pointer subtraction (i.e., "x - y" -> array index of x relative
|
||||
* to y, which is calculated using division by struct size). Integer
|
||||
* ".div" hits you for 35 cycles, as opposed to a 1-cycle "sra" ...
|
||||
* this hack cut 10% off of the time to create the Wisconsin database!
|
||||
* It eats up more shared memory, of course, but we're (allegedly)
|
||||
* going to make some of these types bigger soon anyway... -pma 1/2/93
|
||||
*/
|
||||
|
||||
/* NO spinlock */
|
||||
|
||||
#if defined(PORTNAME_ultrix4)
|
||||
char sb_pad[60]; /* no slock_t */
|
||||
#endif /* mips */
|
||||
|
||||
/* HAS_TEST_AND_SET -- platform dependent size */
|
||||
|
||||
#if defined(PORTNAME_aix)
|
||||
char sb_pad[44]; /* typedef unsigned int slock_t; */
|
||||
#endif /* aix */
|
||||
#if defined(PORTNAME_alpha)
|
||||
char sb_pad[40]; /* typedef msemaphore slock_t; */
|
||||
#endif /* alpha */
|
||||
#if defined(PORTNAME_hpux)
|
||||
char sb_pad[44]; /* typedef struct { int sem[4]; } slock_t; */
|
||||
#endif /* hpux */
|
||||
#if defined(PORTNAME_irix5)
|
||||
char sb_pad[44]; /* typedef abilock_t slock_t; */
|
||||
#endif /* irix5 */
|
||||
#if defined(PORTNAME_next)
|
||||
char sb_pad[56]; /* typedef struct mutex slock_t; */
|
||||
#endif /* next */
|
||||
|
||||
/* HAS_TEST_AND_SET -- default 1 byte spinlock */
|
||||
|
||||
#if defined(PORTNAME_BSD44_derived) || \
|
||||
defined(PORTNAME_bsdi) || \
|
||||
defined(PORTNAME_bsdi_2_1) || \
|
||||
defined(PORTNAME_i386_solaris) || \
|
||||
defined(PORTNAME_linux) || \
|
||||
defined(PORTNAME_sparc) || \
|
||||
defined(PORTNAME_sparc_solaris)
|
||||
char sb_pad[56]; /* has slock_t */
|
||||
#endif /* 1 byte slock_t */
|
||||
};
|
||||
|
||||
/*
|
||||
* mao tracing buffer allocation
|
||||
*/
|
||||
|
||||
/*#define BMTRACE*/
|
||||
#ifdef BMTRACE
|
||||
|
||||
typedef struct _bmtrace {
|
||||
int bmt_pid;
|
||||
long bmt_buf;
|
||||
long bmt_dbid;
|
||||
long bmt_relid;
|
||||
int bmt_blkno;
|
||||
int bmt_op;
|
||||
|
||||
#define BMT_NOTUSED 0
|
||||
#define BMT_ALLOCFND 1
|
||||
#define BMT_ALLOCNOTFND 2
|
||||
#define BMT_DEALLOC 3
|
||||
|
||||
} bmtrace;
|
||||
|
||||
#endif /* BMTRACE */
|
||||
|
||||
|
||||
/*
|
||||
* Bufmgr Interface:
|
||||
*/
|
||||
|
||||
/* Internal routines: only called by buf.c */
|
||||
|
||||
/*freelist.c*/
|
||||
extern void AddBufferToFreelist(BufferDesc *bf);
|
||||
extern void PinBuffer(BufferDesc *buf);
|
||||
extern void PinBuffer_Debug(char *file, int line, BufferDesc *buf);
|
||||
extern void UnpinBuffer(BufferDesc *buf);
|
||||
extern void UnpinBuffer_Debug(char *file, int line, BufferDesc *buf);
|
||||
extern BufferDesc *GetFreeBuffer(void);
|
||||
extern void InitFreeList(bool init);
|
||||
extern void DBG_FreeListCheck(int nfree);
|
||||
|
||||
/* buf_table.c */
|
||||
extern void InitBufTable(void);
|
||||
extern BufferDesc *BufTableLookup(BufferTag *tagPtr);
|
||||
extern bool BufTableDelete(BufferDesc *buf);
|
||||
extern bool BufTableInsert(BufferDesc *buf);
|
||||
extern void DBG_LookupListCheck(int nlookup);
|
||||
|
||||
/* bufmgr.c */
|
||||
extern BufferDesc *BufferDescriptors;
|
||||
extern BufferBlock BufferBlocks;
|
||||
extern long *PrivateRefCount;
|
||||
extern long *LastRefCount;
|
||||
extern SPINLOCK BufMgrLock;
|
||||
|
||||
/* localbuf.c */
|
||||
extern long *LocalRefCount;
|
||||
extern BufferDesc *LocalBufferDescriptors;
|
||||
extern int NLocBuffer;
|
||||
|
||||
extern BufferDesc *LocalBufferAlloc(Relation reln, BlockNumber blockNum,
|
||||
bool *foundPtr);
|
||||
extern int WriteLocalBuffer(Buffer buffer, bool release);
|
||||
extern int FlushLocalBuffer(Buffer buffer);
|
||||
extern void InitLocalBuffer();
|
||||
extern void LocalBufferSync();
|
||||
extern void ResetLocalBufferPool();
|
||||
|
||||
#endif /* BUFMGR_INTERNALS_H */
|
||||
112
src/include/storage/bufmgr.h
Normal file
112
src/include/storage/bufmgr.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* bufmgr.h--
|
||||
* POSTGRES buffer manager definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: bufmgr.h,v 1.1 1996/08/28 01:58:01 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BUFMGR_H
|
||||
#define BUFMGR_H
|
||||
|
||||
#include "c.h"
|
||||
|
||||
#include "machine.h" /* for BLCKSZ */
|
||||
#include "utils/rel.h"
|
||||
|
||||
#include "storage/buf_internals.h" /* UGLY! -- ay */
|
||||
|
||||
/*
|
||||
* the maximum size of a disk block for any possible installation.
|
||||
*
|
||||
* in theory this could be anything, but in practice this is actually
|
||||
* limited to 2^13 bytes because we have limited ItemIdData.lp_off and
|
||||
* ItemIdData.lp_len to 13 bits (see itemid.h).
|
||||
*/
|
||||
#define MAXBLCKSZ 8192
|
||||
|
||||
typedef void *Block;
|
||||
|
||||
|
||||
/* special pageno for bget */
|
||||
#define P_NEW InvalidBlockNumber /* grow the file to get a new page */
|
||||
|
||||
typedef bits16 BufferLock;
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
the rest is function defns in the bufmgr that are externally callable
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
* These routines are beaten on quite heavily, hence the macroization.
|
||||
* See buf_internals.h for a related comment.
|
||||
*/
|
||||
#define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1)
|
||||
|
||||
/*
|
||||
* BufferIsPinned --
|
||||
* True iff the buffer is pinned (and therefore valid)
|
||||
*
|
||||
* Note:
|
||||
* Smenatics are identical to BufferIsValid
|
||||
* XXX - need to remove either one eventually.
|
||||
*/
|
||||
#define BufferIsPinned BufferIsValid
|
||||
|
||||
|
||||
extern int ShowPinTrace;
|
||||
|
||||
/*
|
||||
* prototypes for functions in bufmgr.c
|
||||
*/
|
||||
extern Buffer RelationGetBufferWithBuffer(Relation relation,
|
||||
BlockNumber blockNumber, Buffer buffer);
|
||||
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
|
||||
extern Buffer ReadBuffer_Debug(char *file, int line, Relation reln,
|
||||
BlockNumber blockNum);
|
||||
extern int WriteBuffer(Buffer buffer);
|
||||
extern void WriteBuffer_Debug(char *file, int line, Buffer buffer);
|
||||
extern void DirtyBufferCopy(Oid dbid, Oid relid, BlockNumber blkno,
|
||||
char *dest);
|
||||
extern int WriteNoReleaseBuffer(Buffer buffer);
|
||||
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
||||
BlockNumber blockNum);
|
||||
|
||||
extern void InitBufferPool(IPCKey key);
|
||||
extern void PrintBufferUsage(FILE *statfp);
|
||||
extern void ResetBufferUsage(void);
|
||||
extern void ResetBufferPool(void);
|
||||
extern int BufferPoolCheckLeak(void);
|
||||
extern void FlushBufferPool(int StableMainMemoryFlag);
|
||||
extern bool BufferIsValid(Buffer bufnum);
|
||||
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
|
||||
extern Relation BufferGetRelation(Buffer buffer);
|
||||
extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
|
||||
extern Block BufferGetBlock(Buffer buffer);
|
||||
extern void ReleaseTmpRelBuffers(Relation tempreldesc);
|
||||
extern void DropBuffers(Oid dbid);
|
||||
extern void PrintBufferDescs(void);
|
||||
extern void PrintPinnedBufs(void);
|
||||
extern int BufferShmemSize(void);
|
||||
extern void BufferPoolBlowaway(void);
|
||||
extern void IncrBufferRefCount(Buffer buffer);
|
||||
extern int ReleaseBuffer(Buffer buffer);
|
||||
|
||||
extern void IncrBufferRefCount_Debug(char *file, int line, Buffer buffer);
|
||||
extern void ReleaseBuffer_Debug(char *file, int line, Buffer buffer);
|
||||
extern int ReleaseAndReadBuffer_Debug(char *file,
|
||||
int line,
|
||||
Buffer buffer,
|
||||
Relation relation,
|
||||
BlockNumber blockNum);
|
||||
extern void BufferRefCountReset(int *refcountsave);
|
||||
extern void BufferRefCountRestore(int *refcountsave);
|
||||
|
||||
#endif /* !defined(BufMgrIncluded) */
|
||||
|
||||
256
src/include/storage/bufpage.h
Normal file
256
src/include/storage/bufpage.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* bufpage.h--
|
||||
* Standard POSTGRES buffer page definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: bufpage.h,v 1.1 1996/08/28 01:58:03 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BUFPAGE_H
|
||||
#define BUFPAGE_H
|
||||
|
||||
#include "c.h"
|
||||
#include "machine.h" /* for BLCKSZ */
|
||||
|
||||
#include "storage/buf.h"
|
||||
#include "storage/item.h"
|
||||
#include "storage/itemid.h"
|
||||
#include "storage/itemptr.h"
|
||||
|
||||
/*
|
||||
* a postgres disk page is an abstraction layered on top of a postgres
|
||||
* disk block (which is simply a unit of i/o, see block.h).
|
||||
*
|
||||
* specifically, while a disk block can be unformatted, a postgres
|
||||
* disk page is always a slotted page of the form:
|
||||
*
|
||||
* +----------------+---------------------------------+
|
||||
* | PageHeaderData | linp0 linp1 linp2 ... |
|
||||
* +-----------+----+---------------------------------+
|
||||
* | ... linpN | |
|
||||
* +-----------+--------------------------------------+
|
||||
* | ^ pd_lower |
|
||||
* | |
|
||||
* | v pd_upper |
|
||||
* +-------------+------------------------------------+
|
||||
* | | tupleN ... |
|
||||
* +-------------+------------------+-----------------+
|
||||
* | ... tuple2 tuple1 tuple0 | "special space" |
|
||||
* +--------------------------------+-----------------+
|
||||
* ^ pd_special
|
||||
*
|
||||
* a page is full when nothing can be added between pd_lower and
|
||||
* pd_upper.
|
||||
*
|
||||
* all blocks written out by an access method must be disk pages.
|
||||
*
|
||||
* EXCEPTIONS:
|
||||
*
|
||||
* obviously, a page is not formatted before it is initialized with by
|
||||
* a call to PageInit.
|
||||
*
|
||||
* the contents of the special pg_variable/pg_time/pg_log tables are
|
||||
* raw disk blocks with special formats. these are the only "access
|
||||
* methods" that need not write disk pages.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* linp0..N form an ItemId array. ItemPointers point into this array
|
||||
* rather than pointing directly to a tuple.
|
||||
*
|
||||
* tuple0..N are added "backwards" on the page. because a tuple's
|
||||
* ItemPointer points to its ItemId entry rather than its actual
|
||||
* byte-offset position, tuples can be physically shuffled on a page
|
||||
* whenever the need arises.
|
||||
*
|
||||
* AM-generic per-page information is kept in the pd_opaque field of
|
||||
* the PageHeaderData. (this is currently only the page size.)
|
||||
* AM-specific per-page data is kept in the area marked "special
|
||||
* space"; each AM has an "opaque" structure defined somewhere that is
|
||||
* stored as the page trailer. an access method should always
|
||||
* initialize its pages with PageInit and then set its own opaque
|
||||
* fields.
|
||||
*/
|
||||
typedef Pointer Page;
|
||||
|
||||
/*
|
||||
* PageIsValid --
|
||||
* True iff page is valid.
|
||||
*/
|
||||
#define PageIsValid(page) PointerIsValid(page)
|
||||
|
||||
|
||||
/*
|
||||
* location (byte offset) within a page.
|
||||
*
|
||||
* note that this is actually limited to 2^13 because we have limited
|
||||
* ItemIdData.lp_off and ItemIdData.lp_len to 13 bits (see itemid.h).
|
||||
*/
|
||||
typedef uint16 LocationIndex;
|
||||
|
||||
|
||||
/*
|
||||
* space management information generic to any page
|
||||
*
|
||||
* od_pagesize - size in bytes.
|
||||
* in reality, we need at least 64B to fit the
|
||||
* page header, opaque space and a minimal tuple;
|
||||
* on the high end, we can only support pages up
|
||||
* to 8KB because lp_off/lp_len are 13 bits.
|
||||
*/
|
||||
typedef struct OpaqueData {
|
||||
uint16 od_pagesize;
|
||||
} OpaqueData;
|
||||
|
||||
typedef OpaqueData *Opaque;
|
||||
|
||||
|
||||
/*
|
||||
* disk page organization
|
||||
*/
|
||||
typedef struct PageHeaderData {
|
||||
LocationIndex pd_lower; /* offset to start of free space */
|
||||
LocationIndex pd_upper; /* offset to end of free space */
|
||||
LocationIndex pd_special; /* offset to start of special space */
|
||||
OpaqueData pd_opaque; /* AM-generic information */
|
||||
ItemIdData pd_linp[1]; /* line pointers */
|
||||
} PageHeaderData;
|
||||
|
||||
typedef PageHeaderData *PageHeader;
|
||||
|
||||
typedef enum {
|
||||
ShufflePageManagerMode,
|
||||
OverwritePageManagerMode
|
||||
} PageManagerMode;
|
||||
|
||||
/* ----------------
|
||||
* misc support macros
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX this is wrong -- ignores padding/alignment, variable page size,
|
||||
* AM-specific opaque space at the end of the page (as in btrees), ...
|
||||
* however, it at least serves as an upper bound for heap pages.
|
||||
*/
|
||||
#define MAXTUPLEN (BLCKSZ - sizeof (PageHeaderData))
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* page support macros
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* PageIsValid -- This is defined in page.h.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PageIsUsed --
|
||||
* True iff the page size is used.
|
||||
*
|
||||
* Note:
|
||||
* Assumes page is valid.
|
||||
*/
|
||||
#define PageIsUsed(page) \
|
||||
(AssertMacro(PageIsValid(page)) ? \
|
||||
((bool) (((PageHeader) (page))->pd_lower != 0)) : false)
|
||||
|
||||
/*
|
||||
* PageIsEmpty --
|
||||
* returns true iff no itemid has been allocated on the page
|
||||
*/
|
||||
#define PageIsEmpty(page) \
|
||||
(((PageHeader) (page))->pd_lower == \
|
||||
(sizeof(PageHeaderData) - sizeof(ItemIdData)) ? true : false)
|
||||
|
||||
/*
|
||||
* PageGetItemId --
|
||||
* Returns an item identifier of a page.
|
||||
*/
|
||||
#define PageGetItemId(page, offsetNumber) \
|
||||
((ItemId) (&((PageHeader) (page))->pd_linp[(-1) + (offsetNumber)]))
|
||||
|
||||
/* ----------------
|
||||
* macros to access opaque space
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* PageSizeIsValid --
|
||||
* True iff the page size is valid.
|
||||
*
|
||||
* XXX currently all page sizes are "valid" but we only actually
|
||||
* use BLCKSZ.
|
||||
*/
|
||||
#define PageSizeIsValid(pageSize) 1
|
||||
|
||||
/*
|
||||
* PageGetPageSize --
|
||||
* Returns the page size of a page.
|
||||
*
|
||||
* this can only be called on a formatted page (unlike
|
||||
* BufferGetPageSize, which can be called on an unformatted page).
|
||||
* however, it can be called on a page for which there is no buffer.
|
||||
*/
|
||||
#define PageGetPageSize(page) \
|
||||
((Size) ((PageHeader) (page))->pd_opaque.od_pagesize)
|
||||
|
||||
/*
|
||||
* PageSetPageSize --
|
||||
* Sets the page size of a page.
|
||||
*/
|
||||
#define PageSetPageSize(page, size) \
|
||||
((PageHeader) (page))->pd_opaque.od_pagesize = (size)
|
||||
|
||||
/* ----------------
|
||||
* page special data macros
|
||||
* ----------------
|
||||
*/
|
||||
/*
|
||||
* PageGetSpecialSize --
|
||||
* Returns size of special space on a page.
|
||||
*
|
||||
* Note:
|
||||
* Assumes page is locked.
|
||||
*/
|
||||
#define PageGetSpecialSize(page) \
|
||||
((uint16) (PageGetPageSize(page) - ((PageHeader)page)->pd_special))
|
||||
|
||||
/*
|
||||
* PageGetSpecialPointer --
|
||||
* Returns pointer to special space on a page.
|
||||
*
|
||||
* Note:
|
||||
* Assumes page is locked.
|
||||
*/
|
||||
#define PageGetSpecialPointer(page) \
|
||||
(AssertMacro(PageIsValid(page)) ? \
|
||||
(char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
|
||||
: (char *) 0)
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* extern declarations
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern Size BufferGetPageSize(Buffer buffer);
|
||||
extern Page BufferGetPage(Buffer buffer);
|
||||
extern void PageInit(Page page, Size pageSize, Size specialSize);
|
||||
extern Item PageGetItem(Page page, ItemId itemId);
|
||||
extern OffsetNumber PageAddItem(Page page, Item item, Size size,
|
||||
OffsetNumber offsetNumber, ItemIdFlags flags);
|
||||
extern Page PageGetTempPage(Page page, Size specialSize);
|
||||
extern void PageRestoreTempPage(Page tempPage, Page oldPage);
|
||||
extern OffsetNumber PageGetMaxOffsetNumber(Page page);
|
||||
extern void PageRepairFragmentation(Page page);
|
||||
extern Size PageGetFreeSpace(Page page);
|
||||
extern void PageManagerModeSet(PageManagerMode mode);
|
||||
extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
|
||||
extern void PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr,
|
||||
char *location, Size size);
|
||||
|
||||
|
||||
#endif /* BUFPAGE_H */
|
||||
96
src/include/storage/fd.h
Normal file
96
src/include/storage/fd.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* fd.h--
|
||||
* Virtual file descriptor definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: fd.h,v 1.1 1996/08/28 01:58:04 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* calls:
|
||||
*
|
||||
* File {Close, Read, Write, Seek, Tell, Sync}
|
||||
* {File Name Open, Allocate, Free} File
|
||||
*
|
||||
* These are NOT JUST RENAMINGS OF THE UNIX ROUTINES.
|
||||
* use them for all file activity...
|
||||
*
|
||||
* fd = FilePathOpenFile("foo", O_RDONLY);
|
||||
* File fd;
|
||||
*
|
||||
* use AllocateFile if you need a file descriptor in some other context.
|
||||
* it will make sure that there is a file descriptor free
|
||||
*
|
||||
* use FreeFile to let the virtual file descriptor package know that
|
||||
* there is now a free fd (when you are done with it)
|
||||
*
|
||||
* AllocateFile();
|
||||
* FreeFile();
|
||||
*/
|
||||
#ifndef FD_H
|
||||
#define FD_H
|
||||
|
||||
/*
|
||||
* FileOpen uses the standard UNIX open(2) flags.
|
||||
*/
|
||||
#include <fcntl.h> /* for O_ on most */
|
||||
#ifndef O_RDONLY
|
||||
#include <sys/file.h> /* for O_ on the rest */
|
||||
#endif /* O_RDONLY */
|
||||
|
||||
/*
|
||||
* FileSeek uses the standard UNIX lseek(2) flags.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#include <unistd.h> /* for SEEK_ on most */
|
||||
#else
|
||||
#ifndef SEEK_SET
|
||||
#include <stdio.h> /* for SEEK_ on the rest */
|
||||
#endif /* SEEK_SET */
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include "c.h"
|
||||
#include "storage/block.h"
|
||||
|
||||
typedef char *FileName;
|
||||
|
||||
typedef int File;
|
||||
|
||||
/* originally in libpq-fs.h */
|
||||
struct pgstat { /* just the fields we need from stat structure */
|
||||
int st_ino;
|
||||
int st_mode;
|
||||
unsigned int st_size;
|
||||
unsigned int st_sizehigh; /* high order bits */
|
||||
/* 2^64 == 1.8 x 10^20 bytes */
|
||||
int st_uid;
|
||||
int st_atime_s; /* just the seconds */
|
||||
int st_mtime_s; /* since SysV and the new BSD both have */
|
||||
int st_ctime_s; /* usec fields.. */
|
||||
};
|
||||
|
||||
/*
|
||||
* prototypes for functions in fd.c
|
||||
*/
|
||||
extern void FileInvalidate(File file);
|
||||
extern File FileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
|
||||
extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
|
||||
extern void FileClose(File file);
|
||||
extern void FileUnlink(File file);
|
||||
extern int FileRead(File file, char *buffer, int amount);
|
||||
extern int FileWrite(File file, char *buffer, int amount);
|
||||
extern long FileSeek(File file, long offset, int whence);
|
||||
extern long FileTell(File file);
|
||||
extern int FileTruncate(File file, int offset);
|
||||
extern int FileSync(File file);
|
||||
extern int FileNameUnlink(char *filename);
|
||||
extern void AllocateFile(void);
|
||||
extern void FreeFile(void);
|
||||
extern void closeAllVfds(void);
|
||||
extern void closeOneVfd(void);
|
||||
|
||||
#endif /* FD_H */
|
||||
302
src/include/storage/ipc.h
Normal file
302
src/include/storage/ipc.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* ipc.h--
|
||||
* POSTGRES inter-process communication definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: ipc.h,v 1.1 1996/08/28 01:58:05 scrappy Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file is very architecture-specific. This stuff should actually
|
||||
* be factored into the port/ directories.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef IPC_H
|
||||
#define IPC_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _IPC_
|
||||
#define _IPC_
|
||||
#include <sys/ipc.h>
|
||||
#endif
|
||||
|
||||
#include "c.h"
|
||||
|
||||
/*
|
||||
* Many architectures have support for user-level spinlocks (i.e., an
|
||||
* atomic test-and-set instruction). However, we have only written
|
||||
* spinlock code for the architectures listed.
|
||||
*/
|
||||
#if defined(PORTNAME_aix) || \
|
||||
defined(PORTNAME_alpha) || \
|
||||
defined(PORTNAME_BSD44_derived) || \
|
||||
defined(PORTNAME_bsdi) || \
|
||||
defined(PORTNAME_bsdi_2_1) || \
|
||||
defined(PORTNAME_hpux) || \
|
||||
defined(PORTNAME_i386_solaris) || \
|
||||
defined(PORTNAME_irix5) || \
|
||||
defined(PORTNAME_linux) || \
|
||||
defined(PORTNAME_next) || \
|
||||
defined(PORTNAME_sparc) || \
|
||||
defined(PORTNAME_sparc_solaris)
|
||||
#define HAS_TEST_AND_SET
|
||||
#endif
|
||||
|
||||
#if defined(HAS_TEST_AND_SET)
|
||||
|
||||
#if defined(PORTNAME_aix)
|
||||
/*
|
||||
* The AIX C library has the cs(3) builtin for compare-and-set that
|
||||
* operates on ints.
|
||||
*/
|
||||
typedef unsigned int slock_t;
|
||||
#else /* aix */
|
||||
|
||||
#if defined(PORTNAME_alpha)
|
||||
#include <sys/mman.h>
|
||||
typedef msemaphore slock_t;
|
||||
#else /* alpha */
|
||||
|
||||
#if defined(PORTNAME_hpux)
|
||||
/*
|
||||
* The PA-RISC "semaphore" for the LDWCX instruction is 4 bytes aligned
|
||||
* to a 16-byte boundary.
|
||||
*/
|
||||
typedef struct { int sem[4]; } slock_t;
|
||||
#else /* hpux */
|
||||
|
||||
#if defined(PORTNAME_irix5)
|
||||
#include <abi_mutex.h>
|
||||
typedef abilock_t slock_t;
|
||||
#else /* irix5 */
|
||||
|
||||
#if defined(PORTNAME_next)
|
||||
/*
|
||||
* Use Mach mutex routines since these are, in effect, test-and-set
|
||||
* spinlocks.
|
||||
*/
|
||||
#undef NEVER /* definition in cthreads.h conflicts with parse.h */
|
||||
#include <mach/cthreads.h>
|
||||
typedef struct mutex slock_t;
|
||||
#else /* next */
|
||||
|
||||
/*
|
||||
* On all other architectures spinlocks are a single byte.
|
||||
*/
|
||||
typedef unsigned char slock_t;
|
||||
|
||||
#endif /* next */
|
||||
#endif /* irix5 */
|
||||
#endif /* hpux */
|
||||
#endif /* alpha */
|
||||
#endif /* aix */
|
||||
|
||||
extern void S_LOCK(slock_t *lock);
|
||||
extern void S_UNLOCK(slock_t *lock);
|
||||
extern void S_INIT_LOCK(slock_t *lock);
|
||||
|
||||
#if defined(PORTNAME_alpha) || \
|
||||
defined(PORTNAME_hpux) || \
|
||||
defined(PORTNAME_irix5) || \
|
||||
defined(PORTNAME_next)
|
||||
extern int S_LOCK_FREE(slock_t *lock);
|
||||
#else
|
||||
#define S_LOCK_FREE(lock) ((*lock) == 0)
|
||||
#endif
|
||||
|
||||
#endif /* HAS_TEST_AND_SET */
|
||||
|
||||
/*
|
||||
* On architectures for which we have not implemented spinlocks (or
|
||||
* cannot do so), we use System V semaphores. We also use them for
|
||||
* long locks. For some reason union semun is never defined in the
|
||||
* System V header files so we must do it ourselves.
|
||||
*
|
||||
* bsdi_2_1 does not need this
|
||||
*/
|
||||
#if defined(sequent) || \
|
||||
defined(PORTNAME_aix) || \
|
||||
defined(PORTNAME_alpha) || \
|
||||
defined(PORTNAME_bsdi) || \
|
||||
defined(PORTNAME_hpux) || \
|
||||
defined(PORTNAME_i386_solaris) || \
|
||||
defined(PORTNAME_sparc_solaris) || \
|
||||
defined(PORTNAME_ultrix4) || \
|
||||
defined(PORTNAME_svr4) || \
|
||||
defined(WIN32)
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
unsigned short *array;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef uint16 SystemPortAddress;
|
||||
|
||||
/* semaphore definitions */
|
||||
|
||||
#define IPCProtection (0600) /* access/modify by user only */
|
||||
|
||||
#define IPC_NMAXSEM 25 /* maximum number of semaphores */
|
||||
#define IpcSemaphoreDefaultStartValue 255
|
||||
#define IpcSharedLock (-1)
|
||||
#define IpcExclusiveLock (-255)
|
||||
|
||||
#define IpcUnknownStatus (-1)
|
||||
#define IpcInvalidArgument (-2)
|
||||
#define IpcSemIdExist (-3)
|
||||
#define IpcSemIdNotExist (-4)
|
||||
|
||||
typedef uint32 IpcSemaphoreKey; /* semaphore key */
|
||||
typedef int IpcSemaphoreId;
|
||||
|
||||
/* shared memory definitions */
|
||||
|
||||
#define IpcMemCreationFailed (-1)
|
||||
#define IpcMemIdGetFailed (-2)
|
||||
#define IpcMemAttachFailed 0
|
||||
|
||||
typedef uint32 IPCKey;
|
||||
#define PrivateIPCKey IPC_PRIVATE
|
||||
#define DefaultIPCKey 17317
|
||||
|
||||
typedef uint32 IpcMemoryKey; /* shared memory key */
|
||||
typedef int IpcMemoryId;
|
||||
|
||||
|
||||
/* ipc.c */
|
||||
extern void exitpg(int code);
|
||||
extern void quasi_exitpg(void);
|
||||
extern on_exitpg(void (*function)(), caddr_t arg);
|
||||
|
||||
extern IpcSemaphoreId IpcSemaphoreCreate(IpcSemaphoreKey semKey,
|
||||
int semNum, int permission, int semStartValue,
|
||||
int removeOnExit, int *status);
|
||||
extern void IpcSemaphoreSet(int semId, int semno, int value);
|
||||
extern void IpcSemaphoreKill(IpcSemaphoreKey key);
|
||||
extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock);
|
||||
extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock);
|
||||
extern int IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem);
|
||||
extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem);
|
||||
extern IpcMemoryId IpcMemoryCreate(IpcMemoryKey memKey, uint32 size,
|
||||
int permission);
|
||||
extern IpcMemoryId IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size);
|
||||
extern void IpcMemoryDetach(int status, char *shmaddr);
|
||||
extern char *IpcMemoryAttach(IpcMemoryId memId);
|
||||
extern void IpcMemoryKill(IpcMemoryKey memKey);
|
||||
extern void CreateAndInitSLockMemory(IPCKey key);
|
||||
extern void AttachSLockMemory(IPCKey key);
|
||||
|
||||
|
||||
#ifdef HAS_TEST_AND_SET
|
||||
|
||||
#define NSLOCKS 2048
|
||||
#define NOLOCK 0
|
||||
#define SHAREDLOCK 1
|
||||
#define EXCLUSIVELOCK 2
|
||||
|
||||
typedef enum _LockId_ {
|
||||
BUFMGRLOCKID,
|
||||
LOCKLOCKID,
|
||||
OIDGENLOCKID,
|
||||
SHMEMLOCKID,
|
||||
BINDINGLOCKID,
|
||||
LOCKMGRLOCKID,
|
||||
SINVALLOCKID,
|
||||
|
||||
#ifdef MAIN_MEMORY
|
||||
MMCACHELOCKID,
|
||||
#endif /* MAIN_MEMORY */
|
||||
|
||||
PROCSTRUCTLOCKID,
|
||||
FIRSTFREELOCKID
|
||||
} _LockId_;
|
||||
|
||||
#define MAX_SPINS FIRSTFREELOCKID
|
||||
|
||||
typedef struct slock {
|
||||
slock_t locklock;
|
||||
unsigned char flag;
|
||||
short nshlocks;
|
||||
slock_t shlock;
|
||||
slock_t exlock;
|
||||
slock_t comlock;
|
||||
struct slock *next;
|
||||
} SLock;
|
||||
|
||||
extern void ExclusiveLock(int lockid);
|
||||
extern void ExclusiveUnlock(int lockid);
|
||||
extern bool LockIsFree(int lockid);
|
||||
#else /* HAS_TEST_AND_SET */
|
||||
|
||||
typedef enum _LockId_ {
|
||||
SHMEMLOCKID,
|
||||
BINDINGLOCKID,
|
||||
BUFMGRLOCKID,
|
||||
LOCKMGRLOCKID,
|
||||
SINVALLOCKID,
|
||||
|
||||
#ifdef MAIN_MEMORY
|
||||
MMCACHELOCKID,
|
||||
#endif /* MAIN_MEMORY */
|
||||
|
||||
PROCSTRUCTLOCKID,
|
||||
OIDGENLOCKID,
|
||||
FIRSTFREELOCKID
|
||||
} _LockId_;
|
||||
|
||||
#define MAX_SPINS FIRSTFREELOCKID
|
||||
|
||||
#endif /* HAS_TEST_AND_SET */
|
||||
|
||||
/*
|
||||
* the following are originally in ipci.h but the prototypes have circular
|
||||
* dependencies and most files include both ipci.h and ipc.h anyway, hence
|
||||
* combined.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* These must not hash to DefaultIPCKey or PrivateIPCKey.
|
||||
*/
|
||||
#define SystemPortAddressGetIPCKey(address) \
|
||||
(28597 * (address) + 17491)
|
||||
|
||||
/*
|
||||
* these keys are originally numbered from 1 to 12 consecutively but not
|
||||
* all are used. The unused ones are removed. - ay 4/95.
|
||||
*/
|
||||
#define IPCKeyGetBufferMemoryKey(key) \
|
||||
((key == PrivateIPCKey) ? key : 1 + (key))
|
||||
|
||||
#define IPCKeyGetSIBufferMemoryBlock(key) \
|
||||
((key == PrivateIPCKey) ? key : 7 + (key))
|
||||
|
||||
#define IPCKeyGetSLockSharedMemoryKey(key) \
|
||||
((key == PrivateIPCKey) ? key : 10 + (key))
|
||||
|
||||
#define IPCKeyGetSpinLockSemaphoreKey(key) \
|
||||
((key == PrivateIPCKey) ? key : 11 + (key))
|
||||
#define IPCKeyGetWaitIOSemaphoreKey(key) \
|
||||
((key == PrivateIPCKey) ? key : 12 + (key))
|
||||
|
||||
/* --------------------------
|
||||
* NOTE: This macro must always give the highest numbered key as every backend
|
||||
* process forked off by the postmaster will be trying to acquire a semaphore
|
||||
* with a unique key value starting at key+14 and incrementing up. Each
|
||||
* backend uses the current key value then increments it by one.
|
||||
* --------------------------
|
||||
*/
|
||||
#define IPCGetProcessSemaphoreInitKey(key) \
|
||||
((key == PrivateIPCKey) ? key : 14 + (key))
|
||||
|
||||
/* ipci.c */
|
||||
extern IPCKey SystemPortAddressCreateIPCKey(SystemPortAddress address);
|
||||
extern void CreateSharedMemoryAndSemaphores(IPCKey key);
|
||||
extern void AttachSharedMemoryAndSemaphores(IPCKey key);
|
||||
|
||||
#endif /* IPC_H */
|
||||
20
src/include/storage/item.h
Normal file
20
src/include/storage/item.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* item.h--
|
||||
* POSTGRES disk item definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: item.h,v 1.1 1996/08/28 01:58:06 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ITEM_H
|
||||
#define ITEM_H
|
||||
|
||||
#include "c.h"
|
||||
|
||||
typedef Pointer Item;
|
||||
|
||||
#endif /* ITEM_H */
|
||||
75
src/include/storage/itemid.h
Normal file
75
src/include/storage/itemid.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* itemid.h--
|
||||
* Standard POSTGRES buffer page item identifier definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: itemid.h,v 1.1 1996/08/28 01:58:08 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ITEMID_H
|
||||
#define ITEMID_H
|
||||
|
||||
typedef uint16 ItemOffset;
|
||||
typedef uint16 ItemLength;
|
||||
|
||||
typedef bits16 ItemIdFlags;
|
||||
|
||||
|
||||
|
||||
typedef struct ItemIdData { /* line pointers */
|
||||
unsigned lp_off:13, /* offset to find tup */
|
||||
/* can be reduced by 2 if necc. */
|
||||
lp_flags:6, /* flags on tuple */
|
||||
lp_len:13; /* length of tuple */
|
||||
} ItemIdData;
|
||||
|
||||
typedef struct ItemIdData *ItemId;
|
||||
|
||||
#ifndef LP_USED
|
||||
#define LP_USED 0x01 /* this line pointer is being used */
|
||||
#endif
|
||||
|
||||
/* ----------------
|
||||
* support macros
|
||||
* ----------------
|
||||
*/
|
||||
/*
|
||||
* ItemIdGetLength
|
||||
*/
|
||||
#define ItemIdGetLength(itemId) \
|
||||
((itemId)->lp_len)
|
||||
|
||||
/*
|
||||
* ItemIdGetOffset
|
||||
*/
|
||||
#define ItemIdGetOffset(itemId) \
|
||||
((itemId)->lp_off)
|
||||
|
||||
/*
|
||||
* ItemIdGetFlags
|
||||
*/
|
||||
#define ItemIdGetFlags(itemId) \
|
||||
((itemId)->lp_flags)
|
||||
|
||||
/*
|
||||
* ItemIdIsValid --
|
||||
* True iff disk item identifier is valid.
|
||||
*/
|
||||
#define ItemIdIsValid(itemId) PointerIsValid(itemId)
|
||||
|
||||
/*
|
||||
* ItemIdIsUsed --
|
||||
* True iff disk item identifier is in use.
|
||||
*
|
||||
* Note:
|
||||
* Assumes disk item identifier is valid.
|
||||
*/
|
||||
#define ItemIdIsUsed(itemId) \
|
||||
(AssertMacro(ItemIdIsValid(itemId)) ? \
|
||||
(bool) (((itemId)->lp_flags & LP_USED) != 0) : false)
|
||||
|
||||
#endif /* ITEMID_H */
|
||||
44
src/include/storage/itempos.h
Normal file
44
src/include/storage/itempos.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* itempos.h--
|
||||
* Standard POSTGRES buffer page long item subposition definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: itempos.h,v 1.1 1996/08/28 01:58:09 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ITEMPOS_H
|
||||
#define ITEMPOS_H
|
||||
|
||||
#include "c.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/itemid.h"
|
||||
|
||||
typedef struct ItemSubpositionData {
|
||||
Buffer op_db;
|
||||
ItemId op_lpp;
|
||||
char *op_cp; /* XXX */
|
||||
uint32 op_len;
|
||||
} ItemSubpositionData;
|
||||
|
||||
typedef ItemSubpositionData *ItemSubposition;
|
||||
|
||||
/*
|
||||
* PNOBREAK(OBJP, LEN)
|
||||
* struct objpos *OBJP;
|
||||
* unsigned LEN;
|
||||
*/
|
||||
#define PNOBREAK(OBJP, LEN) ((OBJP)->op_len >= LEN)
|
||||
|
||||
/*
|
||||
* PSKIP(OBJP, LEN)
|
||||
* struct objpos *OBJP;
|
||||
* unsigned LEN;
|
||||
*/
|
||||
#define PSKIP(OBJP, LEN)\
|
||||
{ (OBJP)->op_cp += (LEN); (OBJP)->op_len -= (LEN); }
|
||||
|
||||
#endif /* ITEMPOS_H */
|
||||
115
src/include/storage/itemptr.h
Normal file
115
src/include/storage/itemptr.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* itemptr.h--
|
||||
* POSTGRES disk item pointer definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: itemptr.h,v 1.1 1996/08/28 01:58:11 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ITEMPTR_H
|
||||
#define ITEMPTR_H
|
||||
|
||||
#include "c.h"
|
||||
#include "storage/block.h"
|
||||
#include "storage/off.h"
|
||||
#include "storage/itemid.h"
|
||||
|
||||
/*
|
||||
* ItemPointer:
|
||||
*
|
||||
* this is a pointer to an item on another disk page in the same file.
|
||||
* blkid tells us which block, posid tells us which entry in the linp
|
||||
* (ItemIdData) array we want.
|
||||
*/
|
||||
typedef struct ItemPointerData {
|
||||
BlockIdData ip_blkid;
|
||||
OffsetNumber ip_posid;
|
||||
} ItemPointerData;
|
||||
|
||||
typedef ItemPointerData *ItemPointer;
|
||||
|
||||
/* ----------------
|
||||
* support macros
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* ItemPointerIsValid --
|
||||
* True iff the disk item pointer is not NULL.
|
||||
*/
|
||||
#define ItemPointerIsValid(pointer) \
|
||||
((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0)))
|
||||
|
||||
/*
|
||||
* ItemPointerGetBlockNumber --
|
||||
* Returns the block number of a disk item pointer.
|
||||
*/
|
||||
#define ItemPointerGetBlockNumber(pointer) \
|
||||
(AssertMacro(ItemPointerIsValid(pointer)) ? \
|
||||
BlockIdGetBlockNumber(&(pointer)->ip_blkid) : (BlockNumber) 0)
|
||||
|
||||
/*
|
||||
* ItemPointerGetOffsetNumber --
|
||||
* Returns the offset number of a disk item pointer.
|
||||
*/
|
||||
#define ItemPointerGetOffsetNumber(pointer) \
|
||||
(AssertMacro(ItemPointerIsValid(pointer)) ? \
|
||||
(pointer)->ip_posid : \
|
||||
InvalidOffsetNumber)
|
||||
|
||||
/*
|
||||
* ItemPointerSet --
|
||||
* Sets a disk item pointer to the specified block and offset.
|
||||
*/
|
||||
#define ItemPointerSet(pointer, blockNumber, offNum) \
|
||||
Assert(PointerIsValid(pointer)); \
|
||||
BlockIdSet(&((pointer)->ip_blkid), blockNumber); \
|
||||
(pointer)->ip_posid = offNum
|
||||
|
||||
/*
|
||||
* ItemPointerSetBlockNumber --
|
||||
* Sets a disk item pointer to the specified block.
|
||||
*/
|
||||
#define ItemPointerSetBlockNumber(pointer, blockNumber) \
|
||||
Assert(PointerIsValid(pointer)); \
|
||||
BlockIdSet(&((pointer)->ip_blkid), blockNumber)
|
||||
|
||||
/*
|
||||
* ItemPointerSetOffsetNumber --
|
||||
* Sets a disk item pointer to the specified offset.
|
||||
*/
|
||||
#define ItemPointerSetOffsetNumber(pointer, offsetNumber) \
|
||||
AssertMacro(PointerIsValid(pointer)); \
|
||||
(pointer)->ip_posid = (offsetNumber)
|
||||
|
||||
/*
|
||||
* ItemPointerCopy --
|
||||
* Copies the contents of one disk item pointer to another.
|
||||
*/
|
||||
#define ItemPointerCopy(fromPointer, toPointer) \
|
||||
Assert(PointerIsValid(toPointer)); \
|
||||
Assert(PointerIsValid(fromPointer)); \
|
||||
*(toPointer) = *(fromPointer)
|
||||
|
||||
/*
|
||||
* ItemPointerSetInvalid --
|
||||
* Sets a disk item pointer to be invalid.
|
||||
*/
|
||||
#define ItemPointerSetInvalid(pointer) \
|
||||
Assert(PointerIsValid(pointer)); \
|
||||
BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber); \
|
||||
(pointer)->ip_posid = InvalidOffsetNumber
|
||||
|
||||
/* ----------------
|
||||
* externs
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2);
|
||||
|
||||
#endif /* ITEMPTR_H */
|
||||
|
||||
58
src/include/storage/large_object.h
Normal file
58
src/include/storage/large_object.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* large_object.h--
|
||||
* file of info for Postgres large objects. POSTGRES 4.2 supports
|
||||
* zillions of large objects (internal, external, jaquith, inversion).
|
||||
* Now we only support inversion.
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: large_object.h,v 1.1 1996/08/28 01:58:12 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef LARGE_OBJECT_H
|
||||
#define LARGE_OBJECT_H
|
||||
|
||||
#include "c.h"
|
||||
#include "utils/rel.h"
|
||||
#include "access/relscan.h"
|
||||
|
||||
/*
|
||||
* This structure will eventually have lots more stuff associated with it.
|
||||
*/
|
||||
typedef struct LargeObjectDesc
|
||||
{
|
||||
Relation heap_r; /* heap relation */
|
||||
Relation index_r; /* index relation on seqno attribute */
|
||||
IndexScanDesc iscan; /* index scan we're using */
|
||||
TupleDesc hdesc; /* heap relation tuple desc */
|
||||
TupleDesc idesc; /* index relation tuple desc */
|
||||
uint32 lowbyte; /* low byte on the current page */
|
||||
uint32 highbyte; /* high byte on the current page */
|
||||
uint32 offset; /* current seek pointer */
|
||||
ItemPointerData htid; /* tid of current heap tuple */
|
||||
|
||||
#define IFS_RDLOCK (1 << 0)
|
||||
#define IFS_WRLOCK (1 << 1)
|
||||
#define IFS_ATEOF (1 << 2)
|
||||
|
||||
u_long flags; /* locking info, etc */
|
||||
} LargeObjectDesc;
|
||||
|
||||
/*
|
||||
* Function definitions...
|
||||
*/
|
||||
|
||||
/* inversion stuff in inv_api.c */
|
||||
extern LargeObjectDesc *inv_create(int flags);
|
||||
extern LargeObjectDesc *inv_open(Oid lobjId, int flags);
|
||||
extern void inv_close(LargeObjectDesc *obj_desc);
|
||||
extern int inv_destroy(Oid lobjId);
|
||||
extern int inv_stat(LargeObjectDesc *obj_desc, struct pgstat *stbuf);
|
||||
extern int inv_seek(LargeObjectDesc *obj_desc, int offset, int whence);
|
||||
extern int inv_tell(LargeObjectDesc *obj_desc);
|
||||
extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes);
|
||||
extern int inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes);
|
||||
|
||||
#endif /* LARGE_OBJECT_H */
|
||||
84
src/include/storage/lmgr.h
Normal file
84
src/include/storage/lmgr.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* lmgr.h--
|
||||
* POSTGRES lock manager definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: lmgr.h,v 1.1 1996/08/28 01:58:13 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef LMGR_H
|
||||
#define LMGR_H
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/itemptr.h"
|
||||
#include "storage/lock.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
* This was moved from pladt.h for the new lock manager. Want to obsolete
|
||||
* all of the old code.
|
||||
*/
|
||||
typedef struct LRelId {
|
||||
Oid relId; /* a relation identifier */
|
||||
Oid dbId; /* a database identifier */
|
||||
} LRelId;
|
||||
|
||||
typedef struct LockInfoData {
|
||||
bool initialized;
|
||||
LRelId lRelId;
|
||||
TransactionId transactionIdData;
|
||||
uint16 flags;
|
||||
} LockInfoData;
|
||||
typedef LockInfoData *LockInfo;
|
||||
|
||||
#define LockInfoIsValid(linfo) \
|
||||
((PointerIsValid(linfo)) && ((LockInfo) linfo)->initialized)
|
||||
|
||||
|
||||
extern LRelId RelationGetLRelId(Relation relation);
|
||||
extern Oid LRelIdGetDatabaseId(LRelId lRelId);
|
||||
extern Oid LRelIdGetRelationId(LRelId lRelId);
|
||||
extern bool DatabaseIdIsMyDatabaseId(Oid databaseId);
|
||||
extern bool LRelIdContainsMyDatabaseId(LRelId lRelId);
|
||||
extern void RelationInitLockInfo(Relation relation);
|
||||
extern void RelationDiscardLockInfo(Relation relation);
|
||||
extern void RelationSetLockForDescriptorOpen(Relation relation);
|
||||
extern void RelationSetLockForRead(Relation relation);
|
||||
extern void RelationUnsetLockForRead(Relation relation);
|
||||
extern void RelationSetLockForWrite(Relation relation);
|
||||
extern void RelationUnsetLockForWrite(Relation relation);
|
||||
extern void RelationSetLockForTupleRead(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
|
||||
/* used in vaccum.c */
|
||||
extern void RelationSetLockForWritePage(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
|
||||
/* used in nbtpage.c, hashpage.c */
|
||||
extern void RelationSetSingleWLockPage(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
extern void RelationUnsetSingleWLockPage(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
extern void RelationSetSingleRLockPage(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
extern void RelationUnsetSingleRLockPage(Relation relation,
|
||||
ItemPointer itemPointer);
|
||||
extern void RelationSetRIntentLock(Relation relation);
|
||||
extern void RelationUnsetRIntentLock(Relation relation);
|
||||
extern void RelationSetWIntentLock(Relation relation);
|
||||
extern void RelationUnsetWIntentLock(Relation relation);
|
||||
extern void RelationSetLockForExtend(Relation relation);
|
||||
extern void RelationUnsetLockForExtend(Relation relation);
|
||||
extern void LRelIdAssign(LRelId *lRelId, Oid dbId, Oid relId);
|
||||
|
||||
/* single.c */
|
||||
extern bool SingleLockReln(LockInfo linfo, LOCKT lockt, int action);
|
||||
extern bool SingleLockPage(LockInfo linfo, ItemPointer tidPtr,
|
||||
LOCKT lockt, int action);
|
||||
|
||||
#endif /* LMGR_H */
|
||||
218
src/include/storage/lock.h
Normal file
218
src/include/storage/lock.h
Normal file
@@ -0,0 +1,218 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* lock.h--
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: lock.h,v 1.1 1996/08/28 01:58:15 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef LOCK_H_
|
||||
#define LOCK_H_
|
||||
|
||||
#include "postgres.h"
|
||||
#include "storage/itemptr.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/backendid.h"
|
||||
#include "utils/hsearch.h"
|
||||
|
||||
extern SPINLOCK LockMgrLock;
|
||||
typedef int MASK;
|
||||
|
||||
#define INIT_TABLE_SIZE 100
|
||||
#define MAX_TABLE_SIZE 1000
|
||||
|
||||
|
||||
/* ----------------------
|
||||
* The following defines are used to estimate how much shared
|
||||
* memory the lock manager is going to require.
|
||||
*
|
||||
* NBACKENDS - The number of concurrently running backends
|
||||
* NLOCKS_PER_XACT - The number of unique locks acquired in a transaction
|
||||
* NLOCKENTS - The maximum number of lock entries in the lock table.
|
||||
* ----------------------
|
||||
*/
|
||||
#define NBACKENDS 50
|
||||
#define NLOCKS_PER_XACT 40
|
||||
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
|
||||
|
||||
typedef int LOCK_TYPE;
|
||||
typedef int LOCKT;
|
||||
typedef int LockTableId;
|
||||
|
||||
/* MAX_LOCKTYPES cannot be larger than the bits in MASK */
|
||||
#define MAX_LOCKTYPES 6
|
||||
|
||||
/*
|
||||
* MAX_TABLES corresponds to the number of spin locks allocated in
|
||||
* CreateSpinLocks() or the number of shared memory locations allocated
|
||||
* for lock table spin locks in the case of machines with TAS instructions.
|
||||
*/
|
||||
#define MAX_TABLES 2
|
||||
|
||||
#define INVALID_TABLEID 0
|
||||
|
||||
/*typedef struct LOCK LOCK; */
|
||||
|
||||
|
||||
typedef struct ltag {
|
||||
Oid relId;
|
||||
Oid dbId;
|
||||
ItemPointerData tupleId;
|
||||
} LOCKTAG;
|
||||
|
||||
#define TAGSIZE (sizeof(LOCKTAG))
|
||||
|
||||
/* This is the control structure for a lock table. It
|
||||
* lives in shared memory:
|
||||
*
|
||||
* tableID -- the handle used by the lock table's clients to
|
||||
* refer to the table.
|
||||
*
|
||||
* nLockTypes -- number of lock types (READ,WRITE,etc) that
|
||||
* are defined on this lock table
|
||||
*
|
||||
* conflictTab -- this is an array of bitmasks showing lock
|
||||
* type conflicts. conflictTab[i] is a mask with the j-th bit
|
||||
* turned on if lock types i and j conflict.
|
||||
*
|
||||
* prio -- each locktype has a priority, so, for example, waiting
|
||||
* writers can be given priority over readers (to avoid
|
||||
* starvation).
|
||||
*
|
||||
* masterlock -- synchronizes access to the table
|
||||
*
|
||||
*/
|
||||
typedef struct lockctl {
|
||||
LockTableId tableId;
|
||||
int nLockTypes;
|
||||
int conflictTab[MAX_LOCKTYPES];
|
||||
int prio[MAX_LOCKTYPES];
|
||||
SPINLOCK masterLock;
|
||||
} LOCKCTL;
|
||||
|
||||
/*
|
||||
* lockHash -- hash table on lock Ids,
|
||||
* xidHash -- hash on xid and lockId in case
|
||||
* multiple processes are holding the lock
|
||||
* ctl - control structure described above.
|
||||
*/
|
||||
typedef struct ltable {
|
||||
HTAB *lockHash;
|
||||
HTAB *xidHash;
|
||||
LOCKCTL *ctl;
|
||||
} LOCKTAB;
|
||||
|
||||
/* -----------------------
|
||||
* A transaction never conflicts with its own locks. Hence, if
|
||||
* multiple transactions hold non-conflicting locks on the same
|
||||
* data, private per-transaction information must be stored in the
|
||||
* XID table. The tag is XID + shared memory lock address so that
|
||||
* all locks can use the same XID table. The private information
|
||||
* we store is the number of locks of each type (holders) and the
|
||||
* total number of locks (nHolding) held by the transaction.
|
||||
*
|
||||
* NOTE: --
|
||||
* There were some problems with the fact that currently TransactionIdData
|
||||
* is a 5 byte entity and compilers long word aligning of structure fields.
|
||||
* If the 3 byte padding is put in front of the actual xid data then the
|
||||
* hash function (which uses XID_TAGSIZE when deciding how many bytes of a
|
||||
* struct to look at for the key) might only see the last two bytes of the xid.
|
||||
*
|
||||
* Clearly this is not good since its likely that these bytes will be the
|
||||
* same for many transactions and hence they will share the same entry in
|
||||
* hash table causing the entry to be corrupted. For this long-winded
|
||||
* reason I have put the tag in a struct of its own to ensure that the
|
||||
* XID_TAGSIZE is computed correctly. It used to be sizeof (SHMEM_OFFSET) +
|
||||
* sizeof(TransactionIdData) which != sizeof(XIDTAG).
|
||||
*
|
||||
* Finally since the hash function will now look at all 12 bytes of the tag
|
||||
* the padding bytes MUST be zero'd before use in hash_search() as they
|
||||
* will have random values otherwise. Jeff 22 July 1991.
|
||||
* -----------------------
|
||||
*/
|
||||
|
||||
typedef struct XIDTAG {
|
||||
SHMEM_OFFSET lock;
|
||||
int pid;
|
||||
TransactionId xid;
|
||||
} XIDTAG;
|
||||
|
||||
typedef struct XIDLookupEnt {
|
||||
/* tag */
|
||||
XIDTAG tag;
|
||||
|
||||
/* data */
|
||||
int holders[MAX_LOCKTYPES];
|
||||
int nHolding;
|
||||
SHM_QUEUE queue;
|
||||
} XIDLookupEnt;
|
||||
|
||||
#define XID_TAGSIZE (sizeof(XIDTAG))
|
||||
|
||||
/* originally in procq.h */
|
||||
typedef struct procQueue {
|
||||
SHM_QUEUE links;
|
||||
int size;
|
||||
} PROC_QUEUE;
|
||||
|
||||
|
||||
/*
|
||||
* lock information:
|
||||
*
|
||||
* tag -- uniquely identifies the object being locked
|
||||
* mask -- union of the conflict masks of all lock types
|
||||
* currently held on this object.
|
||||
* waitProcs -- queue of processes waiting for this lock
|
||||
* holders -- count of each lock type currently held on the
|
||||
* lock.
|
||||
* nHolding -- total locks of all types.
|
||||
*/
|
||||
typedef struct Lock {
|
||||
/* hash key */
|
||||
LOCKTAG tag;
|
||||
|
||||
/* data */
|
||||
int mask;
|
||||
PROC_QUEUE waitProcs;
|
||||
int holders[MAX_LOCKTYPES];
|
||||
int nHolding;
|
||||
int activeHolders[MAX_LOCKTYPES];
|
||||
int nActive;
|
||||
} LOCK;
|
||||
|
||||
#define LockGetLock_nHolders(l) l->nHolders
|
||||
|
||||
#define LockDecrWaitHolders(lock, lockt) \
|
||||
lock->nHolding--; \
|
||||
lock->holders[lockt]--
|
||||
|
||||
#define LockLockTable() SpinAcquire(LockMgrLock);
|
||||
#define UnlockLockTable() SpinRelease(LockMgrLock);
|
||||
|
||||
extern SPINLOCK LockMgrLock;
|
||||
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
extern void InitLocks(void);
|
||||
extern void LockDisable(int status);
|
||||
extern LockTableId LockTabInit(char *tabName, MASK *conflictsP, int *prioP,
|
||||
int ntypes);
|
||||
extern LockTableId LockTabRename(LockTableId tableId);
|
||||
extern bool LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
|
||||
extern int LockResolveConflicts(LOCKTAB *ltable, LOCK *lock, LOCKT lockt,
|
||||
TransactionId xid);
|
||||
extern int WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock,
|
||||
LOCKT lockt);
|
||||
extern bool LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
|
||||
extern void GrantLock(LOCK *lock, LOCKT lockt);
|
||||
extern bool LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue);
|
||||
extern int LockShmemSize(void);
|
||||
extern bool LockingDisabled(void);
|
||||
|
||||
#endif /* LOCK_H */
|
||||
64
src/include/storage/multilev.h
Normal file
64
src/include/storage/multilev.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* multilev.h--
|
||||
* multi level lock table consts/defs for single.c and multi.c and their
|
||||
* clients
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: multilev.h,v 1.1 1996/08/28 01:58:17 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef MULTILEV_H
|
||||
#define MULTILEV_H
|
||||
|
||||
#include "storage/lock.h"
|
||||
#include "storage/lmgr.h"
|
||||
|
||||
#define READ_LOCK 2
|
||||
#define WRITE_LOCK 1
|
||||
|
||||
/* any time a small granularity READ/WRITE lock is set.
|
||||
* Higher granularity READ_INTENT/WRITE_INTENT locks must
|
||||
* also be set. A read intent lock is has value READ+INTENT.
|
||||
* in this implementation.
|
||||
*/
|
||||
#define NO_LOCK 0
|
||||
#define INTENT 2
|
||||
#define READ_INTENT (READ_LOCK+INTENT)
|
||||
#define WRITE_INTENT (WRITE_LOCK+INTENT)
|
||||
|
||||
#define EXTEND_LOCK 5
|
||||
|
||||
#define SHORT_TERM 1
|
||||
#define LONG_TERM 2
|
||||
#define UNLOCK 0
|
||||
|
||||
#define N_LEVELS 3
|
||||
#define RELN_LEVEL 0
|
||||
#define PAGE_LEVEL 1
|
||||
#define TUPLE_LEVEL 2
|
||||
typedef int LOCK_LEVEL;
|
||||
|
||||
/* multi.c */
|
||||
|
||||
extern LockTableId MultiTableId;
|
||||
extern LockTableId ShortTermTableId;
|
||||
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
extern LockTableId InitMultiLevelLockm(void);
|
||||
extern bool MultiLockReln(LockInfo linfo, LOCKT lockt);
|
||||
extern bool MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
|
||||
extern bool MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
|
||||
extern bool MultiAcquire(LockTableId tableId, LOCKTAG *tag, LOCKT lockt,
|
||||
LOCK_LEVEL level);
|
||||
extern bool MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
|
||||
extern bool MultiReleaseReln(LockInfo linfo, LOCKT lockt);
|
||||
extern bool MultiRelease(LockTableId tableId, LOCKTAG *tag, LOCKT lockt,
|
||||
LOCK_LEVEL level);
|
||||
|
||||
#endif /* MULTILEV_H */
|
||||
60
src/include/storage/off.h
Normal file
60
src/include/storage/off.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* off.h--
|
||||
* POSTGRES disk "offset" definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: off.h,v 1.1 1996/08/28 01:58:18 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef OFF_H
|
||||
#define OFF_H
|
||||
|
||||
#include "c.h"
|
||||
#include "machine.h" /* for BLCKSZ */
|
||||
#include "storage/itemid.h"
|
||||
|
||||
/*
|
||||
* OffsetNumber:
|
||||
*
|
||||
* this is a 1-based index into the linp (ItemIdData) array in the
|
||||
* header of each disk page.
|
||||
*/
|
||||
typedef uint16 OffsetNumber;
|
||||
|
||||
#define InvalidOffsetNumber ((OffsetNumber) 0)
|
||||
#define FirstOffsetNumber ((OffsetNumber) 1)
|
||||
#define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData)))
|
||||
#define OffsetNumberMask (0xffff) /* valid uint16 bits */
|
||||
|
||||
/* ----------------
|
||||
* support macros
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* OffsetNumberIsValid --
|
||||
* True iff the offset number is valid.
|
||||
*/
|
||||
#define OffsetNumberIsValid(offsetNumber) \
|
||||
((bool) ((offsetNumber != InvalidOffsetNumber) && \
|
||||
(offsetNumber <= MaxOffsetNumber)))
|
||||
|
||||
/*
|
||||
* OffsetNumberNext --
|
||||
* OffsetNumberPrev --
|
||||
* Increments/decrements the argument. These macros look pointless
|
||||
* but they help us disambiguate the different manipulations on
|
||||
* OffsetNumbers (e.g., sometimes we substract one from an
|
||||
* OffsetNumber to move back, and sometimes we do so to form a
|
||||
* real C array index).
|
||||
*/
|
||||
#define OffsetNumberNext(offsetNumber) \
|
||||
((OffsetNumber) (1 + (offsetNumber)))
|
||||
#define OffsetNumberPrev(offsetNumber) \
|
||||
((OffsetNumber) (-1 + (offsetNumber)))
|
||||
|
||||
#endif /* OFF_H */
|
||||
26
src/include/storage/page.h
Normal file
26
src/include/storage/page.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* page.h--
|
||||
* POSTGRES buffer page abstraction definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: page.h,v 1.1 1996/08/28 01:58:20 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PAGE_H
|
||||
#define PAGE_H
|
||||
|
||||
#include "c.h"
|
||||
|
||||
typedef Pointer Page;
|
||||
|
||||
/*
|
||||
* PageIsValid --
|
||||
* True iff page is valid.
|
||||
*/
|
||||
#define PageIsValid(page) PointerIsValid(page)
|
||||
|
||||
#endif /* PAGE_H */
|
||||
33
src/include/storage/pagenum.h
Normal file
33
src/include/storage/pagenum.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pagenum.h--
|
||||
* POSTGRES page number definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pagenum.h,v 1.1 1996/08/28 01:58:21 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PAGENUM_H
|
||||
#define PAGENUM_H
|
||||
|
||||
#include "c.h"
|
||||
#include "storage/page.h"
|
||||
|
||||
typedef uint16 PageNumber;
|
||||
|
||||
typedef uint32 LogicalPageNumber;
|
||||
|
||||
#define InvalidLogicalPageNumber 0
|
||||
|
||||
/*
|
||||
* LogicalPageNumberIsValid --
|
||||
* True iff the logical page number is valid.
|
||||
*/
|
||||
#define LogicalPageNumberIsValid(pageNumber) \
|
||||
((bool)((pageNumber) != InvalidLogicalPageNumber))
|
||||
|
||||
|
||||
#endif /* PAGENUM_H */
|
||||
64
src/include/storage/pos.h
Normal file
64
src/include/storage/pos.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pos.h--
|
||||
* POSTGRES "position" definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pos.h,v 1.1 1996/08/28 01:58:22 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef POS_H
|
||||
#define POS_H
|
||||
|
||||
#include "c.h"
|
||||
|
||||
/*
|
||||
* a 'position' used to be <pagenumber, offset> in postgres. this has
|
||||
* been changed to just <offset> as the notion of having multiple pages
|
||||
* within a block has been removed.
|
||||
*
|
||||
* the 'offset' abstraction is somewhat confusing. it is NOT a byte
|
||||
* offset within the page; instead, it is an offset into the line
|
||||
* pointer array contained on every page that store (heap or index)
|
||||
* tuples.
|
||||
*/
|
||||
typedef bits16 PositionIdData;
|
||||
typedef PositionIdData *PositionId;
|
||||
|
||||
/* ----------------
|
||||
* support macros
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* PositionIdIsValid --
|
||||
* True iff the position identifier is valid.
|
||||
*/
|
||||
#define PositionIdIsValid(positionId) \
|
||||
PointerIsValid(positionId)
|
||||
|
||||
/*
|
||||
* PositionIdSetInvalid --
|
||||
* Make an invalid position.
|
||||
*/
|
||||
#define PositionIdSetInvalid(positionId) \
|
||||
*(positionId) = (bits16) 0
|
||||
|
||||
/*
|
||||
* PositionIdSet --
|
||||
* Sets a position identifier to the specified value.
|
||||
*/
|
||||
#define PositionIdSet(positionId, offsetNumber) \
|
||||
*(positionId) = (offsetNumber)
|
||||
|
||||
/*
|
||||
* PositionIdGetOffsetNumber --
|
||||
* Retrieve the offset number from a position identifier.
|
||||
*/
|
||||
#define PositionIdGetOffsetNumber(positionId) \
|
||||
((OffsetNumber) *(positionId))
|
||||
|
||||
#endif /* POS_H */
|
||||
123
src/include/storage/proc.h
Normal file
123
src/include/storage/proc.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* proc.h--
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: proc.h,v 1.1 1996/08/28 01:58:24 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef _PROC_H_
|
||||
#define _PROC_H_
|
||||
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/lock.h"
|
||||
#ifndef WIN32
|
||||
#include <sys/sem.h>
|
||||
#else
|
||||
/* This is because WIN32 already defines PROC */
|
||||
#define PROC PGL_PROC
|
||||
#endif /* WIN32 */
|
||||
#include "storage/shmem.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int sleeplock;
|
||||
int semNum;
|
||||
IpcSemaphoreId semId;
|
||||
IpcSemaphoreKey semKey;
|
||||
} SEMA;
|
||||
|
||||
/*
|
||||
* Each backend has:
|
||||
*/
|
||||
typedef struct proc {
|
||||
|
||||
/* proc->links MUST BE THE FIRST ELEMENT OF STRUCT (see ProcWakeup()) */
|
||||
|
||||
SHM_QUEUE links; /* proc can be waiting for one event(lock) */
|
||||
SEMA sem; /* ONE semaphore to sleep on */
|
||||
int errType; /* error code tells why we woke up */
|
||||
|
||||
int procId; /* unique number for this structure
|
||||
* NOT unique per backend, these things
|
||||
* are reused after the backend dies.
|
||||
*/
|
||||
|
||||
int critSects; /* If critSects > 0, we are in sensitive
|
||||
* routines that cannot be recovered when
|
||||
* the process fails.
|
||||
*/
|
||||
|
||||
int prio; /* priority for sleep queue */
|
||||
|
||||
TransactionId xid; /* transaction currently being executed
|
||||
* by this proc
|
||||
*/
|
||||
|
||||
LOCK * waitLock; /* Lock we're sleeping on */
|
||||
int token; /* info for proc wakeup routines */
|
||||
int pid; /* This procs process id */
|
||||
short sLocks[MAX_SPINS]; /* Spin lock stats */
|
||||
SHM_QUEUE lockQueue; /* locks associated with current transaction */
|
||||
} PROC;
|
||||
|
||||
|
||||
/*
|
||||
* MAX_PROC_SEMS is the maximum number of per-process semaphores (those used
|
||||
* by the lock mgr) we can keep track of. PROC_NSEMS_PER_SET is the number
|
||||
* of semaphores in each (sys-V) semaphore set allocated. (Be careful not
|
||||
* to set it to greater 32. Otherwise, the bitmap will overflow.)
|
||||
*/
|
||||
#define MAX_PROC_SEMS 128
|
||||
#define PROC_NSEMS_PER_SET 16
|
||||
|
||||
typedef struct procglobal {
|
||||
SHMEM_OFFSET freeProcs;
|
||||
int numProcs;
|
||||
IPCKey currKey;
|
||||
int32 freeSemMap[MAX_PROC_SEMS/PROC_NSEMS_PER_SET];
|
||||
} PROC_HDR;
|
||||
|
||||
extern PROC *MyProc;
|
||||
|
||||
#define PROC_INCR_SLOCK(lock) if (MyProc) (MyProc->sLocks[(lock)])++
|
||||
#define PROC_DECR_SLOCK(lock) if (MyProc) (MyProc->sLocks[(lock)])--
|
||||
|
||||
/*
|
||||
* flags explaining why process woke up
|
||||
*/
|
||||
#define NO_ERROR 0
|
||||
#define ERR_TIMEOUT 1
|
||||
#define ERR_BUFFER_IO 2
|
||||
|
||||
#define MAX_PRIO 50
|
||||
#define MIN_PRIO (-1)
|
||||
|
||||
extern SPINLOCK ProcStructLock;
|
||||
|
||||
/*
|
||||
* Function Prototypes
|
||||
*/
|
||||
extern void InitProcess(IPCKey key);
|
||||
extern void ProcReleaseLocks(void);
|
||||
extern bool ProcRemove(int pid);
|
||||
/* extern bool ProcKill(int exitStatus, int pid); */
|
||||
/* make static in storage/lmgr/proc.c -- jolly */
|
||||
|
||||
extern PROC_QUEUE *ProcQueueAlloc(char *name);
|
||||
extern void ProcQueueInit(PROC_QUEUE *queue);
|
||||
extern int ProcSleep(PROC_QUEUE *queue, SPINLOCK spinlock, int token,
|
||||
int prio, LOCK *lock);
|
||||
extern PROC *ProcWakeup(PROC *proc, int errType);
|
||||
extern int ProcGetId(void);
|
||||
extern int ProcLockWakeup(PROC_QUEUE *queue, char * ltable, char * lock);
|
||||
extern void ProcAddLock(SHM_QUEUE *elem);
|
||||
extern void HandleDeadLock(int sig);
|
||||
extern void ProcReleaseSpins(PROC *proc);
|
||||
extern void ProcFreeAllSemaphores(void);
|
||||
|
||||
#endif /* PROC_H */
|
||||
104
src/include/storage/shmem.h
Normal file
104
src/include/storage/shmem.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* shmem.h--
|
||||
* shared memory management structures
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: shmem.h,v 1.1 1996/08/28 01:58:26 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SHMEM_H
|
||||
#define SHMEM_H
|
||||
|
||||
#include "storage/spin.h" /* for SPINLOCK */
|
||||
#include "utils/hsearch.h" /* for HTAB */
|
||||
|
||||
/* The shared memory region can start at a different address
|
||||
* in every process. Shared memory "pointers" are actually
|
||||
* offsets relative to the start of the shared memory region(s).
|
||||
*/
|
||||
typedef unsigned long SHMEM_OFFSET;
|
||||
#define INVALID_OFFSET (-1)
|
||||
#define BAD_LOCATION (-1)
|
||||
|
||||
/* start of the lowest shared memory region. For now, assume that
|
||||
* there is only one shared memory region
|
||||
*/
|
||||
extern SHMEM_OFFSET ShmemBase;
|
||||
|
||||
|
||||
/* coerce an offset into a pointer in this process's address space */
|
||||
#define MAKE_PTR(xx_offs)\
|
||||
(ShmemBase+((unsigned long)(xx_offs)))
|
||||
|
||||
/* coerce a pointer into a shmem offset */
|
||||
#define MAKE_OFFSET(xx_ptr)\
|
||||
(SHMEM_OFFSET) (((unsigned long)(xx_ptr))-ShmemBase)
|
||||
|
||||
#define SHM_PTR_VALID(xx_ptr)\
|
||||
(((unsigned long)xx_ptr) > ShmemBase)
|
||||
|
||||
/* cannot have an offset to ShmemFreeStart (offset 0) */
|
||||
#define SHM_OFFSET_VALID(xx_offs)\
|
||||
((xx_offs != 0) && (xx_offs != INVALID_OFFSET))
|
||||
|
||||
|
||||
extern SPINLOCK ShmemLock;
|
||||
extern SPINLOCK BindingLock;
|
||||
|
||||
/* shmemqueue.c */
|
||||
typedef struct SHM_QUEUE {
|
||||
SHMEM_OFFSET prev;
|
||||
SHMEM_OFFSET next;
|
||||
} SHM_QUEUE;
|
||||
|
||||
/* shmem.c */
|
||||
extern void ShmemBindingTabReset();
|
||||
extern void ShmemCreate(unsigned int key, unsigned int size);
|
||||
extern int InitShmem(unsigned int key, unsigned int size);
|
||||
extern long *ShmemAlloc(unsigned long size);
|
||||
extern int ShmemIsValid(unsigned long addr);
|
||||
extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
|
||||
HASHCTL *infoP, int hash_flags);
|
||||
extern bool ShmemPIDLookup(int pid, SHMEM_OFFSET* locationPtr);
|
||||
extern SHMEM_OFFSET ShmemPIDDestroy(int pid);
|
||||
extern long *ShmemInitStruct(char *name, unsigned long size,
|
||||
bool *foundPtr);
|
||||
|
||||
|
||||
typedef int TableID;
|
||||
|
||||
/* size constants for the binding table */
|
||||
/* max size of data structure string name */
|
||||
#define BTABLE_KEYSIZE (50)
|
||||
/* data in binding table hash bucket */
|
||||
#define BTABLE_DATASIZE (sizeof(BindingEnt) - BTABLE_KEYSIZE)
|
||||
/* maximum size of the binding table */
|
||||
#define BTABLE_SIZE (100)
|
||||
|
||||
/* this is a hash bucket in the binding table */
|
||||
typedef struct {
|
||||
char key[BTABLE_KEYSIZE]; /* string name */
|
||||
unsigned long location; /* location in shared mem */
|
||||
unsigned long size; /* numbytes allocated for the
|
||||
* structure
|
||||
*/
|
||||
} BindingEnt;
|
||||
|
||||
/*
|
||||
* prototypes for functions in shmqueue.c
|
||||
*/
|
||||
extern void SHMQueueInit(SHM_QUEUE *queue);
|
||||
extern bool SHMQueueIsDetached(SHM_QUEUE *queue);
|
||||
extern void SHMQueueElemInit(SHM_QUEUE *queue);
|
||||
extern void SHMQueueDelete(SHM_QUEUE *queue);
|
||||
extern void SHMQueueInsertHD(SHM_QUEUE *queue, SHM_QUEUE *elem);
|
||||
extern void SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem);
|
||||
extern void SHMQueueFirst(SHM_QUEUE *queue, Pointer *nextPtrPtr,
|
||||
SHM_QUEUE *nextQueue);
|
||||
extern bool SHMQueueEmpty(SHM_QUEUE *queue);
|
||||
|
||||
#endif /* SHMEM_H */
|
||||
33
src/include/storage/sinval.h
Normal file
33
src/include/storage/sinval.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* sinval.h--
|
||||
* POSTGRES shared cache invalidation communication definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: sinval.h,v 1.1 1996/08/28 01:58:28 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SINVAL_H
|
||||
#define SINVAL_H
|
||||
|
||||
#include "c.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/itemptr.h"
|
||||
#include "storage/backendid.h"
|
||||
|
||||
extern SPINLOCK SInvalLock;
|
||||
|
||||
extern void CreateSharedInvalidationState(IPCKey key);
|
||||
extern void AttachSharedInvalidationState(IPCKey key);
|
||||
extern void InitSharedInvalidationState();
|
||||
extern void RegisterSharedInvalid(int cacheId, Index hashIndex,
|
||||
ItemPointer pointer);
|
||||
extern void InvalidateSharedInvalid(void (*invalFunction)(),
|
||||
void (*resetFunction)());
|
||||
|
||||
|
||||
#endif /* SINVAL_H */
|
||||
126
src/include/storage/sinvaladt.h
Normal file
126
src/include/storage/sinvaladt.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* sinvaladt.h--
|
||||
* POSTGRES shared cache invalidation segment definitions.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: sinvaladt.h,v 1.1 1996/08/28 01:58:29 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SINVALADT_H
|
||||
#define SINVALADT_H
|
||||
|
||||
#include "postgres.h" /* XXX */
|
||||
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/itemptr.h"
|
||||
#include "storage/sinval.h"
|
||||
|
||||
/*
|
||||
* The structure of the shared cache invaidation segment
|
||||
*
|
||||
*/
|
||||
/*
|
||||
A------------- Header info --------------
|
||||
criticalSectionSemaphoreId
|
||||
generalSemaphoreId
|
||||
startEntrySection (offset a)
|
||||
endEntrySection (offset a + b)
|
||||
startFreeSpace (offset relative to B)
|
||||
startEntryChain (offset relatiev to B)
|
||||
endEntryChain (offset relative to B)
|
||||
numEntries
|
||||
maxNumEntries
|
||||
procState[MaxBackendId] --> limit
|
||||
resetState (bool)
|
||||
a tag (POSTID)
|
||||
B------------- Start entry section -------
|
||||
SISegEntry --> entryData --> ... (see SharedInvalidData!)
|
||||
isfree (bool)
|
||||
next (offset to next entry in chain )
|
||||
b .... (dynamically growing down)
|
||||
C----------------End shared segment -------
|
||||
|
||||
*/
|
||||
|
||||
/* Parameters (configurable) *******************************************/
|
||||
#define MaxBackendId 32 /* maximum number of backends */
|
||||
#define MAXNUMMESSAGES 1000 /* maximum number of messages in seg*/
|
||||
|
||||
|
||||
#define InvalidOffset 1000000000 /* a invalid offset (End of chain) */
|
||||
|
||||
typedef struct ProcState {
|
||||
int limit; /* the number of read messages */
|
||||
bool resetState; /* true, if backend has to reset its state */
|
||||
int tag; /* special tag, recieved from the postmaster */
|
||||
} ProcState;
|
||||
|
||||
|
||||
typedef struct SISeg {
|
||||
IpcSemaphoreId criticalSectionSemaphoreId; /* semaphore id */
|
||||
IpcSemaphoreId generalSemaphoreId; /* semaphore id */
|
||||
Offset startEntrySection; /* (offset a) */
|
||||
Offset endEntrySection; /* (offset a + b) */
|
||||
Offset startFreeSpace; /* (offset relative to B) */
|
||||
Offset startEntryChain; /* (offset relative to B) */
|
||||
Offset endEntryChain; /* (offset relative to B) */
|
||||
int numEntries;
|
||||
int maxNumEntries;
|
||||
ProcState procState[MaxBackendId]; /* reflects the invalidation state */
|
||||
/* here starts the entry section, controlled by offsets */
|
||||
} SISeg;
|
||||
#define SizeSISeg sizeof(SISeg)
|
||||
|
||||
typedef struct SharedInvalidData {
|
||||
int cacheId; /* XXX */
|
||||
Index hashIndex;
|
||||
ItemPointerData pointerData;
|
||||
} SharedInvalidData;
|
||||
|
||||
typedef SharedInvalidData *SharedInvalid;
|
||||
|
||||
|
||||
typedef struct SISegEntry {
|
||||
SharedInvalidData entryData; /* the message data */
|
||||
bool isfree; /* entry free? */
|
||||
Offset next; /* offset to next entry*/
|
||||
} SISegEntry;
|
||||
|
||||
#define SizeOfOneSISegEntry sizeof(SISegEntry)
|
||||
|
||||
typedef struct SISegOffsets {
|
||||
Offset startSegment; /* always 0 (for now) */
|
||||
Offset offsetToFirstEntry; /* A + a = B */
|
||||
Offset offsetToEndOfSegemnt; /* A + a + b */
|
||||
} SISegOffsets;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* synchronization of the shared buffer access */
|
||||
/* access to the buffer is synchronized by the lock manager !! */
|
||||
/****************************************************************************/
|
||||
|
||||
#define SI_LockStartValue 255
|
||||
#define SI_SharedLock (-1)
|
||||
#define SI_ExclusiveLock (-255)
|
||||
|
||||
extern SISeg *shmInvalBuffer;
|
||||
|
||||
/*
|
||||
* prototypes for functions in sinvaladt.c
|
||||
*/
|
||||
extern int SIBackendInit(SISeg *segInOutP);
|
||||
extern int SISegmentInit(bool killExistingSegment, IPCKey key);
|
||||
|
||||
extern bool SISetDataEntry(SISeg *segP, SharedInvalidData *data);
|
||||
extern void SISetProcStateInvalid(SISeg *segP);
|
||||
extern bool SIDelDataEntry(SISeg *segP);
|
||||
extern void SIReadEntryData(SISeg *segP, int backendId,
|
||||
void (*invalFunction)(), void (*resetFunction)());
|
||||
extern void SIDelExpiredDataEntries(SISeg *segP);
|
||||
|
||||
#endif /* SINVALADT_H */
|
||||
84
src/include/storage/smgr.h
Normal file
84
src/include/storage/smgr.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* smgr.h--
|
||||
* storage manager switch public interface declarations.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: smgr.h,v 1.1 1996/08/28 01:58:32 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SMGR_H
|
||||
#define SMGR_H
|
||||
|
||||
#include "utils/rel.h"
|
||||
#include "storage/spin.h" /* for SPINLOCK */
|
||||
|
||||
#define SM_FAIL 0
|
||||
#define SM_SUCCESS 1
|
||||
|
||||
#define DEFAULT_SMGR 0
|
||||
|
||||
extern int smgrinit(void);
|
||||
extern void smgrshutdown(int dummy);
|
||||
extern int smgrcreate(int16 which, Relation reln);
|
||||
extern int smgrunlink(int16 which, Relation reln);
|
||||
extern int smgrextend(int16 which, Relation reln, char *buffer);
|
||||
extern int smgropen(int16 which, Relation reln);
|
||||
extern int smgrclose(int16 which, Relation reln);
|
||||
extern int smgrread(int16 which, Relation reln, BlockNumber blocknum,
|
||||
char *buffer);
|
||||
extern int smgrwrite(int16 which, Relation reln, BlockNumber blocknum,
|
||||
char *buffer);
|
||||
extern int smgrflush(int16 which, Relation reln, BlockNumber blocknum,
|
||||
char *buffer);
|
||||
extern int smgrblindwrt(int16 which, char *dbname, char *relname, Oid dbid,
|
||||
Oid relid, BlockNumber blkno, char *buffer);
|
||||
extern int smgrnblocks(int16 which, Relation reln);
|
||||
extern int smgrcommit(void);
|
||||
extern int smgrabort(void);
|
||||
extern bool smgriswo(int16 smgrno);
|
||||
|
||||
|
||||
|
||||
/* internals: move me elsewhere -- ay 7/94 */
|
||||
|
||||
/* in md.c */
|
||||
extern int mdinit(void);
|
||||
extern int mdcreate(Relation reln);
|
||||
extern int mdunlink(Relation reln);
|
||||
extern int mdextend(Relation reln, char *buffer);
|
||||
extern int mdopen(Relation reln);
|
||||
extern int mdclose(Relation reln);
|
||||
extern int mdread(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mdwrite(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mdflush(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mdblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
|
||||
BlockNumber blkno, char *buffer);
|
||||
extern int mdnblocks(Relation reln);
|
||||
extern int mdcommit(void);
|
||||
extern int mdabort(void);
|
||||
|
||||
/* mm.c */
|
||||
extern SPINLOCK MMCacheLock;
|
||||
|
||||
extern int mminit(void);
|
||||
extern int mmshutdown(void);
|
||||
extern int mmcreate(Relation reln);
|
||||
extern int mmunlink(Relation reln);
|
||||
extern int mmextend(Relation reln, char *buffer);
|
||||
extern int mmopen(Relation reln);
|
||||
extern int mmclose(Relation reln);
|
||||
extern int mmread(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mmwrite(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mmflush(Relation reln, BlockNumber blocknum, char *buffer);
|
||||
extern int mmblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
|
||||
BlockNumber blkno, char *buffer);
|
||||
extern int mmnblocks(Relation reln);
|
||||
extern int mmcommit(void);
|
||||
extern int mmabort(void);
|
||||
extern int MMShmemSize(void);
|
||||
|
||||
#endif /* SMGR_H */
|
||||
38
src/include/storage/spin.h
Normal file
38
src/include/storage/spin.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* spin.h--
|
||||
* synchronization routines
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: spin.h,v 1.1 1996/08/28 01:58:33 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SPIN_H
|
||||
#define SPIN_H
|
||||
|
||||
#include "ipc.h"
|
||||
|
||||
/*
|
||||
* two implementations of spin locks
|
||||
*
|
||||
* sequent, sparc, sun3: real spin locks. uses a TAS instruction; see
|
||||
* src/storage/ipc/s_lock.c for details.
|
||||
*
|
||||
* default: fake spin locks using semaphores. see spin.c
|
||||
*
|
||||
*/
|
||||
|
||||
typedef int SPINLOCK;
|
||||
|
||||
extern bool CreateSpinlocks(IPCKey key);
|
||||
extern bool AttachSpinLocks(IPCKey key);
|
||||
extern bool InitSpinLocks(int init, IPCKey key);
|
||||
|
||||
extern void SpinAcquire(SPINLOCK lock);
|
||||
extern void SpinRelease(SPINLOCK lock);
|
||||
extern bool SpinIsLocked(SPINLOCK lock);
|
||||
|
||||
#endif /* SPIN_H */
|
||||
Reference in New Issue
Block a user