/*============================================================================= TStack.h $Log: CAAtomicFIFO.h,v $ Revision 1.3.4.1 2005/04/21 19:28:35 dwyatt bring over a few things from TOT for the benefit of test tools Revision 1.4 2005/03/11 01:41:01 dwyatt renaming Revision 1.3 2004/09/30 21:02:59 jcm10 add missing includes Revision 1.2 2004/06/02 22:39:45 dwyatt add empty() Revision 1.1 2004/05/26 00:33:09 dwyatt moved from Source/CAServices/AudioUnits/Generators/TStack.h Revision 1.2 2004/01/07 22:29:00 dwyatt work in progress Revision 1.1 2003/12/12 22:16:25 dwyatt initial checkin created Tue Oct 28 2003, Doug Wyatt Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved $NoKeywords: $ =============================================================================*/ #ifndef __TStack_h__ #define __TStack_h__ #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) #include #else #include #endif // linked list FIFO stack, elements are pushed and popped atomically // class T must implement set_next() and get_next() template class TAtomicStack { public: TAtomicStack() : mHead(NULL) { } // non-atomic routines, for use when initializing/deinitializing, operate NON-atomically void push_NA(T *item) { item->set_next(mHead); mHead = item; } T * pop_NA() { T *result = mHead; if (result) mHead = result->get_next(); return result; } bool empty() { return mHead == NULL; } // atomic routines void push_atomic(T *item) { T *head; do { head = mHead; item->set_next(head); } while (!CompareAndSwap(UInt32(head), UInt32(item), (UInt32 *)&mHead)); } T * pop_atomic() { T *result; do { if ((result = mHead) == NULL) break; } while (!CompareAndSwap(UInt32(result), UInt32(result->get_next()), (UInt32 *)&mHead)); return result; } T * pop_all() { T *result; do { if ((result = mHead) == NULL) break; } while (!CompareAndSwap(UInt32(result), 0L, (UInt32 *)&mHead)); return result; } protected: T * mHead; }; #endif // __TStack_h__