|
|
|
@ -16,15 +16,15 @@ |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifndef GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H |
|
|
|
|
#define GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H |
|
|
|
|
#ifndef GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H |
|
|
|
|
#define GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
#include <grpc/support/time.h> |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include "src/core/lib/gprpp/atomic.h" |
|
|
|
|
#include "src/core/lib/gprpp/sync.h" |
|
|
|
|
#include <grpc/support/time.h> |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
@ -36,7 +36,7 @@ class MPMCQueueInterface { |
|
|
|
|
|
|
|
|
|
// Put elem into queue immediately at the end of queue.
|
|
|
|
|
// This might cause to block on full queue depending on implementation.
|
|
|
|
|
virtual void Put(void *elem) = 0; |
|
|
|
|
virtual void Put(void* elem) = 0; |
|
|
|
|
|
|
|
|
|
// Remove the oldest element from the queue and return it.
|
|
|
|
|
// This might cause to block on empty queue depending on implementation.
|
|
|
|
@ -48,16 +48,16 @@ class MPMCQueueInterface { |
|
|
|
|
|
|
|
|
|
class MPMCQueue : public MPMCQueueInterface { |
|
|
|
|
public: |
|
|
|
|
struct Stats { // Stats of queue
|
|
|
|
|
uint64_t num_started; // Number of elements have been added to queue
|
|
|
|
|
uint64_t num_completed; // Number of elements have been removed from
|
|
|
|
|
// the queue
|
|
|
|
|
gpr_timespec total_queue_cycles; // Total waiting time that all the
|
|
|
|
|
// removed elements have spent in queue
|
|
|
|
|
gpr_timespec max_queue_cycles; // Max waiting time among all removed
|
|
|
|
|
// elements
|
|
|
|
|
gpr_timespec busy_time_cycles; // Accumulated amount of time that queue
|
|
|
|
|
// was not empty
|
|
|
|
|
struct Stats { // Stats of queue
|
|
|
|
|
uint64_t num_started; // Number of elements have been added to queue
|
|
|
|
|
uint64_t num_completed; // Number of elements have been removed from
|
|
|
|
|
// the queue
|
|
|
|
|
gpr_timespec total_queue_cycles; // Total waiting time that all the
|
|
|
|
|
// removed elements have spent in queue
|
|
|
|
|
gpr_timespec max_queue_cycles; // Max waiting time among all removed
|
|
|
|
|
// elements
|
|
|
|
|
gpr_timespec busy_time_cycles; // Accumulated amount of time that queue
|
|
|
|
|
// was not empty
|
|
|
|
|
|
|
|
|
|
Stats() { |
|
|
|
|
num_started = 0; |
|
|
|
@ -66,23 +66,7 @@ class MPMCQueue : public MPMCQueueInterface { |
|
|
|
|
max_queue_cycles = gpr_time_0(GPR_TIMESPAN); |
|
|
|
|
busy_time_cycles = gpr_time_0(GPR_TIMESPAN); |
|
|
|
|
} |
|
|
|
|
void* operator new(size_t n) { |
|
|
|
|
void* p = gpr_malloc(n); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void operator delete(void* p) { |
|
|
|
|
gpr_free(p); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
void* operator new(size_t n) { |
|
|
|
|
void* p = gpr_malloc(n); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void operator delete(void* p) { |
|
|
|
|
gpr_free(p); |
|
|
|
|
} |
|
|
|
|
// Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created
|
|
|
|
|
// will have infinite length.
|
|
|
|
|
explicit MPMCQueue(); |
|
|
|
@ -115,34 +99,26 @@ class MPMCQueue : public MPMCQueueInterface { |
|
|
|
|
void* PopFront(); |
|
|
|
|
|
|
|
|
|
struct Node { |
|
|
|
|
Node *next; // Linking
|
|
|
|
|
void *content; // Points to actual element
|
|
|
|
|
gpr_timespec insert_time; // Time for stats
|
|
|
|
|
Node* next; // Linking
|
|
|
|
|
void* content; // Points to actual element
|
|
|
|
|
gpr_timespec insert_time; // Time for stats
|
|
|
|
|
Node(void* c) : content(c) { |
|
|
|
|
next = nullptr; |
|
|
|
|
insert_time = gpr_now(GPR_CLOCK_PRECISE); |
|
|
|
|
} |
|
|
|
|
void* operator new(size_t n) { |
|
|
|
|
void* p = gpr_malloc(n); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void operator delete(void* p) { |
|
|
|
|
gpr_free(p); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Mutex mu_; // Protecting lock
|
|
|
|
|
CondVar wait_nonempty_; // Wait on empty queue on get
|
|
|
|
|
int num_waiters_; // Number of waiters
|
|
|
|
|
Mutex mu_; // Protecting lock
|
|
|
|
|
CondVar wait_nonempty_; // Wait on empty queue on get
|
|
|
|
|
int num_waiters_; // Number of waiters
|
|
|
|
|
|
|
|
|
|
Node *queue_head_; // Head of the queue, remove position
|
|
|
|
|
Node *queue_tail_; // End of queue, insert position
|
|
|
|
|
Atomic<uint64_t> count_; // Number of elements in queue
|
|
|
|
|
Stats stats_; // Stats info
|
|
|
|
|
gpr_timespec busy_time; // Start time of busy queue
|
|
|
|
|
Node* queue_head_; // Head of the queue, remove position
|
|
|
|
|
Node* queue_tail_; // End of queue, insert position
|
|
|
|
|
Atomic<uint64_t> count_; // Number of elements in queue
|
|
|
|
|
Stats stats_; // Stats info
|
|
|
|
|
gpr_timespec busy_time; // Start time of busy queue
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} // namespace grpc_core
|
|
|
|
|
|
|
|
|
|
#endif /* GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H */ |
|
|
|
|
#endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H */ |
|
|
|
|