Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions canard/handler_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#define CANARD_NUM_HANDLERS 3
#endif

/*
the number of buckets helps reduce CPU usage when there are many handlers
*/
#ifndef CANARD_NUM_RX_BUCKETS
#define CANARD_NUM_RX_BUCKETS 8U
#endif

namespace Canard {

/// @brief HandlerList to register all handled message types.
Expand Down Expand Up @@ -62,7 +69,7 @@ class HandlerList {
#ifdef WITH_SEMAPHORE
WITH_SEMAPHORE(sem[index]);
#endif
HandlerList* entry = head[index];
HandlerList* entry = head[index][msgid % CANARD_NUM_RX_BUCKETS];
while (entry != nullptr) {
if (entry->msgid == msgid && entry->transfer_type == transfer_type) {
signature = entry->signature;
Expand All @@ -81,7 +88,7 @@ class HandlerList {
#ifdef WITH_SEMAPHORE
WITH_SEMAPHORE(sem[index]);
#endif
HandlerList* entry = head[index];
HandlerList* entry = head[index][transfer.data_type_id % CANARD_NUM_RX_BUCKETS];
while (entry != nullptr) {
if (transfer.data_type_id == entry->msgid &&
entry->transfer_type == transfer.transfer_type) {
Expand Down Expand Up @@ -113,18 +120,18 @@ class HandlerList {
#ifdef WITH_SEMAPHORE
WITH_SEMAPHORE(sem[index]);
#endif
next = head[index];
head[index] = this;
next = head[index][msgid % CANARD_NUM_RX_BUCKETS];
head[index][msgid % CANARD_NUM_RX_BUCKETS] = this;
}

// remove ourselves from the handler list
void unlink(void) NOINLINE_FUNC {
#ifdef WITH_SEMAPHORE
WITH_SEMAPHORE(sem[index]);
#endif
HandlerList* entry = head[index];
HandlerList* entry = head[index][msgid % CANARD_NUM_RX_BUCKETS];
if (entry == this) {
head[index] = next;
head[index][msgid % CANARD_NUM_RX_BUCKETS] = next;
return;
}
while (entry != nullptr) {
Expand All @@ -137,13 +144,13 @@ class HandlerList {
}

private:
static HandlerList* head[CANARD_NUM_HANDLERS];
static HandlerList* head[CANARD_NUM_HANDLERS][CANARD_NUM_RX_BUCKETS];
uint16_t msgid;
uint64_t signature;
CanardTransferType transfer_type;
};

} // namespace Canard

#define DEFINE_HANDLER_LIST_HEADS() Canard::HandlerList* Canard::HandlerList::head[CANARD_NUM_HANDLERS] = {}
#define DEFINE_HANDLER_LIST_HEADS() Canard::HandlerList* Canard::HandlerList::head[CANARD_NUM_HANDLERS][CANARD_NUM_RX_BUCKETS] = {}
#define DEFINE_HANDLER_LIST_SEMAPHORES() Canard::Semaphore Canard::HandlerList::sem[CANARD_NUM_HANDLERS] = {}