mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
added wf queue
This commit is contained in:
122
repos/dde_uos-intel-gpgpu/src/virt/strategies/util/wf_queue.h
Normal file
122
repos/dde_uos-intel-gpgpu/src/virt/strategies/util/wf_queue.h
Normal file
@@ -0,0 +1,122 @@
|
||||
#ifndef WF_QUEUE
|
||||
#define WF_QUEUE
|
||||
|
||||
namespace gpgpu_virt::util {
|
||||
|
||||
/**
|
||||
* @brief Wait-Free Queue
|
||||
* http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
|
||||
*/
|
||||
class alignas(64) WFQueue
|
||||
{
|
||||
|
||||
public:
|
||||
class Chain
|
||||
{
|
||||
private:
|
||||
Chain(const Chain ©);
|
||||
|
||||
public:
|
||||
Chain() : next(nullptr) {}
|
||||
Chain* volatile next;
|
||||
};
|
||||
|
||||
private:
|
||||
WFQueue(const WFQueue& copy);
|
||||
alignas(64) Chain* volatile head;
|
||||
|
||||
protected:
|
||||
alignas(64) Chain* tail;
|
||||
alignas(32) Chain stub;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new WFQueue
|
||||
*
|
||||
*/
|
||||
WFQueue() : head(&stub), tail(&stub), stub() { }
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
inline void enqueue(Chain* item);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @return Chain*
|
||||
*/
|
||||
inline Chain* dequeue();
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
inline void remove(Chain* item);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
inline bool empty() { return tail->next == nullptr; }
|
||||
};
|
||||
|
||||
inline void WFQueue::enqueue(Chain* item)
|
||||
{
|
||||
item->next = nullptr;
|
||||
Chain* prev = __sync_lock_test_and_set(&head, item);
|
||||
prev->next = item;
|
||||
}
|
||||
|
||||
inline WFQueue::Chain* WFQueue::dequeue()
|
||||
{
|
||||
Chain* t = (Chain*)tail;
|
||||
Chain* n = t->next;
|
||||
if (t == &stub) {
|
||||
if (nullptr == n) return nullptr;
|
||||
tail = n;
|
||||
t = n;
|
||||
n = n->next;
|
||||
}
|
||||
if (n) {
|
||||
tail = n;
|
||||
t->next = nullptr;
|
||||
return t;
|
||||
}
|
||||
volatile Chain* h = head;
|
||||
if (t != h) return nullptr;
|
||||
enqueue(&stub);
|
||||
n = t->next;
|
||||
if (n) {
|
||||
tail = n;
|
||||
t->next = nullptr;
|
||||
return t;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline void WFQueue::remove(Chain* item)
|
||||
{
|
||||
// serach item
|
||||
Chain* prev = head;
|
||||
while(prev->next != item && prev->next != nullptr)
|
||||
{
|
||||
prev = prev->next;
|
||||
}
|
||||
|
||||
// remove it
|
||||
if(prev != nullptr)
|
||||
{
|
||||
prev->next = item->next;
|
||||
item->next = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // WF_QUEUE
|
||||
Reference in New Issue
Block a user