-
Notifications
You must be signed in to change notification settings - Fork 2.1k
unittests/unicoap: statically allocate option buffers #21610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unittests/unicoap: statically allocate option buffers #21610
Conversation
the default unittest stacksize is set to THREAD_STACKSIZE_LARGE which is 2048 for cortexm_common
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this was my mistake.
For anyone else wondering: The size of the options buffer allocated should be slightly (well, maybe not by 1.3 KB) larger than needed so tests where unicoap
writes too much into buffer can fail gracefully instead of memfaulting immediately.
As a quick fix for making the tests run, modifying the buffer size is the right thing to do. |
Should I adapt the PR to provide that macro instead? Much cleaner solution indeed. |
Okay, then we have two options: // 1
UNICOAP_OPTIONS_ALLOC_STATIC(my_options, 100);
// or
// 2
UNICOAP_OPTIONS_ALLOC(my_options, 100, static); I think I would prefer 2 over 1. |
I'd prefer 1, but that's probably more personal taste. |
@@ -193,7 +193,21 @@ static inline void unicoap_options_clear(unicoap_options_t* options) | |||
* the given capacity, then calls @ref unicoap_options_t::unicoap_options_init. | |||
*/ | |||
#define UNICOAP_OPTIONS_ALLOC(name, capacity) \ | |||
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity) | |||
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity,) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity,) | |
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity) |
I guess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, in that case we don't want to emit anything before the type (aka, no static
).
sys/include/net/unicoap/options.h
Outdated
unicoap_options_t _name; \ | ||
# define _UNICOAP_OPTIONS_ALLOC(_buf, _name, capacity, _static) \ | ||
_static uint8_t _buf[capacity]; \ | ||
unicoap_options_t _name; \ | ||
unicoap_options_init(&_name, _buf, capacity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1, I think the static version should work on the root level of a translation unit, too. So I fear we have to replace unicoap_options_init
with unicoap_options_t _name = { .entries->data = _buf, .storage_capacity = capacity };
3, And why wouldn't we want to statically allocate the unicoap_options_t
, too? Is there a good reason not to? It would make sense because of the lookup array in the options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Good point, adapted it accordingly. Note that I do the same for both
_STATIC
and non-static, with the slight difference that more memory will be zero-initialized for the non-static version compared to using theunicoap_options_init
function. But it keeps the macros in sync. -
Sure, would make sense, especially if used outside of functions. Adapted.
I've also added |
maybe you could update the pr description to reflect the change |
Done. |
Sorry, had forgotten to push 🙈 please tell me when to squash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I somewhat wonder if the macros are worth the hassle...
Yes squash please |
dd80c05
to
64352cb
Compare
@carl-tud is your review done? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks.
Please run |
@crasbe would you mind checking for the necessary |
Already on it :) |
buechse@skyleaf:~/RIOTstuff/riot-unicoap/RIOT/tests/unittests$ git diff Makefile.ci
diff --git a/tests/unittests/Makefile.ci b/tests/unittests/Makefile.ci
index 3490841797..6e9fdfedef 100644
--- a/tests/unittests/Makefile.ci
+++ b/tests/unittests/Makefile.ci
@@ -79,6 +79,7 @@ BOARD_INSUFFICIENT_MEMORY := \
pba-d-01-kw2x \
remote-pa \
remote-reva \
+ remote-revb \
samd10-xmini \
samd20-xpro \
samd21-xpro \ |
So annoying that it failed at the last minute... |
64352cb
to
8623772
Compare
Should run through now 🙏 |
Backport provided in #21622 |
Contribution description
unicoap unittests would currently fail due to stack overflow on most hardware. They indeed allocate much more memory than needed.
The default unittest stacksize is set to THREAD_STACKSIZE_LARGE which is 2048 for cortexm_common, so 900 bytes will largely fit. However, some other architectures (e.g., atmega8) define much smaller stack sizes per default, where the reduced buffer would not fit. Should we rather make them static so they work for all architectures? We then wouldn't be able to use the convenience macro anymore.
EDIT: Changed to statically allocated buffers now using a new convenience macro
UNICOAP_OPTIONS_ALLOC_STATIC
.Testing procedure
make -C tests/unittests BOARD=nrf52840dk tests-unicoap flash term
on
master
:with this PR:
Issues/PRs references
Found while testing #21582