casaroli opened a new pull request, #21146:
URL: https://github.com/apache/nuttx/pull/21146

   ## Summary
   
   This PR makes the POSIX option macros of `<unistd.h>` and some limits of 
`<limits.h>` tell the truth about the configuration, and makes key destructors 
repeat as POSIX requires.
   
   - **include/unistd.h: Make the POSIX option macros follow the 
configuration.** `<unistd.h>` defined `_POSIX_SEMAPHORES`, 
`_POSIX_SHARED_MEMORY_OBJECTS`, `_POSIX_MAPPED_FILES`, 
`_POSIX_MESSAGE_PASSING`, `_POSIX_THREADS`, `_POSIX_THREAD_PROCESS_SHARED`, 
`_POSIX_CPUTIME` and `_POSIX_THREAD_CPUTIME` in every configuration. A program 
that tests them then used functions that the build does not have: `sem_open()` 
needs `CONFIG_FS_NAMED_SEMAPHORES`, `shm_open()` needs `CONFIG_FS_SHMFS`, 
`mmap()` of a regular file needs `CONFIG_FS_RAMMAP`, and the CPU-time clocks 
need the run-time accounting of `CONFIG_SCHED_CRITMONITOR`. It did not define 
`_POSIX_BARRIERS`, `_POSIX_READER_WRITER_LOCKS`, `_POSIX_SPIN_LOCKS` and 
`_POSIX_THREAD_ATTR_STACKADDR`, although the functions exist. Now each option 
is `_POSIX_VERSION` when the configuration has it, and -1 when it does not. A 
kernel build has process-shared mutexes only with memory that two processes can 
share (`CONFIG_FS_SHMFS` or `CONFIG_MM_SHM`). T
 he empty `_POSIX_THREADS` and `_POSIX_THREAD_ATTR_STACKSIZE` fallbacks in 
`<pthread.h>` go (`<pthread.h>` includes `<unistd.h>` first, so they never took 
effect).
   - **Documentation/standards: Name the options that POSIX option macros 
need.** `posix.rst` gives the Kconfig option of each of these macros.
   - **include/limits.h: Define _POSIX_THREAD_KEYS_MAX as the POSIX constant.** 
`_POSIX_THREAD_KEYS_MAX` is the smallest `PTHREAD_KEYS_MAX` that POSIX allows, 
always 128. `<limits.h>` defined it from `CONFIG_TLS_NELEM` (0 by default). Now 
it is 128; `PTHREAD_KEYS_MAX` still follows `CONFIG_TLS_NELEM`, and the Kconfig 
help says that POSIX requires at least 128 keys and what each key costs.
   - **libs/libc/tls: Repeat the key destructors as POSIX requires.** 
`tls_destruct()` called each key destructor once and cleared the value after 
the call, so a value that a destructor set again was lost. Now the value is 
cleared before the call, and the pass repeats while a destructor ran, up to 
`PTHREAD_DESTRUCTOR_ITERATIONS` (4, the POSIX minimum, new in `<limits.h>`) 
times.
   - **include/limits.h: Define LOGIN_NAME_MAX.** POSIX requires it. It is 
`NAME_MAX + 1` (`getlogin()` returns at most `NAME_MAX` bytes), and the 
`getlogin()` buffer uses it.
   - **Documentation: Describe the destructors of pthread keys.** 
`08_pthread.rst` said that the destructor argument of `pthread_key_create()` is 
ignored.
   
   ## Impact
   
   Possible breaking change (source level, every build mode, flat too): the 
values of these option macros change. An option that the configuration does not 
have is now -1:
   
   | Macro | -1 when |
   |---|---|
   | `_POSIX_SEMAPHORES` | no `CONFIG_FS_NAMED_SEMAPHORES` |
   | `_POSIX_SHARED_MEMORY_OBJECTS` | no `CONFIG_FS_SHMFS` |
   | `_POSIX_MAPPED_FILES` | no `CONFIG_FS_RAMMAP` |
   | `_POSIX_CPUTIME`, `_POSIX_THREAD_CPUTIME` | no `CONFIG_SCHED_CRITMONITOR` |
   | `_POSIX_MESSAGE_PASSING` | `CONFIG_DISABLE_MQUEUE` |
   | `_POSIX_SPIN_LOCKS` (new) | no `CONFIG_PTHREAD_SPINLOCKS` |
   | `_POSIX_THREAD_PROCESS_SHARED` | kernel build without `CONFIG_FS_SHMFS` 
and `CONFIG_MM_SHM` |
   | `_POSIX_THREADS`, `_POSIX_THREAD_PRIORITY_SCHEDULING`, 
