Add a sent too fast check for simulation and shm
Returns an error if more than queue_size (frequency *
channel_storage_duration) messages were sent in one
channel_storage_duration.
Signed-off-by: Eric Schmiedeberg <eric.schmiedeberg@bluerivertech.com>
Change-Id: Ie41205ba37b66930d8a9082f2d85d7dc3388e3bf
diff --git a/aos/ipc_lib/lockless_queue.h b/aos/ipc_lib/lockless_queue.h
index d6fb72f..f7a85c3 100644
--- a/aos/ipc_lib/lockless_queue.h
+++ b/aos/ipc_lib/lockless_queue.h
@@ -282,10 +282,19 @@
// scoped to this object's lifetime.
class LocklessQueueSender {
public:
+ // Enum of possible sending errors
+ // Send returns GOOD if the messages was sent successfully, INVALID_REDZONE if
+ // one of a message's redzones has invalid data, or MESSAGES_SENT_TOO_FAST if
+ // more than queue_size messages were going to be sent in a
+ // channel_storage_duration_.
+ enum class Result { GOOD, INVALID_REDZONE, MESSAGES_SENT_TOO_FAST };
+
LocklessQueueSender(const LocklessQueueSender &) = delete;
LocklessQueueSender &operator=(const LocklessQueueSender &) = delete;
LocklessQueueSender(LocklessQueueSender &&other)
- : memory_(other.memory_), sender_index_(other.sender_index_) {
+ : memory_(other.memory_),
+ sender_index_(other.sender_index_),
+ channel_storage_duration_(other.channel_storage_duration_) {
other.memory_ = nullptr;
other.sender_index_ = -1;
}
@@ -299,7 +308,8 @@
// Creates a sender. If we couldn't allocate a sender, returns nullopt.
// TODO(austin): Change the API if we find ourselves with more errors.
- static std::optional<LocklessQueueSender> Make(LocklessQueue queue);
+ static std::optional<LocklessQueueSender> Make(
+ LocklessQueue queue, monotonic_clock::duration channel_storage_duration);
// Sends a message without copying the data.
// Copy at most size() bytes of data into the memory pointed to by Data(),
@@ -307,34 +317,43 @@
// Note: calls to Data() are expensive enough that you should cache it.
size_t size() const;
void *Data();
- bool Send(size_t length, monotonic_clock::time_point monotonic_remote_time,
- realtime_clock::time_point realtime_remote_time,
- uint32_t remote_queue_index, const UUID &source_boot_uuid,
- monotonic_clock::time_point *monotonic_sent_time = nullptr,
- realtime_clock::time_point *realtime_sent_time = nullptr,
- uint32_t *queue_index = nullptr);
+ LocklessQueueSender::Result Send(
+ size_t length, monotonic_clock::time_point monotonic_remote_time,
+ realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index, const UUID &source_boot_uuid,
+ monotonic_clock::time_point *monotonic_sent_time = nullptr,
+ realtime_clock::time_point *realtime_sent_time = nullptr,
+ uint32_t *queue_index = nullptr);
// Sends up to length data. Does not wakeup the target.
- bool Send(const char *data, size_t length,
- monotonic_clock::time_point monotonic_remote_time,
- realtime_clock::time_point realtime_remote_time,
- uint32_t remote_queue_index, const UUID &source_boot_uuid,
- monotonic_clock::time_point *monotonic_sent_time = nullptr,
- realtime_clock::time_point *realtime_sent_time = nullptr,
- uint32_t *queue_index = nullptr);
+ LocklessQueueSender::Result Send(
+ const char *data, size_t length,
+ monotonic_clock::time_point monotonic_remote_time,
+ realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index, const UUID &source_boot_uuid,
+ monotonic_clock::time_point *monotonic_sent_time = nullptr,
+ realtime_clock::time_point *realtime_sent_time = nullptr,
+ uint32_t *queue_index = nullptr);
int buffer_index() const;
private:
- LocklessQueueSender(LocklessQueueMemory *memory);
+ LocklessQueueSender(LocklessQueueMemory *memory,
+ monotonic_clock::duration channel_storage_duration);
// Pointer to the backing memory.
LocklessQueueMemory *memory_ = nullptr;
// Index into the sender list.
int sender_index_ = -1;
+
+ // Storage duration of the channel used to check if messages were sent too
+ // fast
+ const monotonic_clock::duration channel_storage_duration_;
};
+std::ostream &operator<<(std::ostream &os, const LocklessQueueSender::Result r);
+
// Pinner for blocks of data. The resources associated with a pinner are
// scoped to this object's lifetime.
class LocklessQueuePinner {