C ++ 17 Без блокировки.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 C ++ 17 Без блокировки.

Сообщение Anonymous »

У меня есть базовый распределитель на основе блоков, который будет использоваться для распределения памяти для типов POD в многопоточной настройке, где все потоки будут запрашивать или выпускать память одновременно в пул общей памяти. Моя текущая реализация подробно описана здесь: < /p>
#include
#include

template class BlockAlloc {
private:
// element_t is either the data for T or a pointer to the next free element_t
struct element_t {
::byte buffer[sizeof(T) > sizeof(element_t*) ? sizeof(T) : sizeof(element_t*)];
element_t*& next() {return reinterpret_cast(buffer);};
T*& data() {return reinterpret_cast(buffer);};
};

// block_t is a contiguous block of elements
struct block_t {
element_t elements[BlockSize];
};

// Allocate one new block of contiguous elements
void AllocBlock() {
block_t* block = new block_t();

// each element in the block points to the previous element...
for (int i = 1; i < BlockSize; i++)
block->elements.next() = &block->elements;

// free should point to the final element in the block,
// while the first element of the block points to free's old location.
// Update made with compare-and-swap loop:
while (!free.compare_exchange_strong(block->elements[0].next() = free.load(), &block->elements[BlockSize-1])) {}

// add the block to the list of all allocated blocks
blocks.push(block);
};

// Release all memory held by all blocks
void ReleaseBlocks() {
free = nullptr;
block_t* block {nullptr};
while (blocks.try_pop(block)) delete block;
};

public:
BlockAlloc() : blocks {}, free(nullptr) { AllocBlock(); };
~BlockAlloc() { ReleaseBlocks(); };

// Acquire a new element from the free list and construct it.
template _type_* Alloc(TArgs &&... a) {
_type_* data {nullptr};
element_t* element {nullptr};

// Grab the free element and set free to the next item in that list
// Update made with compare-and-swap loop:
while (true) {
if (element = free.load()) {
// CRASHES HERE DURING THE CMPxSWP,
// 0xC0000005: "access violation reading location"
if (free.compare_exchange_strong(element, element->next())) {
data = element->data();
new (data) _type_(std::forward(a)...);
return data;
}
}
else {
// if free is empty, grow the list
AllocBlock();
}
}
};

// Destroys the element and return its memory to the free list
void Free(_type_* element) {
if (element == nullptr) {return;}
element->~_type_();
element_t* t = (element_t*)(element);

while (true)
if (free.compare_exchange_strong(t->next() = free.load(), t))
return;
};

concurrency::concurrent_queue blocks;
std::atomic free;
};
< /code>
Запуск в одном потоке эта реализация работает правильно, однако при тестировании в многопоточном приложении этот код быстро сбои в операции Compare и Swap вызовов Alloc, за исключением: < /p>
0xC0000005: "access violation reading location".
< /code>
Я не могу рассказать, что я делаю неправильно, что приведет к брошению этого исключения. Любой совет или вклад были бы очень оценены!

Подробнее здесь: https://stackoverflow.com/questions/795 ... g-location
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»