@ -1,22 +0,0 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: CInfoDefine.h | |||
@Time: 2022/4/16 14:01 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_CINFODEFINE_H | |||
#define CGRAPH_CINFODEFINE_H | |||
#include "CBasicDefine.h" | |||
CGRAPH_NAMESPACE_BEGIN | |||
static const char* CGRAPH_EMPTY = ""; | |||
static const char* CGRAPH_BASIC_EXCEPTION = "CGraph Exception"; | |||
static const char* CGRAPH_FUNCTION_NO_SUPPORT = "function no support"; | |||
CGRAPH_NAMESPACE_END | |||
#endif //CGRAPH_CINFODEFINE_H |
@ -0,0 +1,29 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: CStdEx.h | |||
@Time: 2023/1/31 23:15 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_CSTDEX_H | |||
#define CGRAPH_CSTDEX_H | |||
#include <memory> | |||
#include <type_traits> | |||
CGRAPH_NAMESPACE_BEGIN | |||
// 兼容 std::enable_if_t 的语法 | |||
template<bool B, typename T = void> | |||
using c_enable_if_t = typename std::enable_if<B, T>::type; | |||
// 兼容 std::make_unique 的语法 | |||
template<typename T, typename... Args> | |||
typename std::unique_ptr<T> c_make_unique(Args&&... args) { | |||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |||
} | |||
CGRAPH_NAMESPACE_END | |||
#endif //CGRAPH_CSTDEX_H |
@ -0,0 +1,24 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: CInfoDefine.h | |||
@Time: 2022/4/16 14:01 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_CSTRDEFINE_H | |||
#define CGRAPH_CSTRDEFINE_H | |||
#include "CBasicDefine.h" | |||
CGRAPH_NAMESPACE_BEGIN | |||
static const char* CGRAPH_EMPTY = ""; | |||
static const char* CGRAPH_DEFAULT = "default"; | |||
static const char* CGRAPH_UNKNOWN = "unknown"; | |||
static const char* CGRAPH_BASIC_EXCEPTION = "CGraph default exception"; | |||
static const char* CGRAPH_FUNCTION_NO_SUPPORT = "CGraph function no support"; | |||
CGRAPH_NAMESPACE_END | |||
#endif //CGRAPH_CSTRDEFINE_H |
@ -0,0 +1,14 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: ULockInclude.h | |||
@Time: 2023/2/21 22:19 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_ULOCKINCLUDE_H | |||
#define CGRAPH_ULOCKINCLUDE_H | |||
#include "USpinLock.h" | |||
#endif //CGRAPH_ULOCKINCLUDE_H |
@ -0,0 +1,51 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: USpinLock.h | |||
@Time: 2023/2/21 22:17 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_USPINLOCK_H | |||
#define CGRAPH_USPINLOCK_H | |||
#include <atomic> | |||
#include "../UThreadObject.h" | |||
CGRAPH_NAMESPACE_BEGIN | |||
class USpinLock : public UThreadObject { | |||
public: | |||
/** | |||
* 加锁 | |||
*/ | |||
CVoid lock() { | |||
// memory_order_acquire 后面访存指令勿重排至此条指令之前 | |||
while (flag_.test_and_set(std::memory_order_acquire)) { | |||
} | |||
} | |||
/** | |||
* 解锁 | |||
*/ | |||
CVoid unlock() { | |||
// memory_order_release 前面访存指令勿重排到此条指令之后 | |||
flag_.clear(std::memory_order_release); | |||
} | |||
/** | |||
* 尝试加锁。若未加锁,会上锁 | |||
* @return | |||
*/ | |||
CBool tryLock() { | |||
return !flag_.test_and_set(); | |||
} | |||
private: | |||
std::atomic_flag flag_ = ATOMIC_FLAG_INIT; // 标志位 | |||
}; | |||
CGRAPH_NAMESPACE_END | |||
#endif //CGRAPH_USPINLOCK_H |
@ -0,0 +1,129 @@ | |||
/*************************** | |||
@Author: Chunel | |||
@Contact: chunel@foxmail.com | |||
@File: UAtomicRingBufferQueue.h | |||
@Time: 2022/10/22 22:32 | |||
@Desc: 本 queue 仅支持单入单出模式 | |||
***************************/ | |||
#ifndef CGRAPH_UATOMICRINGBUFFERQUEUE_H | |||
#define CGRAPH_UATOMICRINGBUFFERQUEUE_H | |||
#include <vector> | |||
#include <atomic> | |||
#include "UQueueObject.h" | |||
CGRAPH_NAMESPACE_BEGIN | |||
template<typename T, CUint capacity = CGRAPH_DEFAULT_RINGBUFFER_SIZE> | |||
class UAtomicRingBufferQueue : public UQueueObject { | |||
public: | |||
explicit UAtomicRingBufferQueue() { | |||
head_ = 0; | |||
tail_ = 0; | |||
capacity_ = capacity; | |||
ring_buffer_queue_.resize(capacity_); | |||
} | |||
~UAtomicRingBufferQueue() override { | |||
clear(); | |||
} | |||
/** | |||
* 设置容量信息 | |||
* @param size | |||
* @return | |||
* @notice 谨慎使用,push信息之后,不推荐使用 | |||
*/ | |||
UAtomicRingBufferQueue* setCapacity(CUint size) { | |||
capacity_ = size; | |||
ring_buffer_queue_.resize(capacity_); | |||
return this; | |||
} | |||
/** | |||
* 获取容量信息 | |||
* @return | |||
*/ | |||
[[nodiscard]] CUint getCapacity() const { | |||
return capacity_; | |||
} | |||
/** | |||
* 写入信息 | |||
* @param value | |||
* @return | |||
*/ | |||
template<class TImpl = T> | |||
CVoid push(const TImpl& value) { | |||
{ | |||
CGRAPH_UNIQUE_LOCK lk(mutex_); | |||
if (isFull()) { | |||
push_cv_.wait(lk, [this] { return !isFull(); }); | |||
} | |||
ring_buffer_queue_[tail_] = std::move(c_make_unique<TImpl>(value)); | |||
tail_ = (tail_ + 1) % capacity_; | |||
} | |||
pop_cv_.notify_one(); | |||
} | |||
/** | |||
* 等待弹出信息 | |||
* @param value | |||
* @return | |||
*/ | |||
template<class TImpl = T> | |||
CVoid waitPop(TImpl& value) { | |||
{ | |||
CGRAPH_UNIQUE_LOCK lk(mutex_); | |||
if (isEmpty()) { | |||
pop_cv_.wait(lk, [this] { return !isEmpty(); }); | |||
} | |||
value = (*ring_buffer_queue_[head_]); | |||
*ring_buffer_queue_[head_] = {}; | |||
head_ = (head_ + 1) % capacity_; | |||
} | |||
push_cv_.notify_one(); | |||
} | |||
/** | |||
* 清空所有的数据 | |||
* @return | |||
*/ | |||
CStatus clear() { | |||
CGRAPH_FUNCTION_BEGIN | |||
ring_buffer_queue_.resize(0); | |||
head_ = 0; | |||
tail_ = 0; | |||
CGRAPH_FUNCTION_END | |||
} | |||
protected: | |||
CBool isFull() { | |||
// 空出来一个位置,这个时候不让 tail写入 | |||
return head_ == (tail_ + 1) % capacity_; | |||
} | |||
CBool isEmpty() { | |||
return head_ == tail_; | |||
} | |||
CGRAPH_NO_ALLOWED_COPY(UAtomicRingBufferQueue) | |||
private: | |||
CUint head_; // 头结点位置 | |||
CUint tail_; // 尾结点位置 | |||
CUint capacity_; // 环形缓冲的容量大小 | |||
std::condition_variable push_cv_; // 写入的条件变量。为了保持语义完整,也考虑今后多入多出的可能性,不使用 父类中的 cv_了 | |||
std::condition_variable pop_cv_; // 读取的条件变量 | |||
std::vector<std::unique_ptr<T> > ring_buffer_queue_; // 环形缓冲区 | |||
}; | |||
CGRAPH_NAMESPACE_END | |||
#endif //CGRAPH_UATOMICRINGBUFFERQUEUE_H |
@ -1,54 +0,0 @@ | |||
/*************************** | |||
@Author: MirrorYuChen | |||
@Contact: 2458006366@qq.com | |||
@File: UMemory.h | |||
@Time: 2022/10/11 01:43 上午 | |||
@Desc: | |||
***************************/ | |||
#ifndef CGRAPH_UMEMORY_H | |||
#define CGRAPH_UMEMORY_H | |||
#include <memory> | |||
#include <type_traits> | |||
#include "../CBasic/CBasicInclude.h" | |||
CGRAPH_NAMESPACE_BEGIN | |||
template<bool B, typename T = void> | |||
using enable_if_t = typename std::enable_if<B, T>::type; | |||
template<typename T> | |||
struct MakeUniqueResult { | |||
using scalar = std::unique_ptr<T>; | |||
}; | |||
template<typename T> | |||
struct MakeUniqueResult<T[]> { | |||
using array = std::unique_ptr<T[]>; | |||
}; | |||
template<typename T, size_t N> | |||
struct MakeUniqueResult<T[N]> { | |||
using invalid = void; | |||
}; | |||
template<typename T, typename... Args> | |||
typename MakeUniqueResult<T>::scalar make_unique( | |||
Args &&... args) { | |||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |||
} | |||
template<typename T> | |||
typename MakeUniqueResult<T>::array make_unique(size_t n) { | |||
return std::unique_ptr<T>(new typename std::remove_extent<T>[n]()); | |||
} | |||
template<typename T, typename... Args> | |||
typename MakeUniqueResult<T>::invalid make_unique( | |||
Args &&... /* args */) = delete; | |||
CGRAPH_NAMESPACE_END | |||
#endif // CGRAPH_UMEMORY_H |