Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

451 lines
14 KiB

  1. //============== DAE: OS/2 Database Access Engine =====================
  2. //============== stapi.h: Storage System API =====================
  3. //---- externs -------------------------------------------------------------
  4. extern SEM __near semST;
  5. extern RES __near rgres[];
  6. extern TRX __near trxOldest;
  7. extern TRX __near trxNewest;
  8. extern SIG __near sigBFCleanProc;
  9. //---- IO (io.c) ----------------------------------------------------------
  10. #define LOffsetOfPgnoLow( pgno ) ( ((pgno) - 1) << 12 )
  11. #define LOffsetOfPgnoHigh( pgno ) ( ((pgno) - 1) >> 20 )
  12. #define fioqeOpenFile 1 /* for Opening File */
  13. #define fioqeCloseFile 2 /* for Closing File */
  14. #define fioqeDeleteFile 3 /* for deleting file */
  15. #define fioqeNewSize 4 /* for resize file */
  16. typedef struct _ioqe /* IO queue element */
  17. {
  18. struct _ioqe *pioqePrev; /* double linked IO queue list */
  19. struct _ioqe *pioqeNext;
  20. SIG sigIO; /* signal to wait for IO completion */
  21. ERR err; /* error code for err occurs during the IO */
  22. INT fioqe; /* use up to 16 bits only */
  23. } IOQE;
  24. #define fioqefileReadOnly fTrue
  25. #define fioqefileReadWrite fFalse
  26. typedef struct _ioqefile
  27. {
  28. IOQE;
  29. struct {
  30. BOOL fioqefile; /* open file for read only or not */
  31. HANDLE hf; /* file handle */
  32. char *sz; /* fioqe = fioqeOpenFile, CloseFile, ExtFile */
  33. struct {
  34. ULONG cb; /* how long the file is */
  35. ULONG cbHigh;
  36. };
  37. };
  38. } IOQEFILE;
  39. VOID IOInitFMP();
  40. ERR ErrInitFileMap( PIB *ppib );
  41. BOOL FFileExists( CHAR *szFileName );
  42. ERR ErrIOOpenFile( HANDLE *phf, CHAR *szDatabaseName, ULONG cb, BOOL fioqefile );
  43. VOID IOCloseFile( HANDLE hf );
  44. ERR ErrIONewSize( DBID dbid, CPG cpg );
  45. BOOL FIOFileExists( CHAR *szFileName );
  46. ERR ErrIOLockDbidByNameSz( CHAR *szFileName, DBID *pdbid );
  47. ERR ErrIOLockDbidByDbid( DBID dbid );
  48. ERR ErrIOLockNewDbid( DBID *pdbid, CHAR *szDatabaseName );
  49. ERR ErrIOSetDbid( DBID dbid, CHAR *szDatabaseName );
  50. VOID IOFreeDbid( DBID dbid );
  51. void BFOldestLgpos( LGPOS *plgposCheckPoint );
  52. VOID BFPurge( DBID dbid, PGNO pgnoFDP );
  53. #define FIODatabaseOpen( dbid ) ( rgfmp[dbid].hf != handleNil )
  54. ERR ErrIOOpenDatabase( DBID dbid, CHAR *szDatabaseName, CPG cpg );
  55. VOID IOCloseDatabase( DBID dbid );
  56. VOID IODeleteDatabase( DBID dbid );
  57. BOOL FIODatabaseInUse( DBID dbid );
  58. BOOL FIODatabaseAvailable( DBID dbid );
  59. #define FDatabaseLocked( dbid ) (rgfmp[dbid].fXOpen)
  60. #define IOUnlockDbid( dbid ) \
  61. { \
  62. SgSemRequest( semST ); \
  63. Assert( FDBIDWait( dbid ) ); \
  64. DBIDResetWait( dbid ); \
  65. SgSemRelease( semST ); \
  66. }
  67. #ifdef DEBUG
  68. #define IOSetDatabaseVersion( dbid, ulVersion ) \
  69. { \
  70. Assert( ulVersion == ulDAEPrevVersion || \
  71. ulVersion == ulDAEVersion ); \
  72. rgfmp[dbid].fPrevVersion = ( ulVersion == ulDAEPrevVersion );\
  73. }
  74. #else /* !DEBUG */
  75. #define IOSetDatabaseVersion( dbid, ulVersion )
  76. #endif /* !DEBUG */
  77. #define FIOExclusiveByAnotherSession( dbid, ppib ) \
  78. ( Assert( FDBIDWait( dbid ) ), FDBIDExclusiveByAnotherSession( dbid, ppib ) )
  79. #define IOSetExclusive( dbid, ppib ) \
  80. { \
  81. Assert( FDBIDWait( dbid ) ); \
  82. Assert( !( FDBIDExclusive( dbid ) ) ); \
  83. DBIDSetExclusive( dbid, ppib ); \
  84. }
  85. #define IOResetExclusive( dbid ) \
  86. { \
  87. Assert( FDBIDWait( dbid ) ); \
  88. DBIDResetExclusive( dbid ); \
  89. }
  90. #define FIOReadOnly( dbid ) \
  91. ( Assert( FDBIDWait( dbid ) ), FDBIDReadOnly( dbid ) )
  92. #define IOSetReadOnly( dbid ) \
  93. { \
  94. Assert( FDBIDWait( dbid ) ); \
  95. DBIDSetReadOnly( dbid ); \
  96. }
  97. #define IOResetReadOnly( dbid ) \
  98. { \
  99. Assert( FDBIDWait( dbid ) ); \
  100. DBIDResetReadOnly( dbid ); \
  101. }
  102. #define FIOAttached( dbid ) \
  103. ( Assert( FDBIDWait( dbid ) ), FDBIDAttached( dbid ) )
  104. #define IOSetAttached( dbid ) \
  105. { \
  106. Assert( FDBIDWait( dbid ) ); \
  107. Assert( !( FDBIDAttached( dbid ) ) ); \
  108. DBIDSetAttached( dbid ); \
  109. }
  110. #define IOResetAttached( dbid ) \
  111. { \
  112. Assert( FDBIDWait( dbid ) ); \
  113. Assert( FDBIDAttached( dbid ) ); \
  114. DBIDResetAttached( dbid ); \
  115. }
  116. //---- PAGE (page.c) --------------------------------------------------------
  117. // Max # of lines to update at once with ErrSTReplace
  118. #define clineMax 6
  119. #define UlSTDBTimePssib( pssib ) ( (pssib)->pbf->ppage->pghdr.ulDBTime )
  120. #define PMSetUlDBTime( pssib, ul ) \
  121. ( Assert( (ul) <= rgfmp[DbidOfPn((pssib)->pbf->pn)].ulDBTime ), \
  122. (pssib)->pbf->ppage->pghdr.ulDBTime = (ul) ) \
  123. #define BFSetUlDBTime( pbf, ul ) \
  124. ( Assert( (ul) <= rgfmp[DbidOfPn((pbf)->pn)].ulDBTime ), \
  125. (pbf)->ppage->pghdr.ulDBTime = (ul) ) \
  126. #ifdef DEBUG
  127. VOID AssertPMGet( SSIB *pssib, INT itag );
  128. #else
  129. #define AssertPMGet( pssib, itag )
  130. #endif
  131. //---- BUF (buf.c) ----------------------------------------------------------
  132. #define LRU_K 1
  133. CRIT __near critLRU;
  134. typedef struct _lru
  135. {
  136. INT cbfAvail; // clean available buffers in LRU list
  137. struct _bf *pbfLRU; // Least Recently Used buffer
  138. struct _bf *pbfMRU; // Most Recently Used buffer
  139. } LRULIST;
  140. typedef struct _bgcb // Buffer Group Control Block
  141. {
  142. struct _bgcb *pbgcbNext; // pointer to the next BCGB
  143. struct _bf *rgbf; // buffer control blocks for group
  144. struct _page *rgpage; // buffer control blocks for group
  145. INT cbfGroup; // number of bfs in this group
  146. INT cbfThresholdLow; // threshold to start cleaning buffers
  147. INT cbfThresholdHigh; // threshold to stop cleaning buffers
  148. LRULIST lrulist;
  149. } BGCB;
  150. #define pbgcbNil ((BGCB*)0)
  151. #define PbgcbMEMAlloc() (BGCB*)PbMEMAlloc(iresBGCB)
  152. #ifdef DEBUG /* Debug check for illegal use of freed bgcb */
  153. #define MEMReleasePbgcb(pbgcb) { MEMRelease(iresBGCB, (BYTE*)(pbgcb)); pbgcb = pbgcbNil; }
  154. #else
  155. #define MEMReleasePbgcb(pbgcb) { MEMRelease(iresBGCB, (BYTE*)(pbgcb)); }
  156. #endif
  157. typedef struct _bf
  158. {
  159. struct _page *ppage; // pointer to page buffer
  160. struct _bf *pbfNext; // hash table overflow
  161. struct _bf *pbfLRU; // pointer to Less Recently Used Buffer
  162. struct _bf *pbfMRU; // pointer to More Recently Used Buffer
  163. PIB *ppibWriteLatch; /* thread with Wait Latch */
  164. PIB *ppibWaitLatch; /* thread with Wait Latch */
  165. CRIT critBF; /* for setting fPreread/fRead/fWrite/fHold */
  166. OLP olp; /* for ssync IO, to wait for IO completion */
  167. HANDLE hf; /* for assync IO */
  168. struct _bf *pbfNextBatchIO; /* next BF in BatchIO list */
  169. INT ipageBatchIOFirst;
  170. ERR err; /* error code for err occurs during the IO */
  171. PN pn; // physical pn of cached page
  172. UINT cPin; // if cPin > 0 then buf cannot be overlayed
  173. UINT cReadLatch; // if cReadLatch > 0, page cannot be updated
  174. UINT cWriteLatch; // if cWriteLatch > 0, page cannot be updated by other
  175. UINT cWaitLatch;
  176. UINT fDirty:1; // indicates page needs to be flushed
  177. // the following flags are mutual exclusive:
  178. UINT fPreread:1; // indicates page is being prefetched
  179. UINT fRead:1; // indicates page is being read/written
  180. UINT fWrite:1; //
  181. UINT fHold:1; // indicates buf is in transient state.
  182. UINT fIOError:1; // indicates read/write error
  183. UINT fInHash:1; // BF is currently in hash table
  184. ULONG ulBFTime1;
  185. ULONG ulBFTime2;
  186. INT ipbfHeap; // index in heap
  187. UINT cDepend; // count of prior BF's to be flushed
  188. struct _bf *pbfDepend; // BF to be flushed after this one
  189. LGPOS lgposRC; // log ptr to BeginT of oldest modifying xact
  190. LGPOS lgposModify; // log ptr of entry for last page Modify
  191. #ifdef WIN16
  192. HANDLE hpage; // handle to the page buffer
  193. #endif
  194. // UINT fWaiting:1; // someone is waiting to reference page
  195. // INT wNumberPages; // number of contiguous pages to read
  196. } BF;
  197. #define pbfNil ((BF *) 0)
  198. ERR ErrBFAccessPage( PIB *ppib, BF **ppbf, PN pn );
  199. BF* PbfBFMostUsed( void );
  200. VOID BFAbandon( PIB *ppib, BF *pbf );
  201. ERR ErrBFAllocPageBuffer( PIB *ppib, BF **ppbf, PN pn, LGPOS lgposRC, BYTE pgtyp );
  202. ERR ErrBFAllocTempBuffer( BF **ppbf );
  203. VOID BFFree( BF *pbf );
  204. VOID BFReadAsync( PN pn, INT cpage );
  205. BF * PbfBFdMostUsed( void );
  206. VOID BFRemoveDependence( PIB *ppib, BF *pbf );
  207. /* buffer flush prototype and flags
  208. /**/
  209. #define fBFFlushSome 0
  210. #define fBFFlushAll 1
  211. ERR ErrBFFlushBuffers( DBID dbid, INT fBFFlush );
  212. #define BFSFree( pbf ) \
  213. { \
  214. SgSemRequest( semST ); \
  215. BFFree( pbf ); \
  216. SgSemRelease( semST ); \
  217. }
  218. #define FBFDirty( pbf ) ((pbf)->fDirty)
  219. /* the following small functions are called too often, */
  220. /* make it as a macros */
  221. #ifdef DEBUG
  222. VOID BFSetDirtyBit( BF *pbf );
  223. #else
  224. #define BFSetDirtyBit( pbf ) (pbf)->fDirty = fTrue
  225. #endif
  226. VOID BFDirty( BF *pbf );
  227. /* check if a page is dirty. If it is allocated for temp buffer, whose
  228. * pn must be Null, then no need to check if it is dirty since it will
  229. * not be written out.
  230. */
  231. #define AssertBFDirty( pbf ) \
  232. Assert( (pbf)->pn == pnNull || \
  233. (pbf) != pbfNil && (pbf)->fDirty == fTrue )
  234. #define AssertBFPin( pbf ) Assert( (pbf)->cPin > 0 )
  235. #define AssertBFWaitLatched( pbf, ppib ) \
  236. Assert( (pbf)->cWaitLatch > 0 \
  237. && (pbf)->cPin > 0 \
  238. && (pbf)->ppibWaitLatch == (ppib) );
  239. #define BFPin( pbf ) \
  240. { \
  241. EnterCriticalSection( (pbf)->critBF ); \
  242. Assert( (pbf) != pbfNil ); \
  243. Assert( !(pbf)->fWrite ); \
  244. Assert( !(pbf)->fRead ); \
  245. (pbf)->cPin++; \
  246. LeaveCriticalSection( (pbf)->critBF ); \
  247. }
  248. #define BFUnpin( pbf ) \
  249. { \
  250. EnterCriticalSection( (pbf)->critBF ); \
  251. Assert( (pbf) != pbfNil ); \
  252. Assert( !(pbf)->fWrite ); \
  253. Assert( !(pbf)->fRead ); \
  254. Assert( (pbf)->cPin > 0 ); \
  255. (pbf)->cPin--; \
  256. LeaveCriticalSection( (pbf)->critBF ); \
  257. }
  258. #define BFSetReadLatch( pbf, ppibT ) \
  259. { \
  260. Assert( (pbf)->cPin > 0 ); \
  261. Assert( (pbf)->cWriteLatch == 0 || \
  262. (pbf)->ppibWriteLatch == (ppibT) ); \
  263. (pbf)->cReadLatch++; \
  264. }
  265. #define BFResetReadLatch( pbf, ppibT ) \
  266. { \
  267. Assert( (pbf)->cPin > 0 ); \
  268. Assert( (pbf)->cReadLatch > 0 ); \
  269. Assert( (pbf)->cWriteLatch == 0 || \
  270. (pbf)->ppibWriteLatch == (ppibT) ); \
  271. (pbf)->cReadLatch--; \
  272. }
  273. #define FBFReadLatchConflict( ppibT, pbf ) \
  274. ( (pbf)->cWriteLatch > 0 && \
  275. (pbf)->ppibWriteLatch != (ppibT) )
  276. #define BFSetWriteLatch( pbf, ppibT ) \
  277. { \
  278. Assert( (pbf)->cPin > 0 ); \
  279. Assert( (pbf)->cReadLatch == 0 ); \
  280. Assert( (pbf)->cWriteLatch == 0 || \
  281. (pbf)->ppibWriteLatch == (ppibT) ); \
  282. (pbf)->cWriteLatch++; \
  283. (pbf)->ppibWriteLatch = (ppibT); \
  284. }
  285. #define BFResetWriteLatch( pbf, ppibT ) \
  286. { \
  287. Assert( (pbf)->cPin > 0 ); \
  288. Assert( (pbf)->cReadLatch == 0 ); \
  289. Assert( (pbf)->cWriteLatch > 0 ); \
  290. Assert( (pbf)->ppibWriteLatch == (ppibT) ); \
  291. if ( --(pbf)->cWriteLatch == 0 ) \
  292. { \
  293. (pbf)->ppibWriteLatch = ppibNil; \
  294. Assert( (pbf)->cWaitLatch == 0 ); \
  295. } \
  296. }
  297. #define FBFWriteLatch( ppibT, pbf ) \
  298. ((pbf)->cPin > 0 && \
  299. (pbf)->cWriteLatch > 0 && \
  300. (pbf)->ppibWriteLatch == (ppibT))
  301. #define FBFWriteLatchConflict( ppibT, pbf ) \
  302. ( (pbf)->cReadLatch > 0 || \
  303. ( (pbf)->cWriteLatch > 0 && \
  304. (pbf)->ppibWriteLatch != (ppibT) ) )
  305. #define BFSetWaitLatch( pbf, ppib ) \
  306. { \
  307. Assert( ( pbf )->cPin > 0 ); \
  308. Assert( ( pbf )->cWriteLatch > 0 ); \
  309. Assert( (pbf)->ppibWriteLatch == (ppib) ); \
  310. if ( pbf->cWaitLatch++ > 0 ) \
  311. Assert( (pbf)->ppibWaitLatch == (ppib) ); \
  312. (pbf)->ppibWaitLatch = ppib; \
  313. }
  314. #define BFResetWaitLatch( pbf, ppibT ) \
  315. { \
  316. Assert( (pbf)->cPin > 0 ); \
  317. Assert( ( pbf )->cWriteLatch > 0 ); \
  318. Assert( (pbf)->cWaitLatch > 0 ); \
  319. Assert( (pbf)->ppibWaitLatch == (ppibT) ); \
  320. if ( --(pbf)->cWaitLatch == 0 ) \
  321. { \
  322. (pbf)->ppibWaitLatch = ppibNil; \
  323. SignalSend( (pbf)->olp.sigIO ); \
  324. } \
  325. }
  326. ERR ErrBFDepend( BF *pbf, BF *pbfD );
  327. #define BFUndepend( pbf ) \
  328. { \
  329. if ( (pbf)->pbfDepend != pbfNil ) \
  330. { \
  331. BF *pbfD = (pbf)->pbfDepend; \
  332. Assert( pbfD->cDepend > 0 ); \
  333. EnterCriticalSection( pbfD->critBF ); \
  334. pbfD->cDepend--; \
  335. (pbf)->pbfDepend = pbfNil; \
  336. LeaveCriticalSection( pbfD->critBF ); \
  337. } \
  338. }
  339. //---- STORAGE (storage.c) -------------------------------------------------
  340. ERR ErrFMPSetDatabases( PIB *ppib );
  341. ERR ErrFMPInit( VOID );
  342. VOID FMPTerm( );
  343. ERR ErrSTSetIntrinsicConstants( VOID );
  344. ERR ErrSTInit( VOID );
  345. ERR ErrSTTerm( VOID );
  346. // Transaction support
  347. ERR ErrSTBeginTransaction( PIB *ppib );
  348. ERR ErrSTRollback( PIB *ppib );
  349. ERR ErrSTCommitTransaction( PIB *ppib );
  350. ERR ErrSTInitOpenSysDB();
  351. ERR ErrBFNewPage( FUCB *pfucb, PGNO pgno, PGTYP pgtyp, PGNO pgnoFDP );
  352. VOID BFSleep( unsigned long ulMSecs );
  353. // Modes for Storage System
  354. #define modeRead 0
  355. #define modeWrite 1
  356. #define modeRIW 2
  357. #define PnOfDbidPgno( dbid, pgno ) ( ( (LONG) (dbid) )<<24 | (pgno) )
  358. #define DbidOfPn( pn ) ( (DBID)( (pn)>>24 ) )
  359. #define PgnoOfPn( pn ) ( (pn) & 0x00ffffff )
  360. #define ErrSTReadAccessPage ErrSTAccessPage
  361. #define ErrSTWriteAccessPage ErrSTAccessPage
  362. #define FReadAccessPage FAccessPage
  363. #define FWriteAccessPage FAccessPage
  364. BOOL FBFAccessPage( FUCB *pfucb, PGNO pgno );
  365. #define FAccessPage( pfucb, pgno ) FBFAccessPage( pfucb, pgno )
  366. // UNDONE: this should be in SgSemRequest( semST )
  367. #define ErrSTAccessPage( pfucb, pgnoT ) \
  368. ( ErrBFAccessPage( pfucb->ppib, &(pfucb)->ssib.pbf, PnOfDbidPgno( (pfucb)->dbid, pgnoT ) ) )
  369.