casaroli opened a new pull request, #21470: URL: https://github.com/apache/nuttx/pull/21470
depends-on: apache/nuttx/pull/20723 This branch holds the commits of #20723 and one commit of its own (plus its documentation line), because that commit changes the libc emutls code that #20723 adds. Please review only the last two commits. ## Summary A module or shared library with `__thread` variables took a new emutls index each time it was loaded, and the copies of its variables stayed in each thread until the thread exited. A module that is loaded and unloaded again and again made the arrays of all threads grow. libc now keeps the control object of each index and a list of the arrays of all threads. When a module goes, `libelf_uninit()` calls `lib_emutls_release()` with the data range of the module. libc frees the copies of those variables in every thread and gives their indexes back; a new variable takes the first free index. libc calls it through a pointer that it sets when it gives the first index, so the loader does not link the code. The documentation commit adds one sentence to the TLS guide: a copy is also freed, in every thread, when the module that defines the variable is unloaded. ## Impact - Builds with `CONFIG_TLS_EMUTLS` and module loading: the copies of an unloaded module's `__thread` variables are freed, and their indexes reused. Before, each load took a new index and the old copies stayed until the threads exited. - A program that never unloads a module links nothing new (the loader calls the code through a pointer libc sets on the first index). - No ABI change. Not a breaking change. ## Testing Test program `tlsload.c`: a thread loads and unloads a module with a `__thread` variable 300 times, with `dlopen()`, and checks the value of the variable after each load. Two threads then do the same 300 times each, and the main thread 300 times more. `mallinfo()` gives the heap in use after each step. The test passes when the value is right and the heap in use after the last step has not grown by more than 1 KiB. qemu-armv8a:nsh (flat, HVF), `CONFIG_TLS_NELEM` 4, master 6b9b216ff30: | Heap in use (bytes) | #20723 | #20723 and this PR | |---|---|---| | after the first 300 loads | 89888 | 77856 | | after 2 x 300 loads in two threads | 89888 | 77856 | | after 300 more loads | 106720 | 77856 | | result | FAIL | PASS | The value of the variable was right in all loads in both columns. The test does not cover `exec()` of a module, or a build with more than one CPU. qemu-armv8a:knsh (HVF), with #20723: `tlsgroup.c` and `tlsmany.c` PASS, ostest exits with status 0. Builds with `EXTRAFLAGS="-Wno-cpp -Werror"`, each OK and with `tls_emutls.c` compiled: qemu-armv8a:knsh, qemu-armv8a:nsh, mps2-an500:knsh. `tools/checkpatch.sh -c -u -m -g` passes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
