Shadowrun: Awakened 29 September 2011 - Build 871
DS_ThreadsafeAllocatingQueue.h
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 #ifndef __THREADSAFE_ALLOCATING_QUEUE
00006 #define __THREADSAFE_ALLOCATING_QUEUE
00007 
00008 #include "DS_Queue.h"
00009 #include "SimpleMutex.h"
00010 #include "DS_MemoryPool.h"
00011 
00012 // #if defined(new)
00013 // #pragma push_macro("new")
00014 // #undef new
00015 // #define RMO_NEW_UNDEF_ALLOCATING_QUEUE
00016 // #endif
00017 
00018 namespace DataStructures
00019 {
00020 
00021 template <class structureType>
00022 class RAK_DLL_EXPORT ThreadsafeAllocatingQueue
00023 {
00024 public:
00025     // Queue operations
00026     void Push(structureType *s);
00027     structureType *PopInaccurate(void);
00028     structureType *Pop(void);
00029     void SetPageSize(int size);
00030     bool IsEmpty(void);
00031 
00032     // Memory pool operations
00033     structureType *Allocate(const char *file, unsigned int line);
00034     void Deallocate(structureType *s, const char *file, unsigned int line);
00035     void Clear(const char *file, unsigned int line);
00036 protected:
00037 
00038     MemoryPool<structureType> memoryPool;
00039     RakNet::SimpleMutex memoryPoolMutex;
00040     Queue<structureType*> queue;
00041     RakNet::SimpleMutex queueMutex;
00042 };
00043     
00044 template <class structureType>
00045 void ThreadsafeAllocatingQueue<structureType>::Push(structureType *s)
00046 {
00047     queueMutex.Lock();
00048     queue.Push(s, _FILE_AND_LINE_ );
00049     queueMutex.Unlock();
00050 }
00051 
00052 template <class structureType>
00053 structureType *ThreadsafeAllocatingQueue<structureType>::PopInaccurate(void)
00054 {
00055     structureType *s;
00056     if (queue.IsEmpty())
00057         return 0;
00058     queueMutex.Lock();
00059     if (queue.IsEmpty()==false)
00060         s=queue.Pop();
00061     else
00062         s=0;
00063     queueMutex.Unlock();    
00064     return s;
00065 }
00066 
00067 template <class structureType>
00068 structureType *ThreadsafeAllocatingQueue<structureType>::Pop(void)
00069 {
00070     structureType *s;
00071     queueMutex.Lock();
00072     if (queue.IsEmpty())
00073     {
00074         queueMutex.Unlock();    
00075         return 0;
00076     }
00077     s=queue.Pop();
00078     queueMutex.Unlock();    
00079     return s;
00080 }
00081 
00082 template <class structureType>
00083 structureType *ThreadsafeAllocatingQueue<structureType>::Allocate(const char *file, unsigned int line)
00084 {
00085     structureType *s;
00086     memoryPoolMutex.Lock();
00087     s=memoryPool.Allocate(file, line);
00088     memoryPoolMutex.Unlock();
00089     // Call new operator, memoryPool doesn't do this
00090     s = new ((void*)s) structureType;
00091     return s;
00092 }
00093 template <class structureType>
00094 void ThreadsafeAllocatingQueue<structureType>::Deallocate(structureType *s, const char *file, unsigned int line)
00095 {
00096     // Call delete operator, memory pool doesn't do this
00097     s->~structureType();
00098     memoryPoolMutex.Lock();
00099     memoryPool.Release(s, file, line);
00100     memoryPoolMutex.Unlock();
00101 }
00102 
00103 template <class structureType>
00104 void ThreadsafeAllocatingQueue<structureType>::Clear(const char *file, unsigned int line)
00105 {
00106     memoryPoolMutex.Lock();
00107     for (unsigned int i=0; i < queue.Size(); i++)
00108     {
00109         queue[i]->~structureType();
00110         memoryPool.Release(queue[i], file, line);
00111     }
00112     queue.Clear(file, line);
00113     memoryPoolMutex.Unlock();
00114     memoryPoolMutex.Lock();
00115     memoryPool.Clear(file, line);
00116     memoryPoolMutex.Unlock();
00117 }
00118 
00119 template <class structureType>
00120 void ThreadsafeAllocatingQueue<structureType>::SetPageSize(int size)
00121 {
00122     memoryPool.SetPageSize(size);
00123 }
00124 
00125 template <class structureType>
00126 bool ThreadsafeAllocatingQueue<structureType>::IsEmpty(void)
00127 {
00128     bool isEmpty;
00129     queueMutex.Lock();
00130     isEmpty=queue.IsEmpty();
00131     queueMutex.Unlock();
00132     return isEmpty;
00133 }
00134 
00135 };
00136 
00137 
00138 // #if defined(RMO_NEW_UNDEF_ALLOCATING_QUEUE)
00139 // #pragma pop_macro("new")
00140 // #undef RMO_NEW_UNDEF_ALLOCATING_QUEUE
00141 // #endif
00142 
00143 #endif

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net