我需要一個簡單的非阻塞靜態塊大小的內存池。我在網上找不到這樣的內容。所以每個人都需要這樣的解決方案。這個是免費的...只適用於Win32。非阻塞線程安全內存池實現
最好的問候,
弗里德里希
#ifndef MEMPOOL_HPP_INCLUDED
#define MEMPOOL_HPP_INCLUDED
#include "atomic.hpp"
#include "static_assert.hpp"
#pragma warning(push)
#pragma warning(disable : 4311) // warning C4311: 'Typumwandlung'
/// @brief Block-free memory-pool implemenation
/// @tparam T Object-type to be saved within the memory-pool.
/// @tparam S Capacy of the memory-pool.
template <typename T, int S>
class MemoryPool
{
private:
STATIC_ASSERT(sizeof(int) == sizeof(void*), "Well, ...");
public:
/// @brief Object-type saved within the pool.
typedef T TYPE;
enum
{
/// @brief Capacy of the memory-pool.
SIZE = S
};
private:
/// @brief Chunks, that holds the memory
struct Chunk
{
/// @brief Single-linked list.
Chunk* Next;
/// @brief The value
/// We do not call the default constructor this way.
char Value[sizeof(TYPE)];
};
/// @brief The root object.
Chunk* Root;
/// @brief The pool
Chunk Pool[SIZE];
private:
// do not allow copying
MemoryPool(const MemoryPool&);
MemoryPool& operator=(const MemoryPool&);
void free(Chunk* c)
{
c->Next = Root;
while(!CompareAndSwap((int*)&Root, (int)c->Next, (int)c))
{
c->Next = Root;
}
}
public:
/// Default constructor
/// Creates an empty memory-pool.
/// Invalidates all the memory.
MemoryPool()
: Root(0)
{
for(int i = 0; i < SIZE; i++)
{
MemoryPool::free(&Pool[i]);
}
}
/// @brief Frees a chunk of memory, that was allocated by MemoryPool::malloc
/// @param _Chunk A chunk of memory, that was allocated by MemoryPool::malloc
/// This function will not call the destructor.
/// Thread-safe, non-blocking
void free(T* _Chunk)
{
if(!_Chunk)
return;
Chunk* c = (Chunk*)((int)(_Chunk) - sizeof(Chunk*));
if(c < &Pool[0] || c > &Pool[SIZE - 1])
return;
MemoryPool::free(c);
}
/// @brief Returns a pointer to a chunk of memory
/// @return 0 on a memory shortage
/// @return A pointer to a chunk of memory
/// This function will not call the constructor.
/// Thread-safe, non-blocking
T* malloc()
{
Chunk* r = Root;
if(!r)
return 0;
while(!CompareAndSwap((int*)&Root, (int)r, (int)r->Next))
{
r = Root;
if(!r)
return 0;
}
return &(r->Value);
}
};
#pragma warning(pop)
#endif // MEMPOOL_HPP_INCLUDED
而且比較並交換
/// @brief Atomic compare and set
/// Atomically compare the value stored at *p with cmpval and if the
/// two values are equal, update the value of *p with newval. Returns
/// zero if the compare failed, nonzero otherwise.
/// @param p Pointer to the target
/// @param cmpval Value as we excpect it
/// @param newval New value
static inline int CompareAndSwap(volatile int *_ptr, int _old, int _new)
{
__asm {
mov eax, [_old] // place the value of _old to EAX
mov ecx, [_new] // place the value of _new to ECX
mov edx, [_ptr] // place the pointer of _ptr to EDX
lock cmpxchg [edx], ecx // cmpxchg old (EAX) and *ptr ([EDX])
}
return 1;
}
謝謝,但因此不爲這類職位。 – 2010-11-19 17:17:41
順便說一句:如果這隻適用於Windows:爲什麼不使用InterlockedXYZ()? – mmmmmmmm 2010-11-19 17:23:06
7個問題,0答案,0票,0票接受。謝謝,但是SO不適合這種用戶。 – 2010-11-19 17:27:28