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]
