| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- /// \file DS_ThreadsafeAllocatingQueue.h
- /// \internal
- /// A threadsafe queue, that also uses a memory pool for allocation
- #ifndef __THREADSAFE_ALLOCATING_QUEUE
- #define __THREADSAFE_ALLOCATING_QUEUE
- #include "DS_Queue.h"
- #include "SimpleMutex.h"
- #include "DS_MemoryPool.h"
- // #if defined(new)
- // #pragma push_macro("new")
- // #undef new
- // #define RMO_NEW_UNDEF_ALLOCATING_QUEUE
- // #endif
- namespace DataStructures
- {
- template <class structureType>
- class RAK_DLL_EXPORT ThreadsafeAllocatingQueue
- {
- public:
- // Queue operations
- void Push(structureType *s);
- structureType *PopInaccurate(void);
- structureType *Pop(void);
- void SetPageSize(int size);
- bool IsEmpty(void);
- structureType * operator[] ( unsigned int position );
- void RemoveAtIndex( unsigned int position );
- unsigned int Size( void );
- // Memory pool operations
- structureType *Allocate(const char *file, unsigned int line);
- void Deallocate(structureType *s, const char *file, unsigned int line);
- void Clear(const char *file, unsigned int line);
- protected:
- mutable MemoryPool<structureType> memoryPool;
- RakNet::SimpleMutex memoryPoolMutex;
- Queue<structureType*> queue;
- RakNet::SimpleMutex queueMutex;
- };
-
- template <class structureType>
- void ThreadsafeAllocatingQueue<structureType>::Push(structureType *s)
- {
- queueMutex.Lock();
- queue.Push(s, _FILE_AND_LINE_ );
- queueMutex.Unlock();
- }
- template <class structureType>
- structureType *ThreadsafeAllocatingQueue<structureType>::PopInaccurate(void)
- {
- structureType *s;
- if (queue.IsEmpty())
- return 0;
- queueMutex.Lock();
- if (queue.IsEmpty()==false)
- s=queue.Pop();
- else
- s=0;
- queueMutex.Unlock();
- return s;
- }
- template <class structureType>
- structureType *ThreadsafeAllocatingQueue<structureType>::Pop(void)
- {
- structureType *s;
- queueMutex.Lock();
- if (queue.IsEmpty())
- {
- queueMutex.Unlock();
- return 0;
- }
- s=queue.Pop();
- queueMutex.Unlock();
- return s;
- }
- template <class structureType>
- structureType *ThreadsafeAllocatingQueue<structureType>::Allocate(const char *file, unsigned int line)
- {
- structureType *s;
- memoryPoolMutex.Lock();
- s=memoryPool.Allocate(file, line);
- memoryPoolMutex.Unlock();
- // Call new operator, memoryPool doesn't do this
- s = new ((void*)s) structureType;
- return s;
- }
- template <class structureType>
- void ThreadsafeAllocatingQueue<structureType>::Deallocate(structureType *s, const char *file, unsigned int line)
- {
- // Call delete operator, memory pool doesn't do this
- s->~structureType();
- memoryPoolMutex.Lock();
- memoryPool.Release(s, file, line);
- memoryPoolMutex.Unlock();
- }
- template <class structureType>
- void ThreadsafeAllocatingQueue<structureType>::Clear(const char *file, unsigned int line)
- {
- memoryPoolMutex.Lock();
- for (unsigned int i=0; i < queue.Size(); i++)
- {
- queue[i]->~structureType();
- memoryPool.Release(queue[i], file, line);
- }
- queue.Clear(file, line);
- memoryPoolMutex.Unlock();
- memoryPoolMutex.Lock();
- memoryPool.Clear(file, line);
- memoryPoolMutex.Unlock();
- }
- template <class structureType>
- void ThreadsafeAllocatingQueue<structureType>::SetPageSize(int size)
- {
- memoryPool.SetPageSize(size);
- }
- template <class structureType>
- bool ThreadsafeAllocatingQueue<structureType>::IsEmpty(void)
- {
- bool isEmpty;
- queueMutex.Lock();
- isEmpty=queue.IsEmpty();
- queueMutex.Unlock();
- return isEmpty;
- }
- template <class structureType>
- structureType * ThreadsafeAllocatingQueue<structureType>::operator[] ( unsigned int position )
- {
- structureType *s;
- queueMutex.Lock();
- s=queue[position];
- queueMutex.Unlock();
- return s;
- }
- template <class structureType>
- void ThreadsafeAllocatingQueue<structureType>::RemoveAtIndex( unsigned int position )
- {
- queueMutex.Lock();
- queue.RemoveAtIndex(position);
- queueMutex.Unlock();
- }
- template <class structureType>
- unsigned int ThreadsafeAllocatingQueue<structureType>::Size( void )
- {
- unsigned int s;
- queueMutex.Lock();
- s=queue.Size();
- queueMutex.Unlock();
- return s;
- }
- }
- // #if defined(RMO_NEW_UNDEF_ALLOCATING_QUEUE)
- // #pragma pop_macro("new")
- // #undef RMO_NEW_UNDEF_ALLOCATING_QUEUE
- // #endif
- #endif
|