8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 07:23:02 +01:00
firebird-mirror/src/jrd/cch.h

369 lines
11 KiB
C
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD access method
* MODULE: cch.h
* DESCRIPTION: Cache manager definitions
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef JRD_CCH_H
#define JRD_CCH_H
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
#include "../include/fb_blk.h"
2011-05-09 12:15:19 +02:00
#include "../common/classes/alloc.h"
#include "../common/classes/RefCounted.h"
#include "../common/classes/semaphore.h"
2011-05-09 12:15:19 +02:00
#include "../common/classes/SyncObject.h"
#ifdef SUPERSERVER_V2
#include "../jrd/sbm.h"
2006-05-22 00:07:35 +02:00
#include "../jrd/pag.h"
#endif
#include "../jrd/que.h"
#include "../jrd/lls.h"
#include "../jrd/pag.h"
//#define CCH_DEBUG
#ifdef CCH_DEBUG
DEFINE_TRACE_ROUTINE(cch_trace);
#define CCH_TRACE(args) cch_trace args
#define CCH_TRACE_AST(message) gds__trace(message)
#else
2009-08-22 14:16:47 +02:00
#define CCH_TRACE(args) // nothing
#define CCH_TRACEE_AST(message) // nothing
#endif
namespace Ods {
struct pag;
}
namespace Jrd {
2001-12-24 03:51:06 +01:00
class Lock;
class Precedence;
class thread_db;
2004-03-07 08:58:55 +01:00
struct que;
class BufferDesc;
2004-04-10 02:25:22 +02:00
class Database;
2009-08-22 14:16:47 +02:00
// Page buffer cache size constraints.
2001-05-23 15:26:42 +02:00
const ULONG MIN_PAGE_BUFFERS = 50;
#if SIZEOF_VOID_P == 4
const ULONG MAX_PAGE_BUFFERS = 131072;
#else
const ULONG MAX_PAGE_BUFFERS = MAX_SLONG - 1;
#endif
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
// BufferControl -- Buffer control block -- one per system
2001-05-23 15:26:42 +02:00
struct bcb_repeat
{
2009-08-22 14:16:47 +02:00
BufferDesc* bcb_bdb; // Buffer descriptor block
que bcb_page_mod; // Que of buffers with page mod n
};
2011-05-09 12:15:19 +02:00
class BufferControl : public pool_alloc<type_bcb>
2001-05-23 15:26:42 +02:00
{
2011-05-12 02:42:40 +02:00
explicit BufferControl(MemoryPool& p)
: bcb_bufferpool(&p),
bcb_memory(p)
2011-05-10 03:12:14 +02:00
{
2011-05-09 12:15:19 +02:00
bcb_database = NULL;
QUE_INIT(bcb_in_use);
QUE_INIT(bcb_pending);
QUE_INIT(bcb_empty);
QUE_INIT(bcb_dirty);
bcb_dirty_count = 0;
bcb_free = NULL;
bcb_flags = 0;
bcb_free_minimum = 0;
bcb_count = 0;
bcb_inuse = 0;
bcb_prec_walk_mark = 0;
bcb_page_size = 0;
bcb_page_incarnation = 0;
#ifdef SUPERSERVER_V2
bcb_prefetch = NULL;
#endif
}
public:
2011-05-09 12:15:19 +02:00
static BufferControl* create();
static void destroy(BufferControl*);
Database* bcb_database;
2011-05-09 12:15:19 +02:00
Firebird::MemoryPool* bcb_bufferpool;
Firebird::MemoryStats bcb_memory_stats;
2009-08-22 14:16:47 +02:00
UCharStack bcb_memory; // Large block partitioned into buffers
2011-05-09 12:15:19 +02:00
que bcb_in_use; // Que of buffers in use, main LRU que
que bcb_pending; // Que of buffers which are going to be freed and reassigned
2009-08-22 14:16:47 +02:00
que bcb_empty; // Que of empty buffers
2011-05-09 12:15:19 +02:00
2011-05-10 03:12:14 +02:00
// Recently used buffer put there without locking common LRU que (bcb_in_use).
2011-05-09 12:15:19 +02:00
// When bcb_syncLRU is locked this chain is merged into bcb_in_use. See also
// requeueRecentlyUsed() and recentlyUsed()
2011-05-10 03:12:14 +02:00
Firebird::AtomicPointer<BufferDesc> bcb_lru_chain;
2011-05-09 12:15:19 +02:00
que bcb_dirty; // que of dirty buffers
2008-12-05 01:56:15 +01:00
SLONG bcb_dirty_count; // count of pages in dirty page btree
2011-05-09 12:15:19 +02:00
2009-08-22 14:16:47 +02:00
Precedence* bcb_free; // Free precedence blocks
SSHORT bcb_flags; // see below
SSHORT bcb_free_minimum; // Threshold to activate cache writer
ULONG bcb_count; // Number of buffers allocated
2011-05-09 12:15:19 +02:00
ULONG bcb_inuse; // Number of buffers in use
ULONG bcb_prec_walk_mark; // mark value used in precedence graph walk
2011-05-09 12:15:19 +02:00
ULONG bcb_page_size; // Database page size in bytes
ULONG bcb_page_incarnation; // Cache page incarnation counter
Firebird::SyncObject bcb_syncObject;
Firebird::SyncObject bcb_syncDirtyBdbs;
Firebird::SyncObject bcb_syncPrecedence;
Firebird::SyncObject bcb_syncLRU;
//Firebird::SyncObject bcb_syncPageWrite;
2011-05-12 02:42:40 +02:00
Firebird::Semaphore bcb_writer_sem; // Wake up cache writer
Firebird::Semaphore bcb_writer_init; // Cache writer initialization
Firebird::Semaphore bcb_writer_fini; // Cache writer finalization
#ifdef SUPERSERVER_V2
2011-05-09 12:15:19 +02:00
// the code in cch.cpp is not tested for semaphore instead event !!!
2011-05-12 02:42:40 +02:00
Firebird::Semaphore bcb_reader_sem; // Wake up cache reader
Firebird::Semaphore bcb_reader_init; // Cache reader initialization
Firebird::Semaphore bcb_reader_fini; // Cache reader finalization
2011-05-09 12:15:19 +02:00
2009-08-22 14:16:47 +02:00
PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch
#endif
2011-05-09 12:15:19 +02:00
bcb_repeat* bcb_rpt;
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
const int BCB_keep_pages = 1; // set during btc_flush(), pages not removed from dirty binary tree
const int BCB_cache_writer = 2; // cache writer thread has been started
2007-01-18 16:50:18 +01:00
const int BCB_writer_start = 4; // cache writer thread is starting now
2009-08-22 14:16:47 +02:00
const int BCB_writer_active = 8; // no need to post writer event count
#ifdef SUPERSERVER_V2
2009-08-22 14:16:47 +02:00
const int BCB_cache_reader = 16; // cache reader thread has been started
const int BCB_reader_active = 32; // cache reader not blocked on event
#endif
2009-08-22 14:16:47 +02:00
const int BCB_free_pending = 64; // request cache writer to free pages
2011-05-09 12:15:19 +02:00
const int BCB_exclusive = 128; // there is only BCB in whole system
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
// BufferDesc -- Buffer descriptor block
2001-05-23 15:26:42 +02:00
class BufferDesc : public pool_alloc<type_bdb>
2001-05-23 15:26:42 +02:00
{
2006-05-22 00:07:35 +02:00
public:
2011-06-24 08:34:16 +02:00
explicit BufferDesc(BufferControl* bcb)
2011-05-12 02:42:40 +02:00
: bdb_bcb(bcb),
bdb_page(0, 0),
bdb_pending_page(0, 0)
2011-05-09 12:15:19 +02:00
{
bdb_lock = NULL;
QUE_INIT(bdb_que);
QUE_INIT(bdb_in_use);
QUE_INIT(bdb_dirty);
bdb_buffer = NULL;
bdb_incarnation = 0;
bdb_transactions = 0;
bdb_mark_transaction = 0;
QUE_INIT(bdb_lower);
QUE_INIT(bdb_higher);
bdb_exclusive = NULL;
bdb_io = NULL;
bdb_writers = 0;
bdb_scan_count = 0;
bdb_difference_page = 0;
bdb_prec_walk_mark = 0;
}
void addRef(thread_db* tdbb, Firebird::SyncType syncType);
bool addRefConditional(thread_db* tdbb, Firebird::SyncType syncType);
void downgrade(Firebird::SyncType syncType);
void release(thread_db* tdbb);
void lockIO(thread_db*);
void unLockIO(thread_db*);
bool isLocked() const
{
return bdb_syncPage.isLocked();
}
bool ourExclusiveLock() const
{
return bdb_syncPage.ourExclusiveLock();
}
bool ourIOLock() const
{
return bdb_syncIO.ourExclusiveLock();
}
BufferControl* bdb_bcb;
Firebird::SyncObject bdb_syncPage;
2009-08-22 14:16:47 +02:00
Lock* bdb_lock; // Lock block for buffer
2011-05-09 12:15:19 +02:00
que bdb_que; // Either mod que in hash table or bcb_pending que if BDB_free_pending flag is set
2009-08-22 14:16:47 +02:00
que bdb_in_use; // queue of buffers in use
que bdb_dirty; // dirty pages LRU queue
2011-05-09 12:15:19 +02:00
BufferDesc* bdb_lru_chain; // pending LRU chain
2009-08-22 14:16:47 +02:00
Ods::pag* bdb_buffer; // Actual buffer
PageNumber bdb_page; // Database page number in buffer
2011-05-09 12:15:19 +02:00
PageNumber bdb_pending_page; // Database page number to be
ULONG bdb_incarnation;
2009-08-22 14:16:47 +02:00
ULONG bdb_transactions; // vector of dirty flags to reduce commit overhead
TraNumber bdb_mark_transaction; // hi-water mark transaction to defer header page I/O
2009-08-22 14:16:47 +02:00
que bdb_lower; // lower precedence que
que bdb_higher; // higher precedence que
thread_db* bdb_exclusive; // thread holding exclusive latch
2011-05-12 02:42:40 +02:00
2011-05-09 12:15:19 +02:00
private:
2011-05-12 02:42:40 +02:00
thread_db* bdb_io; // thread holding io latch
2011-05-09 12:15:19 +02:00
Firebird::SyncObject bdb_syncIO;
2011-05-12 02:42:40 +02:00
2011-05-09 12:15:19 +02:00
public:
Firebird::AtomicCounter bdb_ast_flags; // flags manipulated at AST level
Firebird::AtomicCounter bdb_flags;
Firebird::AtomicCounter bdb_use_count; // Number of active users
SSHORT bdb_writers; // Number of recursively taken exclusive locks
SSHORT bdb_io_locks; // Number of recursively taken IO locks
2009-08-22 14:16:47 +02:00
SSHORT bdb_scan_count; // concurrent sequential scans
ULONG bdb_difference_page; // Number of page in difference file, NBAK
ULONG bdb_prec_walk_mark; // mark value used in precedence graph walk
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
// bdb_flags
2001-05-23 15:26:42 +02:00
2009-03-18 03:43:15 +01:00
// to set/clear BDB_dirty use set_dirty_flag()/clear_dirty_flag()
2009-08-23 14:35:03 +02:00
// These constants should really be of type USHORT.
2011-05-09 12:15:19 +02:00
const int BDB_dirty = 0x0001; // page has been updated but not written yet
const int BDB_garbage_collect = 0x0002; // left by scan for garbage collector
const int BDB_writer = 0x0004; // someone is updating the page
const int BDB_marked = 0x0008; // page has been updated
const int BDB_must_write = 0x0010; // forces a write as soon as the page is released
const int BDB_faked = 0x0020; // page was just allocated
2011-05-12 02:42:40 +02:00
//const int BDB_merge = 0x0040;
2011-05-09 12:15:19 +02:00
const int BDB_system_dirty = 0x0080; // system transaction has marked dirty
const int BDB_io_error = 0x0100; // page i/o error
const int BDB_read_pending = 0x0200; // read is pending
const int BDB_free_pending = 0x0400; // buffer being freed for reuse
const int BDB_not_valid = 0x0800; // i/o error invalidated buffer
const int BDB_db_dirty = 0x1000; // page must be written to database
//const int BDB_checkpoint = 0x2000; // page must be written by next checkpoint
2011-05-09 12:15:19 +02:00
const int BDB_prefetch = 0x4000; // page has been prefetched but not yet referenced
const int BDB_no_blocking_ast = 0x8000; // No blocking AST registered with page lock
const int BDB_lru_chained = 0x10000; // buffer is in pending LRU chain
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
// bdb_ast_flags
2001-05-23 15:26:42 +02:00
2011-05-09 12:15:19 +02:00
const int BDB_blocking = 0x01; // a blocking ast was sent while page locked
2001-05-23 15:26:42 +02:00
2009-08-22 14:16:47 +02:00
// PRE -- Precedence block
2001-05-23 15:26:42 +02:00
class Precedence : public pool_alloc<type_pre>
2001-05-23 15:26:42 +02:00
{
2008-05-10 05:44:57 +02:00
public:
BufferDesc* pre_hi;
BufferDesc* pre_low;
que pre_lower;
que pre_higher;
SSHORT pre_flags;
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2004-04-29 16:51:02 +02:00
const int PRE_cleared = 1;
2001-05-23 15:26:42 +02:00
/* Compatibility matrix for latch types.
An exclusive latch is needed to modify a page. Before
marking a page an 'io-prevention' latch is needed: a mark latch.
To look at a buffer, a shared latch is needed. To write a page,
2008-12-05 01:56:15 +01:00
an io latch is needed.
2001-05-23 15:26:42 +02:00
2008-12-05 01:56:15 +01:00
Exclusive and shared latches interact. Io and mark latches
2001-05-23 15:26:42 +02:00
interact.
An mark latch is implemented as an io latch.
2008-12-05 01:56:15 +01:00
2001-05-23 15:26:42 +02:00
Latches are granted in the order in which they are
queued with one notable exception -- if buffer write
is in-progress then shared latches are granted ahead
2008-12-05 01:56:15 +01:00
of any pending exclusive latches.
2001-05-23 15:26:42 +02:00
shared io exclusive mark
-------------------------------------------------
shared 1 - 0 -
io - 0 - 0
exclusive 0 - 0 -
mark - 0 - 0 */
2009-08-22 14:16:47 +02:00
// LATCH types
2001-05-23 15:26:42 +02:00
2004-05-24 19:31:47 +02:00
enum LATCH
2001-05-23 15:26:42 +02:00
{
LATCH_none,
LATCH_shared,
LATCH_io,
LATCH_exclusive,
LATCH_mark
2004-05-24 19:31:47 +02:00
};
2001-05-23 15:26:42 +02:00
#ifdef SUPERSERVER_V2
2003-07-14 12:35:49 +02:00
#include "../jrd/os/pio.h"
2001-05-23 15:26:42 +02:00
// Constants used by prefetch mechanism
2001-05-23 15:26:42 +02:00
const int PREFETCH_MAX_TRANSFER = 16384; // maximum block I/O transfer (bytes)
// maximum pages allowed per prefetch request
const int PREFETCH_MAX_PAGES = (2 * PREFETCH_MAX_TRANSFER / MIN_PAGE_SIZE);
2001-05-23 15:26:42 +02:00
// Prefetch block
2001-05-23 15:26:42 +02:00
class Prefetch : public pool_alloc<type_prf>
2001-05-23 15:26:42 +02:00
{
2008-05-10 05:44:57 +02:00
public:
2009-08-22 14:16:47 +02:00
thread_db* prf_tdbb; // thread database context
SLONG prf_start_page; // starting page of multipage prefetch
USHORT prf_max_prefetch; // maximum no. of pages to prefetch
USHORT prf_page_count; // actual no. of pages being prefetched
phys_io_blk prf_piob; // physical I/O status block
SCHAR* prf_aligned_buffer; // buffer address aligned for raw (OS cache bypass) I/O
SCHAR* prf_io_buffer; // I/O buffer address
2001-05-23 15:26:42 +02:00
UCHAR prf_flags;
BufferDesc* prf_bdbs[PREFETCH_MAX_TRANSFER / MIN_PAGE_SIZE];
2001-05-23 15:26:42 +02:00
SCHAR prf_unaligned_buffer[PREFETCH_MAX_TRANSFER + MIN_PAGE_SIZE];
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2009-08-23 03:27:46 +02:00
const int PRF_active = 1; // prefetch block currently in use
#endif // SUPERSERVER_V2
2001-05-23 15:26:42 +02:00
typedef Firebird::SortedArray<SLONG, Firebird::InlineStorage<SLONG, 256>, SLONG> PagesArray;
2011-05-09 12:15:19 +02:00
} //namespace Jrd
#endif // JRD_CCH_H