Hi, Anthony,
I just found an issue with using libcxx std::thread library on NuttX. The
std::thread implementation uses pthread_key_create and pthread_setspecific
in order to setup a destructor that should be called to cleanup the memory.
Of course, it became pretty obvious what was wrong once I read the
following comment for pthread_key_create
* Input Parameters:
* key - A pointer to the key to create.
* destructor - An optional destructor() function that may be associated
* with each key that is invoked when a thread exits.
*
*However, this argument is ignored in the current** *
implementation.*
From
https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/ptkycre.htm
The destructor routine may be called when the thread ends. It is called
when a non-NULL value has been set for the key for this thread, using
pthread_setspecific(), and the thread:
- Calls pthread_exit()
- Does a return from the start routine
- Is canceled because of a pthread_cancel() request.
So it seems that the implementation would require the destructor to be
called from pthread_exit and pthread_cancel.
However, I'm still uncertain where in the order of operations the
destructor should be called. Before or after pthread_completejoin? Before
or after pthread_mutex_inconsistent?
Looking for some guidance before I start working on a fix.
A complication is that the destructor must run in user-mode in the
user-address space. pthread_exit() runs entirely in kernel mode in the
kernel address space. This is not a critical critical for the FLAT
build since everything runs in a flat address space and everything runs
in kernel mode. But this is a probleml for the PROTECTED and KERNEL
builds. Having the destructor running is kernel mode would be a major
security hole.
The same is true of pthread_cleanup() routines and the some solution
would be required. See issue # 1263,
https://github.com/apache/incubator-nuttx/issues/1263. That solution
would involve:
1. Add the pthread destructor functions to the TLS data structure, and
2. Move a portion of the pthread_cleanup logic into libs/libc/pthread:
That portion would do the pthread_cleanup callbacks and the
pthread-specific data desctructor calls while still in user mode. Then
trap into the kernel complete the find stages of the pthread exit logic.
Greg