Leaked source code of windows server 2003
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.

588 lines
19 KiB

  1. #ifndef _STACK_HPP_
  2. #define _STACK_HPP_
  3. // Ruler
  4. // 1 2 3 4 5 6 7 8
  5. //345678901234567890123456789012345678901234567890123456789012345678901234567890
  6. /********************************************************************/
  7. /* */
  8. /* The standard layout. */
  9. /* */
  10. /* The standard layout for 'hpp' files for this code is as */
  11. /* follows: */
  12. /* */
  13. /* 1. Include files. */
  14. /* 2. Constants exported from the class. */
  15. /* 3. Data structures exported from the class. */
  16. /* 4. Forward references to other data structures. */
  17. /* 5. Class specifications (including inline functions). */
  18. /* 6. Additional large inline functions. */
  19. /* */
  20. /* Any portion that is not required is simply omitted. */
  21. /* */
  22. /********************************************************************/
  23. #include "Global.hpp"
  24. #include "Lock.hpp"
  25. #include "Vector.hpp"
  26. /********************************************************************/
  27. /* */
  28. /* Constants exported from the class. */
  29. /* */
  30. /* The stack constants specify the initial size of the stack. */
  31. /* */
  32. /********************************************************************/
  33. CONST SBIT32 StackSize = 1024;
  34. /********************************************************************/
  35. /* */
  36. /* Stacks and stack management. */
  37. /* */
  38. /* This class provides general purpose stacks along with some */
  39. /* basic management. The stacks are optimized for very high */
  40. /* performance on SMP systems. Whenever possible multiple */
  41. /* items should added and removed from a stack at the same time. */
  42. /* */
  43. /********************************************************************/
  44. template <class TYPE,class LOCK=NO_LOCK> class STACK : public LOCK
  45. {
  46. //
  47. // Private data.
  48. //
  49. SBIT32 MaxSize;
  50. SBIT32 Top;
  51. VECTOR<TYPE> Stack;
  52. public:
  53. //
  54. // Public functions.
  55. //
  56. STACK( SBIT32 NewMaxSize = StackSize );
  57. BOOLEAN MultiplePopStack
  58. (
  59. SBIT32 Requested,
  60. TYPE Data[],
  61. SBIT32 *Size
  62. );
  63. BOOLEAN MultiplePopStackReversed
  64. (
  65. SBIT32 Requested,
  66. TYPE Data[],
  67. SBIT32 *Size
  68. );
  69. VOID MultiplePushStack
  70. (
  71. CONST TYPE Data[],
  72. CONST SBIT32 Size
  73. );
  74. VOID MultiplePushStackReversed
  75. (
  76. CONST TYPE Data[],
  77. CONST SBIT32 Size
  78. );
  79. BOOLEAN PeekStack( TYPE *Data );
  80. BOOLEAN PopStack( TYPE *Data );
  81. VOID PushStack( CONST TYPE & Data );
  82. BOOLEAN ReadStack( SBIT32 Index, TYPE *Data );
  83. VOID ReverseStack( VOID );
  84. BOOLEAN UpdateStack
  85. (
  86. CONST SBIT32 Index,
  87. CONST TYPE & Data
  88. );
  89. ~STACK( VOID );
  90. //
  91. // Public inline functions.
  92. //
  93. INLINE SBIT32 SizeOfStack( VOID )
  94. { return Top; }
  95. private:
  96. //
  97. // Disabled operations.
  98. //
  99. STACK( CONST STACK & Copy );
  100. VOID operator=( CONST STACK & Copy );
  101. };
  102. /********************************************************************/
  103. /* */
  104. /* Class constructor. */
  105. /* */
  106. /* Create a new stack and prepare it for use. This call is */
  107. /* not thread safe and should only be made in a single thread */
  108. /* environment. */
  109. /* */
  110. /********************************************************************/
  111. template <class TYPE,class LOCK> STACK<TYPE,LOCK>::STACK( SBIT32 NewMaxSize ) :
  112. //
  113. // Call the constructors for the contained classes.
  114. //
  115. Stack( NewMaxSize,1,CacheLineSize )
  116. {
  117. #ifdef DEBUGGING
  118. if ( NewMaxSize > 0 )
  119. {
  120. #endif
  121. MaxSize = NewMaxSize;
  122. Top = 0;
  123. #ifdef DEBUGGING
  124. }
  125. else
  126. { Failure( "Size in constructor for STACK" ); }
  127. #endif
  128. }
  129. /********************************************************************/
  130. /* */
  131. /* Remove multiple items from a stack. */
  132. /* */
  133. /* We remove multiple items from a stack and check to make sure */
  134. /* that the stack is not empty. */
  135. /* */
  136. /********************************************************************/
  137. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::MultiplePopStack
  138. (
  139. SBIT32 Requested,
  140. TYPE Data[],
  141. SBIT32 *Size
  142. )
  143. {
  144. REGISTER BOOLEAN Result;
  145. //
  146. // Claim an exclisive lock (if enabled).
  147. //
  148. ClaimExclusiveLock();
  149. //
  150. // If the stack is not empty return the
  151. // top elements.
  152. if ( Top > 0 )
  153. {
  154. REGISTER SBIT32 Count;
  155. (*Size) = (Top >= Requested) ? Requested : Top;
  156. for ( Count = ((*Size) - 1);Count >= 0;Count -- )
  157. { Data[ Count ] = Stack[ -- Top ]; }
  158. Result = True;
  159. }
  160. else
  161. { Result = False; }
  162. //
  163. // Release any lock we claimed earlier.
  164. //
  165. ReleaseExclusiveLock();
  166. return Result;
  167. }
  168. /********************************************************************/
  169. /* */
  170. /* Remove multiple items from a stack in reverse order. */
  171. /* */
  172. /* We remove multiple items from a stack in reverse order and */
  173. /* check to make sure that the stack is not empty. */
  174. /* */
  175. /********************************************************************/
  176. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::MultiplePopStackReversed
  177. (
  178. SBIT32 Requested,
  179. TYPE Data[],
  180. SBIT32 *Size
  181. )
  182. {
  183. REGISTER BOOLEAN Result;
  184. //
  185. // Claim an exclisive lock (if enabled).
  186. //
  187. ClaimExclusiveLock();
  188. //
  189. // If the stack is not empty return the
  190. // top elements.
  191. if ( Top > 0 )
  192. {
  193. REGISTER SBIT32 Count;
  194. (*Size) = (Top >= Requested) ? Requested : Top;
  195. for ( Count = 0;Count < (*Size);Count ++ )
  196. { Data[ Count ] = Stack[ -- Top ]; }
  197. Result = True;
  198. }
  199. else
  200. { Result = False; }
  201. //
  202. // Release any lock we claimed earlier.
  203. //
  204. ReleaseExclusiveLock();
  205. return Result;
  206. }
  207. /********************************************************************/
  208. /* */
  209. /* Add multiple items to a stack. */
  210. /* */
  211. /* We add multiple items to a stack and check to make sure that */
  212. /* the stack has not overflowed. If the stack has overflowed */
  213. /* we double its size. */
  214. /* */
  215. /********************************************************************/
  216. template <class TYPE,class LOCK> VOID STACK<TYPE,LOCK>::MultiplePushStack
  217. (
  218. CONST TYPE Data[],
  219. CONST SBIT32 Size
  220. )
  221. {
  222. REGISTER SBIT32 Count;
  223. //
  224. // Claim an exclisive lock (if enabled).
  225. //
  226. ClaimExclusiveLock();
  227. //
  228. // If the stack will overflow then expand it.
  229. //
  230. while ( (Top + Size) >= MaxSize )
  231. { Stack.Resize( (MaxSize *= ExpandStore) ); }
  232. //
  233. // Push the new elements.
  234. //
  235. for ( Count = 0;Count < Size;Count ++ )
  236. { Stack[ Top ++ ] = Data[ Count ]; }
  237. //
  238. // Release any lock we claimed earlier.
  239. //
  240. ReleaseExclusiveLock();
  241. }
  242. /********************************************************************/
  243. /* */
  244. /* Add multiple items to a stack in reverse order. */
  245. /* */
  246. /* We add multiple items to a stack in reverse order and check */
  247. /* to make sure that the stack has not overflowed. If the stack */
  248. /* has overflowed we double its size. */
  249. /* */
  250. /********************************************************************/
  251. template <class TYPE,class LOCK> VOID STACK<TYPE,LOCK>::MultiplePushStackReversed
  252. (
  253. CONST TYPE Data[],
  254. CONST SBIT32 Size
  255. )
  256. {
  257. REGISTER SBIT32 Count;
  258. //
  259. // Claim an exclisive lock (if enabled).
  260. //
  261. ClaimExclusiveLock();
  262. //
  263. // If the stack will overflow then expand it.
  264. //
  265. while ( (Top + Size) >= MaxSize )
  266. { Stack.Resize( (MaxSize *= ExpandStore) ); }
  267. //
  268. // Push the new elements in reverse order.
  269. //
  270. for ( Count = (Size-1);Count >= 0;Count -- )
  271. { Stack[ Top ++ ] = Data[ Count ]; }
  272. //
  273. // Release any lock we claimed earlier.
  274. //
  275. ReleaseExclusiveLock();
  276. }
  277. /********************************************************************/
  278. /* */
  279. /* Peek at the top of stack. */
  280. /* */
  281. /* We return the top of stack with a pop but check to make sure */
  282. /* that the stack is not empty. */
  283. /* */
  284. /********************************************************************/
  285. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::PeekStack
  286. (
  287. TYPE *Data
  288. )
  289. {
  290. REGISTER BOOLEAN Result;
  291. //
  292. // Claim an shared lock (if enabled).
  293. //
  294. ClaimSharedLock();
  295. //
  296. // If the stack is not empty return a copy
  297. // of the top element.
  298. //
  299. if ( Top > 0 )
  300. {
  301. (*Data) = Stack[ (Top - 1) ];
  302. Result = True;
  303. }
  304. else
  305. { Result = False; }
  306. //
  307. // Release any lock we claimed earlier.
  308. //
  309. ReleaseSharedLock();
  310. return Result;
  311. }
  312. /********************************************************************/
  313. /* */
  314. /* Remove a single item from a stack. */
  315. /* */
  316. /* We remove a single item from a stack and check to make sure */
  317. /* that the stack is not empty. */
  318. /* */
  319. /********************************************************************/
  320. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::PopStack
  321. (
  322. TYPE *Data
  323. )
  324. {
  325. REGISTER BOOLEAN Result;
  326. //
  327. // Claim an exclisive lock (if enabled).
  328. //
  329. ClaimExclusiveLock();
  330. //
  331. // If the stack is not empty return the
  332. // top element.
  333. //
  334. if ( Top > 0 )
  335. {
  336. (*Data) = Stack[ -- Top ];
  337. Result = True;
  338. }
  339. else
  340. { Result = False; }
  341. //
  342. // Release any lock we claimed earlier.
  343. //
  344. ReleaseExclusiveLock();
  345. return Result;
  346. }
  347. /********************************************************************/
  348. /* */
  349. /* Add a single item to a stack. */
  350. /* */
  351. /* We add a single item to a stack and check to make sure that */
  352. /* the stack has not overflowed. If the stack has overflowed */
  353. /* we double its size. */
  354. /* */
  355. /********************************************************************/
  356. template <class TYPE,class LOCK> VOID STACK<TYPE,LOCK>::PushStack
  357. (
  358. CONST TYPE & Data
  359. )
  360. {
  361. //
  362. // Claim an exclisive lock (if enabled).
  363. //
  364. ClaimExclusiveLock();
  365. //
  366. // If the stack is full then expand it.
  367. //
  368. while ( Top >= MaxSize )
  369. { Stack.Resize( (MaxSize *= ExpandStore) ); }
  370. //
  371. // Push a new element.
  372. //
  373. Stack[ Top ++ ] = Data;
  374. //
  375. // Release any lock we claimed earlier.
  376. //
  377. ReleaseExclusiveLock();
  378. }
  379. /********************************************************************/
  380. /* */
  381. /* Read a stack value. */
  382. /* */
  383. /* We return a single item from the stack but check to make */
  384. /* sure that it exists. . */
  385. /* */
  386. /********************************************************************/
  387. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::ReadStack
  388. (
  389. SBIT32 Index,
  390. TYPE *Data
  391. )
  392. {
  393. REGISTER BOOLEAN Result;
  394. //
  395. // Claim an shared lock (if enabled).
  396. //
  397. ClaimSharedLock();
  398. //
  399. // If the element exists then return a copy of
  400. // it to the caller.
  401. //
  402. if ( Index < Top )
  403. {
  404. (*Data) = Stack[ Index ];
  405. Result = True;
  406. }
  407. else
  408. { Result = False; }
  409. //
  410. // Release any lock we claimed earlier.
  411. //
  412. ReleaseSharedLock();
  413. return Result;
  414. }
  415. /********************************************************************/
  416. /* */
  417. /* Reverse the stack. */
  418. /* */
  419. /* We reverse the order of the stack to make effectively */
  420. /* make it a queue. . */
  421. /* */
  422. /********************************************************************/
  423. template <class TYPE,class LOCK> VOID STACK<TYPE,LOCK>::ReverseStack( VOID )
  424. {
  425. REGISTER SBIT32 Count;
  426. REGISTER SBIT32 MidPoint = (Top / 2);
  427. //
  428. // Claim an exclusive lock (if enabled).
  429. //
  430. ClaimExclusiveLock();
  431. //
  432. // Swap all elements around the mid point.
  433. //
  434. for ( Count=0;Count < MidPoint;Count ++ )
  435. {
  436. REGISTER TYPE *Low = & Stack[ Count ];
  437. REGISTER TYPE *High = & Stack[ (Top - Count - 1) ];
  438. REGISTER TYPE Temp = (*Low);
  439. (*Low) = (*High);
  440. (*High) = Temp;
  441. }
  442. //
  443. // Release any lock we claimed earlier.
  444. //
  445. ReleaseExclusiveLock();
  446. }
  447. /********************************************************************/
  448. /* */
  449. /* Update a stack value. */
  450. /* */
  451. /* We update a single item on the stack but check to make */
  452. /* sure that it exists. . */
  453. /* */
  454. /********************************************************************/
  455. template <class TYPE,class LOCK> BOOLEAN STACK<TYPE,LOCK>::UpdateStack
  456. (
  457. CONST SBIT32 Index,
  458. CONST TYPE & Data
  459. )
  460. {
  461. REGISTER BOOLEAN Result;
  462. //
  463. // Claim an exclisive lock (if enabled).
  464. //
  465. ClaimExclusiveLock();
  466. //
  467. // If the element exists then update it.
  468. //
  469. if ( Index < Top )
  470. {
  471. Stack[ Index ] = Data;
  472. Result = True;
  473. }
  474. else
  475. { Result = False; }
  476. //
  477. // Release any lock we claimed earlier.
  478. //
  479. ReleaseExclusiveLock();
  480. return Result;
  481. }
  482. /********************************************************************/
  483. /* */
  484. /* Class destructor. */
  485. /* */
  486. /* Destory the stack. This call is not thread safe and should */
  487. /* only be made in a single thread environment. */
  488. /* */
  489. /********************************************************************/
  490. template <class TYPE,class LOCK> STACK<TYPE,LOCK>::~STACK( VOID )
  491. { /* void */ }
  492. #endif