`_POSIX_THREAD_ATTR_STACKADDR` (new), `_POSIX_THREAD_ATTR_STACKSIZE`, 
`_POSIX_BARRIERS` (new), `_POSIX_READER_WRITER_LOCKS` (new) | 
`CONFIG_DISABLE_PTHREAD` |
   
   A program that only tests `#ifdef` sees no difference. A program that tests 
the value (`#if _POSIX_SEMAPHORES > 0`) now takes its fallback when the 
function is missing; before, it did not link or failed at run time. 
`sysconf(_SC_CPUTIME)` and `sysconf(_SC_THREAD_CPUTIME)` return -1 without 
`CONFIG_SCHED_CRITMONITOR` (before: 201712L, while `clock_gettime()` of these 
clocks failed with `EINVAL`).
   
   In-tree users: no C code in nuttx or nuttx-apps tests these macros. 
`lib_sysconf.c` returns `_POSIX_CPUTIME`/`_POSIX_THREAD_CPUTIME` (see above). 
The lely-canopen patch in nuttx-apps already excludes NuttX from its 
`_POSIX_MAPPED_FILES` paths. `getlogin()` keeps its buffer size.
   
   `<limits.h>`: `_POSIX_THREAD_KEYS_MAX` is 128 in every configuration (was 
`CONFIG_TLS_NELEM`); `LOGIN_NAME_MAX` and `PTHREAD_DESTRUCTOR_ITERATIONS` are 
new.
   
   Key destructors: a destructor that sets a value again is called again (at 
most 4 passes), and a destructor sees its key with the value `NULL`. In-tree 
users of `pthread_key_create()` (ostest, the sim SMP code) give no destructor. 
Task-local storage (`task_tls_alloc()`) is not changed.
   
   No size change of a structure. No new Kconfig option.
   
   ## Testing
   
   Test programs `posixopts.c` (each option macro must match what the build can 
do) and `limitsposix.c`, on qemu-armv8a:knsh (kernel build) and qemu-armv8a:nsh 
(flat build, the tests as builtin apps), QEMU with HVF, `CONFIG_TLS_NELEM=8`:
   
   | Case | master | this PR |
   |---|---|---|
   | `_POSIX_BARRIERS`, `_POSIX_READER_WRITER_LOCKS`, `_POSIX_SPIN_LOCKS` 
defined; barriers and rwlocks work | not defined: FAIL | 201712L, 201712L, -1: 
PASS |
   | `_POSIX_THREAD_ATTR_STACKSIZE`/`STACKADDR` have a value | empty / not 
defined: FAIL | 201712L: PASS |
   | `_POSIX_MAPPED_FILES` matches `mmap()` of a file | 201712L, `mmap()` 
fails: FAIL | -1: PASS |
   | `_POSIX_SEMAPHORES` matches `sem_open()` (default) | 201712L, no 
`sem_open()`: FAIL | -1: PASS |
   | the same with `CONFIG_FS_NAMED_SEMAPHORES` (knsh) | PASS | 201712L: PASS |
   | `_POSIX_THREAD_PROCESS_SHARED`: a process-shared mutex and condition 
variable work across two tasks in `shm_open()` memory (knsh; flat with 
`CONFIG_FS_SHMFS`) | PASS | PASS |
   | `_POSIX_THREAD_KEYS_MAX == 128` | 8: FAIL | 128: PASS |
   | `LOGIN_NAME_MAX` defined, >= 9 | not defined: FAIL | 33: PASS |
   | `PTHREAD_DESTRUCTOR_ITERATIONS` defined, >= 4 | not defined: FAIL | 4: 
PASS |
   | a destructor that sets the value again is called again, and sees `NULL` | 
1 call: FAIL | 3 calls, `NULL` each time: PASS |
   
   The results are the same on knsh and on flat nsh. ostest exits with status 0 
on qemu-armv8a:knsh and qemu-armv8a:nsh (also in the flat runs with the test 
apps), on master and with this PR.
   
   Build, each OK: qemu-armv8a:nsh (flat, arm64), also with `CONFIG_FS_RAMMAP` 
and `CONFIG_SCHED_CRITMONITOR`; qemu-armv8a:knsh (kernel, arm64), also with 
`CONFIG_FS_NAMED_SEMAPHORES`, `CONFIG_PTHREAD_SPINLOCKS` and `CONFIG_MM_SHM`; 
rv-virt:knsh64 (kernel, rv64); mps2-an500:nsh (flat, Cortex-M7), also with 
`CONFIG_DISABLE_PTHREAD` (without the ostest and getprime apps, which need 
pthreads, as on master); mps2-an500:knsh (protected, Cortex-M7).
   
   `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]

Reply via email to