Sese Framework  x.y.z
A cross-platform framework
载入中...
搜索中...
未找到
LinkedQueue.h
浏览该文件的文档.
1// Copyright 2024 libsese
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
23#pragma once
24
25#include <atomic>
26
27namespace sese::concurrent {
28
29// GCOVR_EXCL_START
30
33template<class T>
36 struct Node {
37 std::atomic<T> value{};
38 std::atomic<Node *> next{nullptr};
39 };
40
41 std::atomic<Node *> head{nullptr};
42 std::atomic<Node *> tail{nullptr};
43
44public:
46 auto node = new Node();
47 head.store(node);
48 tail.store(node);
49 }
50
52 auto p_node = head.load();
53 while (p_node) {
54 auto p_next = p_node->next.load();
55 if (p_next == p_node) {
56 p_next = nullptr;
57 }
58 delete p_node;
59 p_node = p_next;
60 }
61 }
62
63 void push(const T &value) {
64 Node *tail;
65 auto node = new Node();
66 node->value.store(value);
67 node->next.store(nullptr);
68 while (true) {
69 tail = this->tail.load();
70 auto next = tail->next.load();
71 if (tail == this->tail) {
72 if (next == nullptr) {
73 if (tail->next.compare_exchange_weak(next, node)) {
74 break;
75 }
76 } else {
77 this->tail.compare_exchange_weak(tail, next);
78 }
79 }
80 }
81 this->tail.compare_exchange_weak(tail, node);
82 }
83
84 bool pop(T &value) {
85 Node *head;
86 while (true) {
87 head = this->head.load();
88 auto tail = this->tail.load();
89 auto next = head->next.load();
90 if (head == this->head) {
91 if (head == tail) {
92 if (next == nullptr) {
93 return false;
94 }
95 this->tail.compare_exchange_weak(tail, next);
96 } else {
97 value = next->value;
98 if (this->head.compare_exchange_weak(head, next)) {
99 break;
100 }
101 }
102 }
103 }
104 delete head;
105 return true;
106 }
107
108 bool empty() {
109 return head == tail;
110 }
111};
112
113// GCOVR_EXCL_STOP
114
115} // namespace sese::concurrent