Skip to content

Commit

Permalink
Object lookup map: Replace slist with own implementation
Browse files Browse the repository at this point in the history
The Zephyr slist implementation did not work on hardware under some
circumstances. The root cause could not be fully identified. It may
have to do with memory alignment or placement of the sys_snode_t at
the end of the struct instead of at the beginning.

This commit replaces the Zephyr linked list with a bespoke
implementation for the ThingSet objects database.
  • Loading branch information
martinjaeger committed May 8, 2024
1 parent d3338c7 commit 7c384ab
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
6 changes: 3 additions & 3 deletions include/thingset.h
Original file line number Diff line number Diff line change
Expand Up @@ -1546,9 +1546,9 @@ struct thingset_data_object

#ifdef CONFIG_THINGSET_OBJECT_LOOKUP_MAP
/**
* Pointer to next node in list for map lookup
* Pointer to next node in the bucket for map lookup
*/
sys_snode_t node;
struct thingset_data_object *bucket_next;
#endif /* CONFIG_THINGSET_OBJECT_LOOKUP_MAP */
};

Expand Down Expand Up @@ -1584,7 +1584,7 @@ struct thingset_context
/**
* Array of linked lists: map for object ID lookup
*/
sys_slist_t data_objects_lookup[CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS];
struct thingset_data_object *data_objects_lookup[CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS];
#endif

/**
Expand Down
26 changes: 16 additions & 10 deletions src/thingset.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,20 @@ static void thingset_init_common(struct thingset_context *ts)
{
#ifdef CONFIG_THINGSET_OBJECT_LOOKUP_MAP
for (unsigned int b = 0; b < CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS; b++) {
sys_slist_init(&ts->data_objects_lookup[b]);
ts->data_objects_lookup[b] = NULL;
}

for (unsigned int i = 0; i < ts->num_objects; i++) {
struct thingset_data_object *object = &ts->data_objects[i];
sys_slist_append(
&ts->data_objects_lookup[object->id % CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS],
&object->node);
/* in case the objects were not declared static and thus not properly null-initialized */
object->bucket_next = NULL;

size_t bucket = object->id % CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS;
struct thingset_data_object **last = &ts->data_objects_lookup[bucket];
while (*last != NULL) {
last = &(*last)->bucket_next;
}
*last = object;
}
#endif
ts->auth_flags = THINGSET_USR_MASK;
Expand Down Expand Up @@ -549,15 +555,15 @@ struct thingset_data_object *thingset_get_child_by_name(struct thingset_context
struct thingset_data_object *thingset_get_object_by_id(struct thingset_context *ts, uint16_t id)
{
#ifdef CONFIG_THINGSET_OBJECT_LOOKUP_MAP
sys_slist_t *list = &ts->data_objects_lookup[id % CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS];
sys_snode_t *pnode;
struct thingset_data_object *object;
SYS_SLIST_FOR_EACH_NODE(list, pnode)
{
object = CONTAINER_OF(pnode, struct thingset_data_object, node);
struct thingset_data_object *object =
ts->data_objects_lookup[id % CONFIG_THINGSET_OBJECT_LOOKUP_BUCKETS];
while (object != NULL) {
if (object->id == id) {
return object;
}
else {
object = object->bucket_next;
}
}
#else
for (unsigned int i = 0; i < ts->num_objects; i++) {
Expand Down

0 comments on commit 7c384ab

Please sign in to comment.