参考LOKI内存池实现。当定义了USE_NO_LOCK宏时,编译成无锁版本。
// defs.h#ifndef _DEFS_H_#define _DEFS_H_typedef char int8 ;typedef unsigned char uint8 ;typedef uint8 byte ;typedef short int16 ;typedef unsigned short uint16 ;typedef int int32 ;typedef unsigned int uint32 ;#ifdef _MSC_VER typedef __int64 int64 ; typedef unsigned __int64 uint64 ; #ifdef _WIN32 typedef uint32 uaddr ; #else typedef uint64 uaddr ; #endif #define STDCALL __stdcall#else typedef long long int64 ; typedef unsigned long long uint64 ; #if __SIZEOF_POINTER__ == 4 typedef uint32 uaddr ; #elif __SIZEOF_POINTER__ == 8 typedef uint64 uaddr ; #endif #define STDCALL __attribute__((stdcall))#endif#ifdef USE_NO_LOCK#define MEM_POOL_NO_LOCK#define TASK_SCHEDULE_NO_LOCK#define IO_BUFFER_NO_LOCK#endif#endif //_DEFS_H_
// atom.h 原子操作#ifndef _ATOM_H_#define _ATOM_H_#include "defs.h"#ifdef _MSC_VER #include#elif defined(__GNUC__) #if __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<1) #error GCC version must be greater or equal than 4.1.2 #endif //#include #else #error Currently only windows and linux os are supported#endif//自增,返回新值inline uint32 AtomSelfAdd(void *var){#ifdef _MSC_VER return InterlockedIncrement((long *)var); // NOLINT#else return __sync_add_and_fetch((uint32 *)var, 1); // NOLINT#endif}//自减,返回新值inline uint32 AtomSelfDec(void *var) {#ifdef _MSC_VER return InterlockedDecrement((long *)var); // NOLINT#else return __sync_add_and_fetch((uint32 *)var, -1); // NOLINT#endif}//加一个值,返回旧值inline uint32 AtomAdd(void *var, const uint32 value) {#ifdef _MSC_VER return InterlockedExchangeAdd((long *)var, value); // NOLINT#else return __sync_fetch_and_add((uint32 *)var, value); // NOLINT#endif}//减一个值,返回旧值inline uint32 AtomDec(void *var, int32 value) { value = value * -1;#ifdef _MSC_VER return InterlockedExchangeAdd((long *)var, value); // NOLINT#else return __sync_fetch_and_add((uint32 *)var, value); // NOLINT#endif}//赋值,windows下返回新值,linux下返回旧值inline uint32 AtomSet(void *var, const uint32 value) {#ifdef _MSC_VER ::InterlockedExchange((long *)var, (long)value); // NOLINT#else __sync_lock_test_and_set((uint32 *)var, value); // NOLINT#endif return value;}//取值inline uint32 AtomGet(void *var) {#ifdef _MSC_VER return InterlockedExchangeAdd((long *)var, 0); // NOLINT#else return __sync_fetch_and_add((uint32 *)var, 0); // NOLINT#endif}//cas 返回旧值inline uint32 AtomCmpAndSet(void *var, uint32 uiCmp, uint32 uiSet){#ifdef _MSC_VER return InterlockedCompareExchange((long *)var, (long)uiSet, (long)uiCmp) ;#else return __sync_val_compare_and_swap((uint32 *)var, uiCmp, uiSet) ;#endif}//cas 返回旧值inline void* AtomCmpAndSetPointer(void **pOri, void *pCmp, void *pSet){#ifdef _MSC_VER return InterlockedCompareExchangePointer(pOri, pSet, pCmp) ;#else return __sync_val_compare_and_swap(pOri, pCmp, pSet) ;#endif}//cas 返回bool值inline bool AtomBoolCmpAndSet(void *var, uint32 uiCmp, uint32 uiSet){#ifdef _MSC_VER return InterlockedCompareExchange((long *)var, (long)uiSet, (long)uiCmp) == (long)uiCmp ;#else return __sync_bool_compare_and_swap((uint32 *)var, uiCmp, uiSet) ;#endif}//cas 返回bool值inline bool AtomBoolCmpAndSetPointer(void **pOri, void *pCmp, void *pSet){#ifdef _MSC_VER return InterlockedCompareExchangePointer(pOri, pSet, pCmp) == pCmp ;#else return __sync_bool_compare_and_swap(pOri, pCmp, pSet) ;#endif}#endif //_ATOM_H_
// Sync.h#ifndef _MDL_SYNC_H_#define _MDL_SYNC_H_#include "defs.h"#include "atom.h"#define _SYNC_NO_LOCK_ //使用无锁#ifdef _SYNC_NO_LOCK_ typedef volatile uint32 SYNCOBJ; #ifdef _WIN_VER_ #include#if(_WIN32_WINNT >= 0x0400) #define Sync_Yield() SwitchToThread() #else #define Sync_Yield() Sleep(0) #endif #else #include #define Sync_Yield() sched_yield() #endif #define Sync_Init(pObj) *(pObj) = 0 #define Sync_Destroy(pObj) *(pObj) = 0 #define Sync_Lock(pObj) while(0 != *(pObj) || 1 != AtomSelfAdd((void *)(pObj))){Sync_Yield();} #define Sync_Unlock(pObj) AtomSet((void *)(pObj), 0)#else #ifdef _WIN_VER_ #include typedef CRITICAL_SECTION SYNCOBJ; #define Sync_Init(pObj) InitializeCriticalSection(pObj) #define Sync_Destroy(pObj) DeleteCriticalSection(pObj) #define Sync_Lock(pObj) EnterCriticalSection(pObj) #define Sync_Unlock(pObj) LeaveCriticalSection(pObj) #else #include typedef pthread_mutex_t SYNCOBJ; #define Sync_Init(pObj) pthread_mutex_init(pObj, NULL) #define Sync_Destroy(pObj) pthread_mutex_destroy(pObj) #define Sync_Lock(pObj) pthread_mutex_lock(pObj) #define Sync_Unlock(pObj) pthread_mutex_unlock(pObj) #endif#endifnamespace mdl{class Sync{public: Sync() { Sync_Init(&m_syncObj); } ~Sync() { Sync_Destroy(&m_syncObj); } void Lock() { Sync_Lock(&m_syncObj); } void Unlock() { Sync_Unlock(&m_syncObj); }private: Sync(const Sync &); Sync& operator=(const Sync &);private: SYNCOBJ m_syncObj;};class AutoSync{public: AutoSync(Sync *pSync) : m_pSync(pSync), m_bLocked(true) { m_pSync->Lock(); } ~AutoSync() { Unlock(); } void Unlock() { if(m_bLocked) { m_pSync->Unlock(); m_bLocked = false; } }private: AutoSync(const AutoSync &); AutoSync& operator=(const AutoSync &);private: Sync *m_pSync; bool m_bLocked;};} // namespace mdl#endif //_MDL_SYNC_H_
// MemPool.h#ifndef _MDL_MEM_POOL_H_#define _MDL_MEM_POOL_H_#include "defs.h"#include "atom.h"#include "Sync.h"namespace mdl{class MemBlock{public: MemBlock(); ~MemBlock(); byte *Allocator(uint32 uiSize, uint32 uiCount);private: byte *AllocBuf(uint32 uiSize, uint32 uiCount); MemBlock *m_pNextBlock; byte *m_pBuf; //预先申请的内存块};class MemPool{public: MemPool(uint32 uiSize, uint32 uiCount = 512); virtual ~MemPool(); void *Alloc(); void Free(void *pMem); uint32 GetPerMemSize() { return m_uiSize; } uint32 GetPerBlockCount() { return m_uiCount; } uint32 GetUsedCount() { return m_uiUsed; } uint32 GetFreeCount() { return m_uiFree; }protected: MemBlock m_memBlock; byte *m_pNextFreeMem; //下一个可分配的内存地址 uint32 m_uiSize; //分配出去的每个内存大小 uint32 m_uiCount; //数量。m_pBufList[i]指向内存块(大小:m_uiSize * m_uiCount) volatile uint32 m_uiUsed; //使用数 volatile uint32 m_uiFree; //空闲数 Sync m_lock; //private: byte *AllocBlock(uint32 uiSize, uint32 uiCount); MemPool(const MemPool &); MemPool& operator=(const MemPool &);};} // namespace mdl#endif //_MDL_MEM_POOL_H_
// MemPool.cpp#include#include #include "MemPool.h"namespace mdl{MemBlock::MemBlock() : m_pNextBlock(NULL), m_pBuf(NULL){}MemBlock::~MemBlock(){ if(NULL != m_pBuf) delete [] m_pBuf; if(NULL != m_pNextBlock) delete m_pNextBlock;}byte* MemBlock::Allocator(uint32 uiSize, uint32 uiCount){ MemBlock *p = new (std::nothrow) MemBlock; if(NULL != p && NULL != p->AllocBuf(uiSize, uiCount)) { p->m_pNextBlock = m_pNextBlock; m_pNextBlock = p; return p->m_pBuf; } else { if(NULL != p) delete p; return NULL; }}byte* MemBlock::AllocBuf(uint32 uiSize, uint32 uiCount){ uint32 ui; m_pBuf = new (std::nothrow) byte[uiSize * uiCount]; //m_pNextBlock = NULL; if(NULL != m_pBuf) { for(ui=0; ui