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.

955 lines
30 KiB

  1. #ifndef _QUEUE_HPP_
  2. #define _QUEUE_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 "Common.hpp"
  25. #include "Lock.hpp"
  26. #include "Vector.hpp"
  27. /********************************************************************/
  28. /* */
  29. /* Constants exported from the class. */
  30. /* */
  31. /* The queue constants specify the initial size of the queue. */
  32. /* */
  33. /********************************************************************/
  34. CONST SBIT32 QueueSize = 1024;
  35. /********************************************************************/
  36. /* */
  37. /* Queues and queue management. */
  38. /* */
  39. /* This class provides general purpose queues along with some */
  40. /* basic management. The queues are optimized for very high */
  41. /* performance on SMP systems. Whenever possible multiple */
  42. /* items should added and removed from a queue at the same time. */
  43. /* */
  44. /********************************************************************/
  45. template <class TYPE,class LOCK=NO_LOCK> class QUEUE : public COMMON, public LOCK
  46. {
  47. //
  48. // Private data.
  49. //
  50. SBIT32 MaxSize;
  51. BOOLEAN Align;
  52. SBIT32 Mask;
  53. SBIT32 Back;
  54. SBIT32 Front;
  55. VECTOR<TYPE> Queue;
  56. public:
  57. //
  58. // Public functions.
  59. //
  60. QUEUE( SBIT32 NewMaxSize = QueueSize,BOOLEAN NewAlign = True );
  61. BOOLEAN MultiplePopBackOfQueue
  62. (
  63. SBIT32 Requested,
  64. TYPE Data[],
  65. SBIT32 *Size
  66. );
  67. BOOLEAN MultiplePopFrontOfQueue
  68. (
  69. SBIT32 Requested,
  70. TYPE Data[],
  71. SBIT32 *Size
  72. );
  73. VOID MultiplePushBackOfQueue
  74. (
  75. CONST TYPE Data[],
  76. CONST SBIT32 Size
  77. );
  78. VOID MultiplePushFrontOfQueue
  79. (
  80. CONST TYPE Data[],
  81. CONST SBIT32 Size
  82. );
  83. BOOLEAN PeekBackOfQueue( TYPE *Data );
  84. BOOLEAN PeekFrontOfQueue( TYPE *Data );
  85. BOOLEAN PopBackOfQueue( TYPE *Data );
  86. BOOLEAN PopFrontOfQueue( TYPE *Data );
  87. VOID PushBackOfQueue( CONST TYPE & Data );
  88. VOID PushFrontOfQueue( CONST TYPE & Data );
  89. SBIT32 SizeOfQueue( VOID );
  90. ~QUEUE( VOID );
  91. //
  92. // Public inline functions.
  93. //
  94. INLINE BOOLEAN MultiplePopQueue
  95. (
  96. SBIT32 Requested,
  97. TYPE Data[],
  98. SBIT32 *Size
  99. )
  100. { return MultiplePopFrontOfQueue( Requested,Data,Size ); }
  101. INLINE VOID MultiplePushQueue
  102. (
  103. CONST TYPE Data[],
  104. CONST SBIT32 Size
  105. )
  106. { MultiplePushBackOfQueue( Data,Size ); }
  107. INLINE BOOLEAN PeekQueue( TYPE *Data )
  108. { return PeekFrontOfQueue( Data ); }
  109. INLINE BOOLEAN PopQueue( TYPE *Data )
  110. { return PopFrontOfQueue( Data ); }
  111. INLINE VOID PushQueue( CONST TYPE & Data )
  112. { PushBackOfQueue( Data ); }
  113. private:
  114. //
  115. // Private functions.
  116. //
  117. VOID ExpandQueue( VOID );
  118. //
  119. // Disabled operations.
  120. //
  121. QUEUE( CONST QUEUE & Copy );
  122. VOID operator=( CONST QUEUE & Copy );
  123. };
  124. /********************************************************************/
  125. /* */
  126. /* Class constructor. */
  127. /* */
  128. /* Create a new queue and prepare it for use. This call is */
  129. /* not thread safe and should only be made in a single thread */
  130. /* environment. */
  131. /* */
  132. /********************************************************************/
  133. template <class TYPE,class LOCK> QUEUE<TYPE,LOCK>::QUEUE
  134. (
  135. SBIT32 NewMaxSize,
  136. BOOLEAN NewAlign
  137. ) :
  138. //
  139. // Call the constructors for the contained classes.
  140. //
  141. Queue( NewMaxSize,1,CacheLineSize )
  142. {
  143. #ifdef DEBUGGING
  144. if ( NewMaxSize > 0 )
  145. {
  146. #endif
  147. //
  148. // Setup the control information.
  149. //
  150. MaxSize = NewMaxSize;
  151. Align = NewAlign;
  152. Mask = 0x7fffffff;
  153. //
  154. // Setup the queue so it is empty.
  155. //
  156. Back = 0;
  157. Front = 0;
  158. //
  159. // Compute the alignment mask.
  160. //
  161. if
  162. (
  163. ((sizeof(TYPE) > 0) && (sizeof(TYPE) <= CacheLineSize))
  164. &&
  165. (PowerOfTwo( sizeof(TYPE) ))
  166. )
  167. { Mask = ((CacheLineSize / sizeof(TYPE))-1); }
  168. #ifdef DEBUGGING
  169. }
  170. else
  171. { Failure( "Size in constructor for QUEUE" ); }
  172. #endif
  173. }
  174. /********************************************************************/
  175. /* */
  176. /* Expand a queue. */
  177. /* */
  178. /* When a queue becomes full we need to expand it and to copy */
  179. /* the tail end of the queue into the correct place. */
  180. /* */
  181. /********************************************************************/
  182. template <class TYPE,class LOCK> VOID QUEUE<TYPE,LOCK>::ExpandQueue( VOID )
  183. {
  184. REGISTER SBIT32 Count;
  185. REGISTER SBIT32 NewSize = (MaxSize * ExpandStore);
  186. //
  187. // Expand the queue (it will be at least doubled).
  188. //
  189. Queue.Resize( NewSize );
  190. //
  191. // Copy the tail end of the queue to the correct
  192. // place in the expanded queue.
  193. //
  194. for ( Count = 0;Count < Back;Count ++ )
  195. { Queue[ (MaxSize + Count) ] = Queue[ Count ]; }
  196. //
  197. // Update the control information.
  198. //
  199. Back += MaxSize;
  200. MaxSize = NewSize;
  201. }
  202. /********************************************************************/
  203. /* */
  204. /* Pop multiple items from the back of the queue. */
  205. /* */
  206. /* We remove multiple items from a queue and check to make sure */
  207. /* that the queue has not wrapped. */
  208. /* */
  209. /********************************************************************/
  210. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::MultiplePopBackOfQueue
  211. (
  212. SBIT32 Requested,
  213. TYPE Data[],
  214. SBIT32 *Size
  215. )
  216. {
  217. REGISTER BOOLEAN Result;
  218. //
  219. // Claim an exclusive lock (if enabled).
  220. //
  221. ClaimExclusiveLock();
  222. //
  223. // When running on SMP hardware it is very important
  224. // to prevent multiple CPU fighting over the same memory.
  225. // Most systems prevent multiple CPUs accessing a cache
  226. // line at the same time. Here we modify the request
  227. // to pop exactly the correct number of items to leave
  228. // us on a cache line boundary.
  229. //
  230. if ( Align )
  231. {
  232. REGISTER SBIT32 Spare = (Back & Mask);
  233. if ( Requested > Spare )
  234. {
  235. Requested -= Spare;
  236. Requested &= ~Mask;
  237. Requested += Spare;
  238. }
  239. }
  240. //
  241. // If there is enough elements in the current queue
  242. // to extract without wrapping then just do a straight
  243. // copy.
  244. //
  245. if
  246. (
  247. ((Front <= Back) && (Front <= (Back - Requested)))
  248. ||
  249. ((Front > Back) && ((Back - Requested) >= 0))
  250. )
  251. {
  252. REGISTER SBIT32 Count;
  253. //
  254. // We have verified that it is safe to remove all
  255. // the requested elements with a straight copy.
  256. //
  257. for ( Count = 0;Count < Requested;Count ++ )
  258. { Data[ Count ] = Queue[ -- Back ]; }
  259. (*Size) = Requested;
  260. Result = True;
  261. }
  262. else
  263. {
  264. REGISTER SBIT32 Count;
  265. //
  266. // It is not safe to remove all the elements from
  267. // the array. Hence, I must remove them one at a
  268. // time. This is tedious but should only happen
  269. // occasionally.
  270. //
  271. for ( Count=0,(*Size)=0;Count < Requested;Count ++,(*Size) ++ )
  272. {
  273. if ( Front != Back )
  274. {
  275. //
  276. // We have found an element so return it
  277. // to the caller. However, lets we need
  278. // to be careful about wrapping.
  279. //
  280. if ( Back <= 0 )
  281. { Back = MaxSize; }
  282. Data[ Count ] = Queue[ -- Back ];
  283. }
  284. else
  285. {
  286. //
  287. // We are out of queue elements so lets exit.
  288. // However, we only return 'False' if we didn't
  289. // find any elements at all.
  290. //
  291. Result = (Count != 0);
  292. break;
  293. }
  294. }
  295. }
  296. //
  297. // Release any lock we claimed earlier.
  298. //
  299. ReleaseExclusiveLock();
  300. return Result;
  301. }
  302. /********************************************************************/
  303. /* */
  304. /* Pop multiple items from the front of the queue. */
  305. /* */
  306. /* We remove multiple items from a queue and check to make sure */
  307. /* that the queue has not wrapped. */
  308. /* */
  309. /********************************************************************/
  310. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::MultiplePopFrontOfQueue
  311. (
  312. SBIT32 Requested,
  313. TYPE Data[],
  314. SBIT32 *Size
  315. )
  316. {
  317. REGISTER BOOLEAN Result;
  318. //
  319. // Claim an exclusive lock (if enabled).
  320. //
  321. ClaimExclusiveLock();
  322. //
  323. // When running on SMP hardware it is very important
  324. // to prevent multiple CPU fighting over the same memory.
  325. // Most systems prevent multiple CPUs accessing cache
  326. // lines at the same time. Here we modify the request
  327. // to access exactly the correct number of items to leave
  328. // us on a cache line boundary.
  329. //
  330. if ( Align )
  331. {
  332. REGISTER SBIT32 Spare = ((Mask + 1) - (Front & Mask));
  333. if ( Requested > Spare )
  334. {
  335. Requested -= Spare;
  336. Requested &= ~Mask;
  337. Requested += Spare;
  338. }
  339. }
  340. //
  341. // If there is enough elements in the current queue
  342. // to extract without wrapping then just do a straight
  343. // copy.
  344. //
  345. if
  346. (
  347. ((Front <= Back) && ((Front + Requested) <= Back))
  348. ||
  349. ((Front > Back) && ((Front + Requested) < MaxSize))
  350. )
  351. {
  352. REGISTER SBIT32 Count;
  353. //
  354. // We have verified that it is safe to remove all
  355. // the requested elements with a straight copy.
  356. //
  357. for ( Count = 0;Count < Requested;Count ++ )
  358. { Data[ Count ] = Queue[ Front ++ ]; }
  359. (*Size) = Requested;
  360. Result = True;
  361. }
  362. else
  363. {
  364. REGISTER SBIT32 Count;
  365. //
  366. // It is not safe to remove all the elements from
  367. // the array. Hence, I must remove them one at a
  368. // time. This is tedious but should only happen
  369. // occasionally.
  370. //
  371. for ( Count=0,(*Size)=0;Count < Requested;Count ++,(*Size) ++ )
  372. {
  373. if ( Front != Back )
  374. {
  375. //
  376. // We have found an element so return it
  377. // to the caller. However, lets we need
  378. // to be careful about wrapping.
  379. //
  380. Data[ Count ] = Queue[ Front ++ ];
  381. if ( Front >= MaxSize )
  382. { Front = 0; }
  383. }
  384. else
  385. {
  386. //
  387. // We are out of queue elements so lets exit.
  388. // However, we only return 'False' if we didn't
  389. // find any elements at all.
  390. //
  391. Result = (Count != 0);
  392. break;
  393. }
  394. }
  395. }
  396. //
  397. // Release any lock we claimed earlier.
  398. //
  399. ReleaseExclusiveLock();
  400. return Result;
  401. }
  402. /********************************************************************/
  403. /* */
  404. /* Push multiple items onto the back of the queue. */
  405. /* */
  406. /* We add multiple items to a queue and check to make sure that */
  407. /* the queue has not overflowed. If the queue has overflowed */
  408. /* we double its size. */
  409. /* */
  410. /********************************************************************/
  411. template <class TYPE,class LOCK> VOID QUEUE<TYPE,LOCK>::MultiplePushBackOfQueue
  412. (
  413. CONST TYPE Data[],
  414. CONST SBIT32 Size
  415. )
  416. {
  417. //
  418. // Claim an exclusive lock (if enabled).
  419. //
  420. ClaimExclusiveLock();
  421. //
  422. // If there is enough space in the current queue
  423. // for the new elements without wrapping then
  424. // just do a straight copy.
  425. //
  426. if
  427. (
  428. ((Front <= Back) && ((Back + Size) < MaxSize))
  429. ||
  430. ((Front > Back) && (Front > (Back + Size)))
  431. )
  432. {
  433. REGISTER SBIT32 Count;
  434. //
  435. // We have verified that it is safe to copy
  436. // all the new elements on to the end of the
  437. // array. So lets do it and then we can exit.
  438. //
  439. for ( Count = 0;Count < Size;Count ++ )
  440. { Queue[ Back ++ ] = Data[ Count ]; }
  441. }
  442. else
  443. {
  444. REGISTER SBIT32 Count;
  445. //
  446. // It is not safe to add the new elements to
  447. // the end of the array so add them one at a
  448. // time. This is tedious but should only happen
  449. // occasionally.
  450. //
  451. for ( Count=0;Count < Size;Count ++ )
  452. {
  453. //
  454. // Add element to the queue. If necessary
  455. // wrap round to the front of the array.
  456. //
  457. Queue[ Back ++ ] = Data[ Count ];
  458. if ( Back >= MaxSize )
  459. { Back = 0; }
  460. //
  461. // Verify that the queue is not full. If
  462. // it is full then double its size and
  463. // copy wrapped data to the correct position
  464. // in the new array.
  465. //
  466. if ( Front == Back )
  467. { ExpandQueue(); }
  468. }
  469. }
  470. //
  471. // Release any lock we claimed earlier.
  472. //
  473. ReleaseExclusiveLock();
  474. }
  475. /********************************************************************/
  476. /* */
  477. /* Push multiple items onto the front of the queue. */
  478. /* */
  479. /* We add multiple items to a queue and check to make sure that */
  480. /* the queue has not overflowed. If the queue has overflowed */
  481. /* we double its size. */
  482. /* */
  483. /********************************************************************/
  484. template <class TYPE,class LOCK> VOID QUEUE<TYPE,LOCK>::MultiplePushFrontOfQueue
  485. (
  486. CONST TYPE Data[],
  487. CONST SBIT32 Size
  488. )
  489. {
  490. //
  491. // Claim an exclusive lock (if enabled).
  492. //
  493. ClaimExclusiveLock();
  494. //
  495. // If there is enough space in the current queue
  496. // for the new elements without wrapping then
  497. // just do a straight copy.
  498. //
  499. if
  500. (
  501. ((Front <= Back) && ((Front - Size) >= 0))
  502. ||
  503. ((Front > Back) && ((Front - Size) > Back))
  504. )
  505. {
  506. REGISTER SBIT32 Count;
  507. //
  508. // We have verified that it is safe to copy
  509. // all the new elements on to the end of the
  510. // array. So lets do it and then we can exit.
  511. //
  512. for ( Count = 0;Count < Size;Count ++ )
  513. { Queue[ -- Front ] = Data[ Count ]; }
  514. }
  515. else
  516. {
  517. REGISTER SBIT32 Count;
  518. //
  519. // It is not safe to add the new elements to
  520. // the end of the array so add them one at a
  521. // time. This is tedious but should only happen
  522. // occasionally.
  523. //
  524. for ( Count = 0;Count < Size;Count ++ )
  525. {
  526. //
  527. // Add element to the queue. If necessary
  528. // wrap round to the back of the array.
  529. //
  530. if ( Front <= 0 )
  531. { Front = MaxSize; }
  532. Queue[ -- Front ] = Data[ Count ];
  533. //
  534. // Verify that the queue is not full. If
  535. // it is full then double its size and
  536. // copy wrapped data to the correct position
  537. // in the new array.
  538. //
  539. if ( Front == Back )
  540. { ExpandQueue(); }
  541. }
  542. }
  543. //
  544. // Release any lock we claimed earlier.
  545. //
  546. ReleaseExclusiveLock();
  547. }
  548. /********************************************************************/
  549. /* */
  550. /* Peek the back of the queue. */
  551. /* */
  552. /* We return the end of the queue but check to make sure */
  553. /* that the queue is not empty. */
  554. /* */
  555. /********************************************************************/
  556. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::PeekBackOfQueue
  557. (
  558. TYPE *Data
  559. )
  560. {
  561. REGISTER BOOLEAN Result;
  562. //
  563. // Claim an exclusive lock (if enabled).
  564. //
  565. ClaimExclusiveLock();
  566. //
  567. // If the queue contains at least one element then
  568. // return a copy of the last element.
  569. //
  570. if ( Front != Back )
  571. {
  572. //
  573. // The 'Back' index points at the next free cell.
  574. // So the last element is 'Back - 1'. However,
  575. // when 'Back' is zero we need to wrap.
  576. //
  577. if ( Back > 0 )
  578. { (*Data) = Queue[ (Back - 1) ]; }
  579. else
  580. { (*Data) = Queue[ (MaxSize - 1) ]; }
  581. Result = True;
  582. }
  583. else
  584. { Result = False; }
  585. //
  586. // Release any lock we claimed earlier.
  587. //
  588. ReleaseExclusiveLock();
  589. return Result;
  590. }
  591. /********************************************************************/
  592. /* */
  593. /* Peek the front of the queue. */
  594. /* */
  595. /* We return the front of the queue but check to make sure */
  596. /* that the queue is not empty. */
  597. /* */
  598. /********************************************************************/
  599. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::PeekFrontOfQueue
  600. (
  601. TYPE *Data
  602. )
  603. {
  604. REGISTER BOOLEAN Result;
  605. //
  606. // Claim an exclusive lock (if enabled).
  607. //
  608. ClaimExclusiveLock();
  609. //
  610. // If the queue contains at least one element then
  611. // return a copy of the first element.
  612. //
  613. if ( Front != Back )
  614. {
  615. (*Data) = Queue[ Front ];
  616. Result = True;
  617. }
  618. else
  619. { Result = False; }
  620. //
  621. // Release any lock we claimed earlier.
  622. //
  623. ReleaseExclusiveLock();
  624. return Result;
  625. }
  626. /********************************************************************/
  627. /* */
  628. /* Pop an item from the back of the queue. */
  629. /* */
  630. /* We remove a single item from a queue and check to make sure */
  631. /* that the queue has not wrapped. */
  632. /* */
  633. /********************************************************************/
  634. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::PopBackOfQueue
  635. (
  636. TYPE *Data
  637. )
  638. {
  639. REGISTER BOOLEAN Result;
  640. //
  641. // Claim an exclusive lock (if enabled).
  642. //
  643. ClaimExclusiveLock();
  644. //
  645. // We make sure the queue is not empty.
  646. //
  647. if ( Front != Back )
  648. {
  649. //
  650. // We have found an element so return it to
  651. // the caller. If we walk off the end of the
  652. // queue then wrap to the other end.
  653. //
  654. if ( Back <= 0 )
  655. { Back = MaxSize; }
  656. (*Data) = Queue[ -- Back ];
  657. Result = True;
  658. }
  659. else
  660. { Result = False; }
  661. //
  662. // Release any lock we claimed earlier.
  663. //
  664. ReleaseExclusiveLock();
  665. return Result;
  666. }
  667. /********************************************************************/
  668. /* */
  669. /* Pop an item from the front of the queue. */
  670. /* */
  671. /* We remove a single item from a queue and check to make sure */
  672. /* that the queue has not wrapped. */
  673. /* */
  674. /********************************************************************/
  675. template <class TYPE,class LOCK> BOOLEAN QUEUE<TYPE,LOCK>::PopFrontOfQueue
  676. (
  677. TYPE *Data
  678. )
  679. {
  680. REGISTER BOOLEAN Result;
  681. //
  682. // Claim an exclusive lock (if enabled).
  683. //
  684. ClaimExclusiveLock();
  685. //
  686. // We make sure the queue is not empty.
  687. //
  688. if ( Front != Back )
  689. {
  690. //
  691. // We have found an element so return it to
  692. // the caller. If we walk off the end of the
  693. // queue then wrap to the other end.
  694. //
  695. (*Data) = Queue[ Front ++ ];
  696. if ( Front >= MaxSize )
  697. { Front = 0; }
  698. Result = True;
  699. }
  700. else
  701. { Result = False; }
  702. //
  703. // Release any lock we claimed earlier.
  704. //
  705. ReleaseExclusiveLock();
  706. return Result;
  707. }
  708. /********************************************************************/
  709. /* */
  710. /* Push an item onto the back of the queue. */
  711. /* */
  712. /* We add a single item to a queue and check to make sure that */
  713. /* the queue has not overflowed. If the queue has overflowed */
  714. /* we double its size. */
  715. /* */
  716. /********************************************************************/
  717. template <class TYPE,class LOCK> VOID QUEUE<TYPE,LOCK>::PushBackOfQueue
  718. (
  719. CONST TYPE & Data
  720. )
  721. {
  722. //
  723. // Claim an exclisive lock (if enabled).
  724. //
  725. ClaimExclusiveLock();
  726. //
  727. // Add element to the queue. If necessary wrap round
  728. // to the front of the array.
  729. //
  730. Queue[ Back ++ ] = Data;
  731. if ( Back >= MaxSize )
  732. { Back = 0; }
  733. //
  734. // Verify that the queue is not full. If it is full then
  735. // double its size and copy wrapped data to the correct
  736. // position in the new array.
  737. //
  738. if ( Front == Back )
  739. { ExpandQueue(); }
  740. //
  741. // Release any lock we claimed earlier.
  742. //
  743. ReleaseExclusiveLock();
  744. }
  745. /********************************************************************/
  746. /* */
  747. /* Push an item onto the front of the queue. */
  748. /* */
  749. /* We add a single item to a queue and check to make sure that */
  750. /* the queue has not overflowed. If the queue has overflowed */
  751. /* we double its size. */
  752. /* */
  753. /********************************************************************/
  754. template <class TYPE,class LOCK> VOID QUEUE<TYPE,LOCK>::PushFrontOfQueue
  755. (
  756. CONST TYPE & Data
  757. )
  758. {
  759. //
  760. // Claim an exclisive lock (if enabled).
  761. //
  762. ClaimExclusiveLock();
  763. //
  764. // Add element to the queue. If necessary wrap round
  765. // to the back of the array.
  766. //
  767. if ( Front <= 0 )
  768. { Front = MaxSize; }
  769. Queue[ -- Front ] = Data;
  770. //
  771. // Verify that the queue is not full. If it is full then
  772. // double its size and copy wrapped data to the correct
  773. // position in the new array.
  774. //
  775. if ( Front == Back )
  776. { ExpandQueue(); }
  777. //
  778. // Release any lock we claimed earlier.
  779. //
  780. ReleaseExclusiveLock();
  781. }
  782. /********************************************************************/
  783. /* */
  784. /* Calculate the size of the queue. */
  785. /* */
  786. /* Calculate the size of the queue and return it to the caller. */
  787. /* This is only used when the size is needed in all other cases */
  788. /* we just try to remove the elements in the queue. */
  789. /* */
  790. /********************************************************************/
  791. template <class TYPE,class LOCK> SBIT32 QUEUE<TYPE,LOCK>::SizeOfQueue( VOID )
  792. {
  793. REGISTER SBIT32 Size;
  794. //
  795. // Claim a shared lock (if enabled).
  796. //
  797. ClaimSharedLock();
  798. //
  799. // Compute the size of the queue.
  800. //
  801. Size = (Back - Front);
  802. if ( Size < 0 )
  803. { Size += MaxSize; }
  804. //
  805. // Release any lock we claimed earlier.
  806. //
  807. ReleaseSharedLock();
  808. return Size;
  809. }
  810. /********************************************************************/
  811. /* */
  812. /* Class destructor. */
  813. /* */
  814. /* Destory a queue. This call is not thread safe and should */
  815. /* only be made in a single thread environment. */
  816. /* */
  817. /********************************************************************/
  818. template <class TYPE,class LOCK> QUEUE<TYPE,LOCK>::~QUEUE( VOID )
  819. { /* void */ }
  820. #endif