-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
[WIP] lib: posix: auto allocate pthread stack if needed #26474
[WIP] lib: posix: auto allocate pthread stack if needed #26474
Conversation
Sorry for delay with looking into this. Trying to do this now. A few beginning comments:
|
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 guess first step here is to clean up terminology.
@@ -39,6 +39,36 @@ config SEM_VALUE_MAX | |||
help | |||
Maximum semaphore count in POSIX compliant Application. | |||
|
|||
config PTHREAD_DYNAMIC_STACK | |||
bool "Support for dynamic stacks" |
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.
Please spell it fully: "Support for dynamic thread stacks"
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.
To be honest, @pfalcon, I don't even think there should be a Kconfig for this. It's basically synonymous with "are we allowed to pass a NULL attr?" The spec explicitly says "yes" here. Maybe removing this would make it easier to solve the static / dynamic wording as well?
I guess the way you're leaning is that dynamic <=> heap-allocated, while static <=> statically allocated?
It would be nice to get @andrewboie 's input as well for naming.
config PTHREAD_DYNAMIC_STACK_SIZE | ||
int "Dynamic pthread stack size (in bytes)" | ||
default 2048 | ||
range 1 4096 |
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 don't think that "1" is realistic lower bound here. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstack.html) says:
The stacksize shall be at least {PTHREAD_STACK_MIN}.
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.
And yeah, why 4096 is upper bound?
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.
@pfalcon - the only reference I have in Zephyr for PTHREAD_STACK_MIN
is in tests/posix/eventfd/src/main.c
and it's only setting the min to 0 if it is undefined. Is there something analogous for Zephyr threads?
There is XT_STACK_MIN_SIZE
for xtensa only.
Correct me if I'm wrong, but it would seem that Kconfig does not allow us to set a min
attribute for int
options. Otherwise, I would happily use min NNNN
instead.
@andrewboie - any ideas?
Then of course it should proceed with specifics. For example, the descriptions here put emphasis on the case of All that leads to an obvious implementation, where one big chunk is pre-allocated, and stacks of different sizes are just sub-allocated from it. The description should explain why that path was not taken. 2nd thought is that all this static pre-allocation is useless, and instead, stacks should be just allocated from heap. Again, there should be description why that path is not taken, with links to prior art, etc. |
@pfalcon - that is, in fact, exactly what I added. /* statically allocated, dynamically assigned stacks */
static K_THREAD_STACK_ARRAY_DEFINE(dstack,
CONFIG_PTHREAD_DYNAMIC_STACK_RESERVED_COUNT,
CONFIG_PTHREAD_DYNAMIC_STACK_SIZE);
static pthread_attr_t dstack_attrs[CONFIG_PTHREAD_DYNAMIC_STACK_RESERVED_COUNT];
static uint32_t dstack_in_use;
When I originally wrote this change, there was no official way to dynamically allocate a thread stack. That also depended on C11 aligned_alloc(), which was added in ed258e9 by @andyross (btw, thanks Andy - C11 has some nice features!). For heap-allocated thread stacks, @andrewboie has a bit of work to do, but heap-allocated thread stacks should be possible soon. With all that being said, there are only 2 reasons why I would consider statically-allocated (but dynamically assignable) thread stacks to be useful even with the availability of heap-allocated stacks:
However, I am quite open to modifying the PR to go entirely heap-allocated when |
Then I miss that, because what I see is that you added preallocation of COUNT stack of fixed SIZE. Not, again, ability to allocate variable-sized stacks from common pool. If you did that on top of COUNT x SIZE thingy, then it's quite an advanced exploit of great Zephyr capabilities, which is again should be explained in the commit message. (I admit that that I didn't review the entire patchset closely, stopping when I figured that I get consistently misguided by the word DYNAMIC, and suggesting to work out terminology first). |
I'm not concerned with variably-sized stacks at this time (it's a feature that could be supported later), but I think that would require heap-allocated stacks to work. |
Sounds good. But between the lines, the whole thing reads "these extravagant workarounds are added because Zephyr can't do otherwise", and I'd prefer to spell it out (if that holds), instead of "everybody knows that, but doesn't talk about it". |
Again, my concern is that we're adding workarounds here, instead of working towards more general solution (just mind that "important thread which may need to run anytime" usecase is already served with explicitly specified stack addr/size). I wanted to spell out that concern explicitly. If you think that's reasonable approach to do it so piecewise, well, ok. I don't have problems with incremental solutions. |
This change allows users to pre-allocate a configurable number of POSIX thread stacks via Kconfig. It also facilitates a future implementation where stacks may be heap-allocated on demand or a hybrid approach. Of course, user-allocated stacks continue to work as usual. Thus, allowing both a NULL and non-NULL pthread_attr_t to be supplied to pthread_create(3) and being more standards-compliant. Fixes #25973 Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
Tests for the previous commit. Fixes #25973 Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
Actually, if using C++, then the "important thread which may need to run anytime" usecase is not served, as there is no language specification to be able to supply a stack - regardless of whether Zephyr threads or pthreads are being used. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
This change aims to facilitate heap-allocated Zephyr thread stacks, and by extension, heap-allocated pthread stacks. Specifically, it allows the following API call to be made with
attr == NULL
.It looks relatively simple to implement. However, the main complication is that threads often abort themselves, which results in all sorts of errors - mmu, mpu, usage faults, etc.
It's possible that the best way to fix that is to append the heap-allocated thread stacks of all threads to a list, and then
k_free()
them from the idle thread - preferably after the idle thread terminates any terminated threads.Fixes #25973