mpscq.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPC_CORE_LIB_GPRPP_MPSCQ_H
20 #define GRPC_CORE_LIB_GPRPP_MPSCQ_H
21 
23 
24 #include <atomic>
25 
26 #include <grpc/support/log.h>
27 
29 
30 namespace grpc_core {
31 
32 // Multiple-producer single-consumer lock free queue, based upon the
33 // implementation from Dmitry Vyukov here:
34 // http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
36  public:
37  // List node. Application node types can inherit from this.
38  struct Node {
39  std::atomic<Node*> next{nullptr};
40  };
41 
44  GPR_ASSERT(head_.load(std::memory_order_relaxed) == &stub_);
45  GPR_ASSERT(tail_ == &stub_);
46  }
47 
48  // Push a node
49  // Thread safe - can be called from multiple threads concurrently
50  // Returns true if this was possibly the first node (may return true
51  // sporadically, will not return false sporadically)
52  bool Push(Node* node);
53  // Pop a node (returns NULL if no node is ready - which doesn't indicate that
54  // the queue is empty!!)
55  // Thread compatible - can only be called from one thread at a time
56  Node* Pop();
57  // Pop a node; sets *empty to true if the queue is empty, or false if it is
58  // not.
59  Node* PopAndCheckEnd(bool* empty);
60 
61  private:
62  // make sure head & tail don't share a cacheline
63  union {
65  std::atomic<Node*> head_{nullptr};
66  };
69 };
70 
71 // An mpscq with a lock: it's safe to pop from multiple threads, but doing
72 // only one thread will succeed concurrently.
74  public:
76 
77  // Push a node
78  // Thread safe - can be called from multiple threads concurrently
79  // Returns true if this was possibly the first node (may return true
80  // sporadically, will not return false sporadically)
81  bool Push(Node* node);
82 
83  // Pop a node (returns NULL if no node is ready - which doesn't indicate that
84  // the queue is empty!!)
85  // Thread safe - can be called from multiple threads concurrently
86  Node* TryPop();
87 
88  // Pop a node. Returns NULL only if the queue was empty at some point after
89  // calling this function
90  Node* Pop();
91 
92  private:
95 };
96 
97 } // namespace grpc_core
98 
99 #endif /* GRPC_CORE_LIB_GPRPP_MPSCQ_H */
log.h
grpc_core::MultiProducerSingleConsumerQueue::Pop
Node * Pop()
Definition: mpscq.cc:37
opencensus.proto.agent.common.v1.common_pb2.Node
Node
Definition: common_pb2.py:308
grpc_core::MultiProducerSingleConsumerQueue::tail_
Node * tail_
Definition: mpscq.h:67
grpc_core::MultiProducerSingleConsumerQueue::MultiProducerSingleConsumerQueue
MultiProducerSingleConsumerQueue()
Definition: mpscq.h:42
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::MultiProducerSingleConsumerQueue::Node::next
std::atomic< Node * > next
Definition: mpscq.h:39
grpc_core::MultiProducerSingleConsumerQueue::padding_
char padding_[GPR_CACHELINE_SIZE]
Definition: mpscq.h:64
grpc_core::LockedMultiProducerSingleConsumerQueue
Definition: mpscq.h:73
grpc_core::MultiProducerSingleConsumerQueue
Definition: mpscq.h:35
grpc_core::LockedMultiProducerSingleConsumerQueue::queue_
MultiProducerSingleConsumerQueue queue_
Definition: mpscq.h:93
GPR_CACHELINE_SIZE
#define GPR_CACHELINE_SIZE
Definition: impl/codegen/port_platform.h:542
grpc_core::LockedMultiProducerSingleConsumerQueue::Push
bool Push(Node *node)
Definition: mpscq.cc:83
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_core::MultiProducerSingleConsumerQueue::Push
bool Push(Node *node)
Definition: mpscq.cc:29
grpc_core::MultiProducerSingleConsumerQueue::~MultiProducerSingleConsumerQueue
~MultiProducerSingleConsumerQueue()
Definition: mpscq.h:43
grpc_core::MultiProducerSingleConsumerQueue::head_
std::atomic< Node * > head_
Definition: mpscq.h:65
grpc_core::LockedMultiProducerSingleConsumerQueue::Node
MultiProducerSingleConsumerQueue::Node Node
Definition: mpscq.h:75
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
grpc_core::LockedMultiProducerSingleConsumerQueue::Pop
Node * Pop()
Definition: mpscq.cc:98
grpc_core::Mutex
Definition: src/core/lib/gprpp/sync.h:61
grpc_core::MultiProducerSingleConsumerQueue::stub_
Node stub_
Definition: mpscq.h:68
grpc_core::MultiProducerSingleConsumerQueue::PopAndCheckEnd
Node * PopAndCheckEnd(bool *empty)
Definition: mpscq.cc:43
grpc_core::MultiProducerSingleConsumerQueue::Node
Definition: mpscq.h:38
grpc_core::LockedMultiProducerSingleConsumerQueue::mu_
Mutex mu_
Definition: mpscq.h:94
sync.h
grpc_core::LockedMultiProducerSingleConsumerQueue::TryPop
Node * TryPop()
Definition: mpscq.cc:88
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:41