Tôi cần một nhóm bộ nhớ kích thước khối tĩnh không chặn đơn giản. Tôi không tìm thấy như vậy trên web. Vì vậy, tất cả mọi người, những người cần một giải pháp như vậy. Điều này là miễn phí ... chỉ hoạt động trên Win32.Việc triển khai pool bộ nhớ an toàn cho luồng không bị chặn
Trân trọng,
Friedrich
#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
Và CompareAndSwap
/// @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;
}
Cảm ơn, nhưng SO không phải là cho các loại hình đường bưu điện. –
BTW: Nếu điều này chỉ hoạt động trên Windows: Tại sao không sử dụng InterlockedXYZ()? – mmmmmmmm
7 câu hỏi, 0 câu trả lời, 0 phiếu bầu, 0 chấp nhận. Cảm ơn, nhưng SO không dành cho loại người dùng này. –