У меня есть базовый распределитель на основе блоков, который будет использоваться для распределения памяти для типов 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
C ++ 17 Без блокировки. ⇐ C++
Программы на C++. Форум разработчиков
1749569375
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[i].next() = &block->elements[i - 1];
// 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>
Я не могу рассказать, что я делаю неправильно, что приведет к брошению этого исключения. Любой совет или вклад были бы очень оценены!
Подробнее здесь: [url]https://stackoverflow.com/questions/79599086/c17-lock-free-allocator-crashing-access-violation-reading-location[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия