662 lines
20 KiB
C
662 lines
20 KiB
C
/****************************************************************************
|
|
|
|
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
|
|
| All Rights Reserved.
|
|
|
|
|
| This program is free software; you can redistribute it and/or
|
|
| modify it under the terms of version 2 of the GNU General Public
|
|
| License as published by the Free Software Foundation.
|
|
|
|
|
| This program is distributed in the hope that it will be useful,
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| GNU General Public License for more details.
|
|
|
|
|
| You should have received a copy of the GNU General Public License
|
|
| along with this program; if not, contact Novell, Inc.
|
|
|
|
|
| To contact Novell about this file by physical or electronic mail,
|
|
| you may find current contact information at www.novell.com
|
|
|
|
|
|***************************************************************************
|
|
|
|
|
| NetWare Advance File Services (NSS) Initialization module
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
|
|
|
| $Author: gpachner $
|
|
| $Date: 2007-07-11 05:18:49 +0530 (Wed, 11 Jul 2007) $
|
|
|
|
|
| $RCSfile$
|
|
| $Revision: 2084 $
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
| This module is used to:
|
|
| Definitions used by caching.
|
|
|
|
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
|
|
|
|
| This header file should ONLY be used for NSS internal development.
|
|
| This includes Semantic Agents (SA) and Loadable Storage Services (LSS).
|
|
| Any other use may cause conflicts which NSS will NOT fix.
|
|
+-------------------------------------------------------------------------*/
|
|
#ifndef _XCACHE_H_
|
|
#define _XCACHE_H_
|
|
|
|
#ifndef _LATCH_H_
|
|
# include <include/latch.h>
|
|
#endif
|
|
|
|
#ifndef _QUE_H_
|
|
# include <library/que.h>
|
|
#endif
|
|
|
|
#ifndef _ALARM_H_
|
|
# include <include/alarm.h>
|
|
#endif
|
|
|
|
#ifndef _CONTROL_H_
|
|
# include <include/control.h>
|
|
#endif
|
|
|
|
#ifndef _FSM_H_
|
|
# include <include/fsm.h>
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Pre-define struct(s) so Linux compiler doesn't complain */
|
|
struct Agent_s;
|
|
struct Pool_s;
|
|
|
|
/*
|
|
* This is here because ASYNCIO.H needs it
|
|
*/
|
|
typedef void (*AgentSignalFunc_t)(struct Agent_s *agent);
|
|
|
|
#ifndef _ASYNCIO_H_
|
|
# include <include/asyncio.h>
|
|
#endif
|
|
|
|
|
|
/*
|
|
* States for buffers:
|
|
*
|
|
* When a buffer is victim selected and is dirty, it is flushed to
|
|
* disk then put at the head of the LRU queue so it is used on the
|
|
* next cache miss.
|
|
*
|
|
* If a buffer is currently in use when you try to toss it, we defer
|
|
* the toss but do remove it from the hash list. On the last release,
|
|
* we put it at the head of the LRU queue.
|
|
*/
|
|
#define CACHE_CLEAR 0 /* No flags set */
|
|
#define CACHE_DIRTY 0x1 /* Needs to be flushed to disk */
|
|
#define CACHE_VICTIM 0x2 /* Was selected as a victim but
|
|
* was dirty and needed to be
|
|
* written. Put at front of LRU
|
|
* queue when done.
|
|
*/
|
|
#define CACHE_TOSS 0x4 /* When this cache buffer is released,
|
|
* just toss it even if it is dirty.
|
|
* (It has already been removed from
|
|
* the hash list).
|
|
*/
|
|
#define CACHE_LOG_TEST 0x8 /* Used while undo/redo testing for
|
|
* recovery to not release buffers
|
|
*/
|
|
#define CACHE_MEMORY_BUFFER 0x10 /* Used by admin volume to indicate
|
|
* whether a buffer should be flushed
|
|
* to disk or to memory.
|
|
*/
|
|
#define CACHE_ATTACHED 0x20 /* When we copy the buffer if someone
|
|
* tries to X_Latch it, while it is
|
|
* being flushed, we set this bit to
|
|
* indicate a bond has been set up
|
|
*/
|
|
#define CACHE_USER_BUFFER 0x40 /* This buffer is being used for
|
|
* user data.
|
|
*/
|
|
#define CACHE_FAKE_BUFFER 0x80 /* Used while waiting to alloc a
|
|
* cache buffer, so that another
|
|
* requesting this same buffer
|
|
* knows about it.
|
|
*/
|
|
#define CACHE_HAS_LINUX_PAGE 0x100 /* This buffer has a page associated
|
|
* with a inode that Linux is
|
|
* managing. If this buffer is not
|
|
* dirty and/or bonded, we can
|
|
* return the page to the linux
|
|
* cache and we will look for it
|
|
* there.
|
|
*/
|
|
//#define CACHE_HAS_NO_LINUX_PAGE 0x200 /* This buffer was created for a
|
|
// * for a Linux Page. But we returned
|
|
// * the page to the Linux cache. We
|
|
// * will look for the page in the
|
|
// * Linux cache and if found, associate
|
|
// * it with this buffer again.
|
|
// */
|
|
#define CACHE_STATE_INVALID 0x400
|
|
#define CACHE_DATA_VALID 0x800 /* The data in the page
|
|
* pointed to by this buffer is
|
|
* valid. No need to read from
|
|
* disk again.
|
|
*/
|
|
|
|
/*
|
|
* Access modes for cache
|
|
*/
|
|
#define CACHE_READ 0 /* Going to read -> shared access */
|
|
#define CACHE_WRITE 1 /* Going to write whole block -> exlusive */
|
|
#define CACHE_UPDATE 2 /* Going to update part of block ->exlusive */
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* These structures and functions are used to setup
|
|
* dependencies between different entities. The entities
|
|
* never see the Bond_s structure but must include
|
|
* the Agent_s structure inside of themselves.
|
|
*
|
|
* The signal functionslets the agent control its behavior when all
|
|
* dependcies have been satisfied. After the specified signal function
|
|
* is finished, it should call the default signal routine.
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
typedef struct Agent_s Agent_s;
|
|
|
|
/* These are values for Agent_s state */
|
|
/* the values 0xFFFF0000 are reserved for local use by the object which
|
|
* contains the agent */
|
|
#define AGENT_FLUSHING 0x0001 /* The agent wants to be flushed
|
|
*/
|
|
#define AGENT_AWAIT_SIGNALS 0x0002 /* Waiting for dependent signals
|
|
* before flushing. */
|
|
#define AGENT_WAIT_FOR_COMMIT 0x0004 /* Wait for the ZLOG buffer to which
|
|
* the EndXLocal gets written to
|
|
* commit
|
|
*/
|
|
#define AGENT_LOCAL_STATE_FLAGS 0xFFFF0000 /* The values in the high word of
|
|
* state are reserved for local use by the
|
|
* object which contains the agent */
|
|
|
|
struct Agent_s
|
|
{
|
|
FsmLite_s fsm; /* FSM for flushing agent's object */
|
|
Latch_s latch; /* Latch to synchronize flushing */
|
|
OneShot_s timer; /* One shot timer to force flushing */
|
|
STKtop_t signalList; /* List to signal after I'm flushed */
|
|
DQhead_t flushList; /* These must flush before agent can flush */
|
|
AgentSignalFunc_t signal; /* User defined signal function */
|
|
LONG numLeft; /* Count of signals I'm still waiting for that
|
|
* I already called the flush functions.
|
|
* This makes processing the flushList
|
|
* much simpler. */
|
|
NINT state; /* State: (eventually combine with numLeft) */
|
|
STATUS status; /* current status of the operation */
|
|
AgentSignalFunc_t bondFreedSignal; /* signal function when a bond is freed*/
|
|
};
|
|
|
|
typedef struct Bond_s
|
|
{
|
|
STKlink_t signalLink; /* List of objects to be signaled */
|
|
/* May be able to use a stack here */
|
|
Agent_s *toSignal; /* Object to signal after flush is done */
|
|
DQlink_t flushLink; /* Must wait until flushed */
|
|
Agent_s *toFlush; /* Object to flush */
|
|
} Bond_s;
|
|
|
|
|
|
#define MYCACHE_STATE_USING_BUFLIST 0x0001
|
|
#define MYCACHE_STATE_TRUNCATING 0x0002
|
|
#define MYCACHE_STATE_PURGING 0x0004
|
|
|
|
typedef struct MyCache_s
|
|
{
|
|
DQhead_t bufList; /* Buffers owned by beast */
|
|
Agent_s agent; /* Agent that is dependent */
|
|
BYTE bufSizeShift; /* Size file cache buffer log 2 */
|
|
BYTE reserved[1]; /* Align structure */
|
|
WORD state; /* State of the mycache */
|
|
} MyCache_s;
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* This Buffer matches zBuffer_s. Any modifications made here
|
|
* should be reflected in zBuffer_s in zParams.h
|
|
* zBuffer_s specifies fileBlk to be a QUAD, and if Blknum_t
|
|
* is changed to be 64-bit, the pad from this strucuture should be
|
|
* removed
|
|
*-------------------------------------------------------------------------*/
|
|
typedef struct PubBuffer_s
|
|
{
|
|
BYTE *data; /* Place first so other layers
|
|
* can access it with out knowing
|
|
* details.
|
|
*/
|
|
MyCache_s *mycache; /* Pointer to user of cache buffer */
|
|
Blknum_t fileBlk; /* Logical block offset in file */
|
|
#if BLKNUM_64 IS_DISABLED
|
|
LONG pad;
|
|
#endif
|
|
} PubBuffer_s;
|
|
|
|
typedef struct Buffer_s
|
|
{
|
|
PubBuffer_s pBuf;
|
|
#ifdef i386
|
|
Blknum_t volBlk; /* Location in volume */
|
|
#endif
|
|
|
|
#ifdef __x86_64__
|
|
SQUAD volBlk; /* Location in volume */
|
|
#endif
|
|
|
|
Agent_s agent; /* Agent for buffer */
|
|
|
|
DQlink_t hashLink; /* Link for hash queue */
|
|
DQlink_t lruLink; /* Link for LRU list */
|
|
|
|
DQlink_t mycacheLink; /* Link to all buffers for beast*/
|
|
DQlink_t signalLink; /* Link of buffers that signals are being
|
|
* delayed on. Used by ZLOG to delay signals
|
|
* until all previous log buffers have been
|
|
* flushed.
|
|
*/
|
|
AgentSignalFunc_t writeDone;/* if non-zero, when a write completes this
|
|
* routine should be called instead of doing
|
|
* the standard processing which consists of
|
|
* calling "defaultSignal" and
|
|
* "CACHE_SIGNAL_RELEASE"
|
|
*/
|
|
LONG state; /* Misc. state bits */
|
|
BYTE reserved;
|
|
BYTE bufSizeShift; /* Size of a buffer log 2 */
|
|
BYTE ioRetryCount; /* retry count when doing writes*/
|
|
BYTE pinned; /* Current count of pins on buf */
|
|
Time_t timeStamp; /* Time stamp when buffer waa put on LRU */
|
|
struct EncryptedBufPage_s *eData; /* pointer to encrypted volume data buffer */
|
|
struct page *b_page; /* A pointer to the page associated with data */
|
|
LONG b_mapCount; /* Number of times the buffer kmap is requested */
|
|
BioReq_s bioReq;
|
|
|
|
} Buffer_s;
|
|
|
|
|
|
extern void mapBufferPage(Buffer_s *buf);
|
|
extern void unmapBufferPage(Buffer_s *buf);
|
|
|
|
extern const Buffer_s *NSSPrivateBuffer;
|
|
/*-------------------------------------------------------------------------
|
|
* The following structures and macros support asynchronous IO requests
|
|
*-------------------------------------------------------------------------*/
|
|
typedef struct Synchronize_s
|
|
{
|
|
Latch_s waitLatch; /* Used to wait for all to finish */
|
|
struct zNSSMsg_s *msg; /* Message for requests */
|
|
} Synchronize_s;
|
|
|
|
#define SYNC_INIT(_sync, _msg) \
|
|
{ \
|
|
(_sync).msg = (_msg); \
|
|
INIT_LATCH( &((_sync).waitLatch)); \
|
|
}
|
|
|
|
#define SYNC_ADD(_sync) ADD_LATCH( &((_sync).waitLatch))
|
|
|
|
#define SYNC_WAIT(_sync) \
|
|
{ \
|
|
if (IS_SLATCHED( &((_sync).waitLatch))) \
|
|
{ \
|
|
X_LATCH( &((_sync).waitLatch)); \
|
|
UNX_LATCH( &((_sync).waitLatch)); \
|
|
} \
|
|
}
|
|
|
|
|
|
extern CIRhead_t WaitForCacheQ; /* Wait queue for free buffers */
|
|
extern Latch_s ReserveBuffers; /* Used to pre-alloc buffers */
|
|
extern Buffer_s CACHE_SparseBuffer; /* Used for sparse files */
|
|
|
|
#if NSS_DEBUG IS_ENABLED
|
|
#define CACHE_RELEASE(_buf) \
|
|
(cacheRelease(_buf), ((_buf) = ((_buf)->pinned) ? (_buf) : NULL))
|
|
|
|
#define CACHE_DIRTY_RELEASE(_buf) \
|
|
(ASSERT_XLATCH( &((_buf)->agent.latch)), \
|
|
((_buf)->state |= CACHE_DIRTY), CACHE_RELEASE(_buf))
|
|
|
|
#define CACHE_MARK_DIRTY(_buf) \
|
|
cacheMarkDirty(_buf) \
|
|
|
|
#define CACHE_CLEAN(_buf) \
|
|
((_buf)->state &= ~CACHE_DIRTY)
|
|
|
|
#define CACHE_SIGNAL_RELEASE(_buf) \
|
|
(cacheSignalRelease(_buf), ((_buf) = ((_buf)->pinned) ? (_buf) : NULL))
|
|
|
|
#define CACHE_SIGNAL_RELEASE_PUSH(_buf) \
|
|
(((_buf)->state |= CACHE_VICTIM), \
|
|
cacheSignalRelease(_buf), ((_buf) = ((_buf)->pinned) ? (_buf) : NULL))
|
|
|
|
#define CACHE_SIGNAL_RELEASE_TOSS(_buf) \
|
|
(cacheSignalReleaseToss(_buf), ((_buf) = ((_buf)->pinned) ? (_buf) : NULL))
|
|
|
|
#else
|
|
#define CACHE_RELEASE(_buf) \
|
|
(cacheRelease(_buf))
|
|
|
|
#define CACHE_DIRTY_RELEASE(_buf) \
|
|
(ASSERT_XLATCH( &((_buf)->agent.latch)), \
|
|
((_buf)->state |= CACHE_DIRTY), CACHE_RELEASE(_buf))
|
|
|
|
#define CACHE_MARK_DIRTY(_buf) \
|
|
cacheMarkDirty(_buf) \
|
|
|
|
#define CACHE_CLEAN(_buf) \
|
|
((_buf)->state &= ~CACHE_DIRTY)
|
|
|
|
#define CACHE_SIGNAL_RELEASE(_buf) \
|
|
(cacheSignalRelease(_buf))
|
|
|
|
#define CACHE_SIGNAL_RELEASE_PUSH(_buf) \
|
|
(((_buf)->state |= CACHE_VICTIM), \
|
|
cacheSignalRelease(_buf))
|
|
|
|
#define CACHE_SIGNAL_RELEASE_TOSS(_buf) \
|
|
(cacheSignalReleaseToss(_buf))
|
|
|
|
#endif
|
|
|
|
#define CACHE_XLATCH(_buf) \
|
|
X_LATCH( &(_buf)->agent.latch)
|
|
|
|
#define CACHE_SLATCH(_buf) \
|
|
S_LATCH( &(_buf)->agent.latch)
|
|
|
|
#define CACHE_UNXLATCH(_buf) \
|
|
UNX_LATCH( &(_buf)->agent.latch)
|
|
|
|
#define CACHE_UNSLATCH(_buf) \
|
|
UNS_LATCH( &(_buf)->agent.latch)
|
|
|
|
#define CACHE_UNLATCH(_buf) \
|
|
UN_LATCH( &(_buf)->agent.latch)
|
|
|
|
#define POKE_SIGNAL_HANDLER(_buf, _func) \
|
|
((_buf)->agent.signal = (_func))
|
|
|
|
#define CACHE_PIN(_buf) (++((_buf)->pinned))
|
|
|
|
#define CACHE_UNPIN(_buf) \
|
|
((void)(zASSERT((_buf)->pinned != 0),((--(_buf)->pinned) || cacheUnpinned(_buf))))
|
|
|
|
extern void initMyCache(
|
|
MyCache_s *mycache,
|
|
AgentSignalFunc_t signal,
|
|
NINT bufSizeShift,
|
|
char *name);
|
|
|
|
extern void checkMyCache(
|
|
MyCache_s *mycache);
|
|
|
|
|
|
extern void cacheFlushAll(void);
|
|
|
|
extern void cachePrepareToFlush(Buffer_s *buffer);
|
|
extern void cacheMarkDirty(Buffer_s *buffer);
|
|
extern void cacheRelease(Buffer_s *buffer);
|
|
extern void cacheReleaseToss(Buffer_s *buffer);
|
|
extern void cacheSignalRelease(Buffer_s *buffer);
|
|
extern void cacheSignalReleaseToss(Buffer_s *buffer);
|
|
extern void cacheFlush(Buffer_s *buffer);
|
|
extern BOOL cacheUnpinned(Buffer_s *buffer);
|
|
extern void cacheUnpin(Buffer_s *buffer);
|
|
|
|
extern void cacheFlushMyCache(
|
|
MyCache_s *mycache);
|
|
|
|
extern void cacheFlushMyCacheBufs(
|
|
MyCache_s *mycache);
|
|
|
|
extern void asyncCacheAllocBuffer(
|
|
Asyncio_s *asyncio,
|
|
voidfunc_t action,
|
|
AgentSignalFunc_t signal );
|
|
|
|
extern void asyncCacheAllocBufferForUserData(
|
|
Asyncio_s *asyncio,
|
|
voidfunc_t action,
|
|
AgentSignalFunc_t signal );
|
|
|
|
|
|
extern Buffer_s *cacheAllocBuffer(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk,
|
|
Blknum_t volBlk,
|
|
AgentSignalFunc_t signal,
|
|
NINT mode );
|
|
|
|
extern Buffer_s *cacheAllocBufferForUserData(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk,
|
|
Blknum_t volBlk,
|
|
AgentSignalFunc_t signal,
|
|
NINT mode );
|
|
|
|
extern Buffer_s *cacheAllocBufferForCopy(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk,
|
|
Blknum_t volBlk,
|
|
AgentSignalFunc_t signal,
|
|
BOOL userBuffer,
|
|
NINT mode );
|
|
|
|
extern Buffer_s *cacheFind (
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk);
|
|
|
|
extern NINT isCached(
|
|
Asyncio_s *asyncio,
|
|
voidfunc_t action);
|
|
|
|
extern Buffer_s *cacheLookup(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk,
|
|
NINT mode);
|
|
|
|
extern Buffer_s *fastCache(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk,
|
|
NINT mode);
|
|
|
|
extern Buffer_s *fastReadCache(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk);
|
|
|
|
#if 0
|
|
extern Buffer_s *fastUpdateCache(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk);
|
|
#endif
|
|
|
|
extern void cacheTossAll(
|
|
MyCache_s *mycache);
|
|
|
|
extern void cacheToss(
|
|
Buffer_s *buffer);
|
|
|
|
extern void cacheTossIfThere(
|
|
MyCache_s *mycache,
|
|
Blknum_t fileBlk);
|
|
|
|
extern void cacheTruncateMyCache(
|
|
MyCache_s *mycache,
|
|
Blknum_t truncAt,
|
|
Blkcnt_t count);
|
|
|
|
extern void cacheFlushAndTossMyCacheUserData(
|
|
MyCache_s *mycache);
|
|
|
|
#if 0
|
|
extern void cacheMoveMyCacheBufList(
|
|
MyCache_s *dstMycache,
|
|
MyCache_s *srcMycache);
|
|
#endif
|
|
|
|
extern Buffer_s *cacheAllocSlab(
|
|
MyCache_s *mycache,
|
|
AgentSignalFunc_t signal);
|
|
|
|
extern Buffer_s *cacheGrabSlab(MyCache_s *mycache);
|
|
extern void cacheReleaseSlab(Buffer_s *buffer);
|
|
|
|
extern Buffer_s *cacheTakeBuffer(void);
|
|
extern void cacheGiveBuffer(Buffer_s *buffer);
|
|
|
|
/*
|
|
* Removes a buffer from the cache for a beast
|
|
*/
|
|
#define MYCACHE_RMV(_buf) \
|
|
{ \
|
|
if (QMEMBER( &((_buf)->mycacheLink))) \
|
|
{ \
|
|
DQ_RMV(_buf, mycacheLink); \
|
|
} \
|
|
}
|
|
|
|
#define NO_BONDS(_d) (((_d)->numLeft == 0) && DQ_EMPTY( &((_d)->flushList)))
|
|
#define HAVE_BONDS(_d) (((_d)->numLeft != 0) || DQ_NOT_EMPTY( &((_d)->flushList)))
|
|
#define NO_SIGNALS(_d) (STK_EMPTY((_d)->signalList))
|
|
|
|
extern void initAgent(
|
|
Agent_s *agent,
|
|
AgentSignalFunc_t signal,
|
|
char *name);
|
|
|
|
extern void LB_defaultSignal(Agent_s *agent);
|
|
extern void LB_defaultFlush(Agent_s *agent);
|
|
extern void LB_defaultFlushWait(Agent_s *agent);
|
|
extern void LB_lazyFlush(Agent_s *agent);
|
|
extern void LB_continueFlush(FsmLite_s *fsm);
|
|
|
|
/* These macros should be used in an inner flush loop where we want to setup
|
|
* binds to dirty objects and immediatly call "defaultFlush" on the outer
|
|
* object. This prevents the signal propogation until the outer default flush
|
|
* is called */
|
|
/* on 7/24/97 Paul and Neal decided these were no longer necessary and were
|
|
* probably causing us problems because , they were changed to NULL macros */
|
|
#define STOP_SIGNAL_PROPAGATION(_agent) ((void)0)
|
|
#define START_SIGNAL_PROPAGATION(_agent) ((void)0)
|
|
|
|
/*Original versions */
|
|
//#define STOP_SIGNAL_PROPAGATION(_agent) (++(_agent)->numLeft)
|
|
//#define START_SIGNAL_PROPAGATION(_agent) (--(_agent)->numLeft)
|
|
|
|
/* this was a new version of this macro created on 7/24/97 because we found
|
|
* a case where we lost a signal. We thought it might be because we decremented
|
|
* the count and didn't send the signal if it went to zero (which could happen
|
|
* if someone else were already flushing the object. We pondered this new
|
|
* version and then decided we didn't need any of this stuff and took it all out */
|
|
/*
|
|
//#define START_SIGNAL_PROPAGATION(_agent) \
|
|
// { \
|
|
// Agent_s *agent = (_agent); \
|
|
// \
|
|
// zASSERT(agent->numLeft > 0); \
|
|
// agent->numLeft--; \
|
|
// if (NO_BONDS(agent) \
|
|
// && (agent->state & AGENT_FLUSHING) \
|
|
// && (agent->state & AGENT_AWAIT_SIGNALS)) \
|
|
// { \
|
|
// agent->state &= ~AGENT_AWAIT_SIGNALS; \
|
|
// agent->signal(agent); \
|
|
// } \
|
|
// }
|
|
*/
|
|
|
|
/**
|
|
* NSS_COPY_ON_XLATCH is used to disable the code that copies
|
|
* cache buffers if someone wishes to XLATCH the cache buffer
|
|
* when the buffer is being flushed to disk.
|
|
*
|
|
*/
|
|
#define NSS_COPY_ON_XLATCH ENABLE
|
|
//#define NSS_COPY_ON_XLATCH DISABLE
|
|
|
|
#if NSS_COPY_ON_XLATCH IS_ENABLED
|
|
extern BOOL gNSSCopyOnXLatch;
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Macros and function prototypes for manipulating bonds
|
|
* If using BOND_FSM_GET, you must call initBind to initialize
|
|
* the bond. The function _action is called with fsm and bond:
|
|
* _action(fsm, bond);
|
|
*-------------------------------------------------------------------------*/
|
|
extern ControlStore_s BondControl;
|
|
|
|
#define BOND_FSM_GET(_fsm, _action) \
|
|
CONTROL_fsmGet( &BondControl, (_fsm), (_action))
|
|
|
|
#define GET_BOND() ((Bond_s *)CONTROL_get( &BondControl))
|
|
#define SETUP_BOND(_bond, _toSignal, _toFlush) \
|
|
{ \
|
|
(_bond)->toSignal = (_toSignal); \
|
|
(_bond)->toFlush = (_toFlush); \
|
|
STK_PUSH((_toFlush)->signalList, (_bond), signalLink); \
|
|
DQ_ENQ( &(_toSignal)->flushList, (_bond), flushLink); \
|
|
}
|
|
|
|
#if NSS_DEBUG IS_ENABLED
|
|
#define FREE_UNUSED_BOND(_bond) \
|
|
((_bond)->toSignal = NULL, \
|
|
(_bond)->toFlush = NULL, \
|
|
LB_freeBond(_bond))
|
|
#else
|
|
#define FREE_UNUSED_BOND(_bond) \
|
|
(LB_freeBond(_bond))
|
|
#endif
|
|
|
|
|
|
void LB_initBind(Bond_s *bond, Agent_s *toSignal, Agent_s *toFlush);
|
|
void LB_bind(Agent_s *toSignal, Agent_s *toFlush);
|
|
void LB_freeBond(Bond_s *bond);
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Macros and function prototypes for manipulating asyncio structures
|
|
* The function _action is called with fsm and asyncio:
|
|
* _action(fsm, asyncio);
|
|
*-------------------------------------------------------------------------*/
|
|
extern ControlStore_s AsyncioControl;
|
|
extern ControlStore_s AsyncioControlRA;
|
|
|
|
#define ASYNCIO_FSM_GET(_fsm, _action) \
|
|
CONTROL_fsmGet( &AsyncioControl, (_fsm), (_action));
|
|
|
|
void LB_freeAsyncio(Asyncio_s *asyncio);
|
|
void LB_freeAsyncioRA(Asyncio_s *asyncio);
|
|
Asyncio_s *LB_getAsyncio(void);
|
|
Asyncio_s *LB_getAsyncioNoWait(void);
|
|
Asyncio_s *LB_getAsyncioNoWaitRA(void);
|
|
|
|
void WORK_Queue(FsmLite_s *fsm, voidfunc_t action, ADDR parameter);
|
|
void WORK_Schedule(FsmLite_s *fsm, voidfunc_t action, ADDR parameter);
|
|
void WORK_Schedule_HIGH(FsmLite_s *fsm, voidfunc_t action, ADDR parameter);
|
|
void WORK_Schedule_LOW(FsmLite_s *fsm, voidfunc_t action, ADDR parameter);
|
|
void WORK_WaitForPending(void);
|
|
|
|
extern void retBuffer_s(Buffer_s *buf);
|
|
|
|
void CACHE_LinuxStatsUpdate( BOOL user, NINT mode, BOOL missLinux );
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|