-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
External Memory for Pthread (IDFGH-9237) #10623
External Memory for Pthread (IDFGH-9237) #10623
Conversation
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 note that the stack and the TCB of a task allocated using xTaskCreateStaticPinnedToCore
are not deleted automatically. You also need to modify the pthread deletion code to free the memory, otherwise it would be leaked.
I've also left a few other comments below.
Also please combine the changes into a single commit (using |
externalmemory option. Update components/pthread/include/esp_pthread.h Co-authored-by: Ivan Grokhotkov <igrokhotkov@gmail.com> Update components/pthread/pthread.c Co-authored-by: Ivan Grokhotkov <igrokhotkov@gmail.com> MALLOC_CAP_DEFAULT as default "External ram" is probably not a very future-proof flag, since some chips might have more types of memory: TCM, internal slower memory, external faster memory, external slower memory, retention-capable memory. Using MALLOC_CAPS macros provides the same amount of flexibility as available in the heap allocation APIs. Need to add free(stack_for_task); here free(stack_for_task); free(taskTC); here as well You also need to modify the pthread deletion code to free the memory, otherwise it would be leaked. this should be done together with deleting pthread structure
857d61b
to
0e73e7a
Compare
like this ? |
This code fails with a assertion at thread.join(); |
no, still |
ah, but this time in the Idle Task. |
https://github.com/hr-agrartechnik/esp-idf-examples-cxx-pthread Crash on join() It is reproducible. |
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.
@f-hoepfinger-hr-agrartechnik Thanks for addressing the pthread external memory issue and sorry for the slow turnaround!
I looked at the code and most of it looks good. I have, however two points that I'm not certain about, please see the comments in the code.
We'll talk about the issue with the esp_pthread_set_cfg()
API (see my comments) and let you know about any results.
@@ -21,6 +21,7 @@ extern "C" { | |||
/** pthread configuration structure that influences pthread creation */ | |||
typedef struct { | |||
size_t stack_size; ///< The stack size of the pthread | |||
uint32_t stack_alloc_caps; ///< A bit mask of memory capabilities (MALLOC_CAPS*) to use when allocating the stack. If zero, MALLOC_CAP_DEFAULT is assumed. |
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'm afraid this might cause trouble for users who initialized each member of esp_pthread_cfg_t
manually like this:
esp_pthread_cfg_t cfg;
cfg.thread_name = name;
cfg.pin_to_core = core_id;
cfg.stack_size = stack;
cfg.prio = prio;
cfg.inherit_cfg = false;
If they would upgrade IDF including this change, esp_pthread_cfg_t.stack_alloc_caps
is uninitialized. Once the configuration is used, this would produce a crash at runtime at best or a way more subtle memory issue in the worst case.
I don't have a definitive solution for this yet. The esp_pthread_set_cfg
makes it hard to introduce non-breaking configuration changes.
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.
Sorry, I missed that our documentation is explicitly advising users to zero-initialize configuration structures. You can consider this comment resolved, then.
if (pthread->detached) { | ||
// auto-free for detached threads | ||
vTaskDelete(NULL); |
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.
What was the reason for moving vTaskDelete(NULL)
here? It seems that the semantics are changed significantly: the following two statements won't be executed, the log call and giving the semaphore below won't be executed, either.
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 take a look at pthread unit tests. They produce a deadlock, likely due to moving the vTaskDelete()
call here which prevents the mutex from being unlocked below (xSemaphoreGive(s_threads_mux);).
It looks like the freeRTOS forbidden to delete a full static(static task stack and TCB) task, so code has |
@f-hoepfinger-hr-agrartechnik could you elaborate "Crash on join()"? Given your change in IDF, I can compile the linked example application, modified so that it actually uses SPI RAM (external memory), and run it without error. The only prerequisites are enabling SPI RAM as well as allowing SPI RAM for FreeRTOS task stacks in menuconfig. I used an ESP32-WROVER Development board. |
@f-hoepfinger-hr-agrartechnik I think saving the stack memory in the struct I'll take a look at this and provide suggestions this week. |
Thanks so much. Very Helpful ! |
any news ? |
@f-hoepfinger-hr-agrartechnik We needed to go a long way because we needed to create new private FreeRTOS functions for this use case. We have merged the FreeRTOS part already. Now we're in the process of merging the final pthread MR. It will be quite different compared to your code, but we'll leave a thanks in the commit message for sure! |
@0xjakob any idea when we can test this ? |
@diplfranzhoepfinger It's been merged to master now, PTAL. There's a unit test which shows how to use the API. |
Very cool. Want to test it. |
#8662