Skip to content
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

Conversation

f-hoepfinger-hr-agrartechnik
Copy link
Contributor

@CLAassistant
Copy link

CLAassistant commented Jan 26, 2023

CLA assistant check
All committers have signed the CLA.

@espressif-bot espressif-bot added the Status: Opened Issue is new label Jan 26, 2023
@github-actions github-actions bot changed the title External Memory for Pthread External Memory for Pthread (IDFGH-9237) Jan 26, 2023
@f-hoepfinger-hr-agrartechnik f-hoepfinger-hr-agrartechnik marked this pull request as ready for review January 26, 2023 16:47
Copy link
Member

@igrr igrr left a 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.

@igrr
Copy link
Member

igrr commented Jan 27, 2023

Also please combine the changes into a single commit (using git rebase -i) to keep the commit history clean.

@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development and removed Status: Opened Issue is new labels Feb 1, 2023
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
@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

Also please combine the changes into a single commit (using git rebase -i) to keep the commit history clean.

like this ?

@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

This code fails with a assertion at thread.join();

@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

no, still
assert failed: prvDeleteTCB tasks.c:4758 (pxTCB->ucStaticallyAllocated == ( ( uint8_t ) 2 ))

@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

no, still assert failed: prvDeleteTCB tasks.c:4758 (pxTCB->ucStaticallyAllocated == ( ( uint8_t ) 2 ))

ah, but this time in the Idle Task.
need more Help.

@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

https://github.com/hr-agrartechnik/esp-idf-examples-cxx-pthread

Crash on join()

It is reproducible.
So need to debug on this minimal example.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Selected for Development Issue is selected for development labels May 8, 2023
Copy link
Contributor

@0xjakob 0xjakob left a 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.
Copy link
Contributor

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.

Copy link
Contributor

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);
Copy link
Contributor

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.

Copy link
Contributor

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);).

@donghengqaz
Copy link
Collaborator

no, still assert failed: prvDeleteTCB tasks.c:4758 (pxTCB->ucStaticallyAllocated == ( ( uint8_t ) 2 ))

It looks like the freeRTOS forbidden to delete a full static(static task stack and TCB) task, so code has assert process. @f-hoepfinger-hr-agrartechnik @0xjakob using xTaskCreateRestrictedStatic may be solution here.

@0xjakob
Copy link
Contributor

0xjakob commented May 8, 2023

https://github.com/hr-agrartechnik/esp-idf-examples-cxx-pthread

Crash on join()

It is reproducible. So need to debug on this minimal example.

@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.

@0xjakob
Copy link
Contributor

0xjakob commented May 9, 2023

@f-hoepfinger-hr-agrartechnik I think saving the stack memory in the struct esp_pthread_t does not work since the deletion must be deferred if the thread is deleting itself, this might be the cause of some of the issues you observed. The best way to defer stack deletion seems to be via vPortCleanUpTCB(), which needs to be enabled and provided.

I'll take a look at this and provide suggestions this week.

@diplfranzhoepfinger
Copy link
Contributor

I'll take a look at this and provide suggestions this week.

Thanks so much. Very Helpful !

@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development and removed Status: In Progress Work is in progress labels Oct 27, 2023
@espressif-bot espressif-bot added the Status: Reviewing Issue is being reviewed label Nov 6, 2023
@espressif-bot espressif-bot removed the Status: Selected for Development Issue is selected for development label Nov 6, 2023
@f-hoepfinger-hr-agrartechnik
Copy link
Contributor Author

I'll take a look at this and provide suggestions this week.

any news ?

@0xjakob
Copy link
Contributor

0xjakob commented Dec 15, 2023

@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!

@diplfranzhoepfinger
Copy link
Contributor

@0xjakob any idea when we can test this ?

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Reviewing Issue is being reviewed labels Jan 23, 2024
@0xjakob
Copy link
Contributor

0xjakob commented Feb 1, 2024

@diplfranzhoepfinger It's been merged to master now, PTAL. There's a unit test which shows how to use the API.

@diplfranzhoepfinger
Copy link
Contributor

Very cool. Want to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants