1 Star 0 Fork 0

windsPx/lunzi

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
NonLockQueueArray.hpp 3.88 KB
一键复制 编辑 原始数据 按行查看 历史
windsPx 提交于 2022-12-23 01:52 . 随便改改
#pragma once
#include <stdlib.h>
#include <atomic>
#include <stdio.h>
#include <thread>
namespace fqa
{
constexpr int DefQALength = 512 * 1024;
//Size必须是2^n
template <typename T, int Size= DefQALength>
class CNonLockQueueArray
{
public:
typedef T Obj_Type;
public:
int m_buf_mask;
//! 存储空间
char pad[56] = {0};
T m_array[Size];
//! 头尾
char pad1[56] = {0};
std::atomic<uint64_t> m_head;
char pad2[56] = {0};
std::atomic<uint64_t> m_tail;
//! 当前最大索引数(多个线程写时必须保证按时间序递增)
char pad3[56] = {0};
std::atomic<uint64_t> m_max_index;
char pad4[56] = {0};
std::atomic<uint64_t> m_min_index;
public:
CNonLockQueueArray() : m_buf_mask(Size - 1), m_head(0), m_tail(0), m_max_index(0), m_min_index(0)
{
memset(m_array, 0, sizeof(m_array));
}
CNonLockQueueArray(const CNonLockQueueArray&) = delete;
CNonLockQueueArray(CNonLockQueueArray&&) = delete;
CNonLockQueueArray& operator&=(const CNonLockQueueArray&) = delete;
CNonLockQueueArray& operator&=(CNonLockQueueArray&&) = delete;
public:
//sp
bool spush_back(T&& val);
//mp
bool push_back(T&& val);
//sc
T pop_front();
//mc
T mpop_front();
};
template <typename T, int Size>
bool CNonLockQueueArray<T, Size>::spush_back(T&& val)
{
do
{
uint64_t max_index = m_tail.load(std::memory_order_relaxed);
uint64_t min_index = m_head.load(std::memory_order_acquire);
if (max_index - min_index >= Size)
{
continue;
}
//写值
m_array[max_index & m_buf_mask] = std::move(val);
std::atomic_signal_fence(std::memory_order_release);
m_tail.store(max_index + 1, std::memory_order_release);
break;
} while (1);
return true;
}
template <typename T, int Size>
bool CNonLockQueueArray<T, Size>::push_back(T&& val)
{
do
{
uint64_t max_index = m_tail.load(std::memory_order_acquire);
uint64_t min_index = m_head.load(std::memory_order_acquire);
uint64_t next_index = max_index + 1;
if (max_index - min_index >= Size)
{
continue;
}
if (!m_max_index.compare_exchange_strong(max_index, next_index, std::memory_order_acquire))
{
continue;
}
//写值
m_array[max_index & m_buf_mask] = std::move(val);
std::atomic_signal_fence(std::memory_order_release);
m_tail.store(max_index + 1, std::memory_order_release);
break;
} while (1);
return true;
}
template <typename T, int Size>
T CNonLockQueueArray<T, Size>::pop_front()
{
uint64_t index = 0;
uint64_t order_index = 0;
T val;
index = m_head.load(std::memory_order_relaxed);
order_index = m_tail.load(std::memory_order_acquire);
if (index >= order_index)
{
return val;
}
//取值
// val = std::move(m_array[index & m_buf_mask]);
val = m_array[index & m_buf_mask];
m_head.store(index + 1, std::memory_order_release);
return val;
}
template <typename T, int Size>
T CNonLockQueueArray<T, Size>::mpop_front()
{
uint64_t index = 0;
uint64_t order_index = 0;
T val;
do
{
order_index = m_tail.load(std::memory_order_acquire);
index = m_head.load(std::memory_order_acquire);
if (index >= order_index)
{
return T();
}
if (!m_min_index.compare_exchange_strong(index, index + 1, std::memory_order_acquire))
{
continue;
}
//取值
// val = std::move(m_array[index & m_buf_mask]);
val = m_array[index & m_buf_mask];
m_head.store(index + 1, std::memory_order_release);
break;
} while (1);
return val;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/windpx/lunzi.git
[email protected]:windpx/lunzi.git
windpx
lunzi
lunzi
master

搜索帮助