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]

  • [PR] libs/libc: Free the __th... casaroli (via GitHub) via commits

Reply via email to