Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Moved the errno storage location out of the TCB and in TLS (into the struct tls_info_s).
  2. Modifed the errno access definitions and logic that was in sched/errno to use the TLS logic in user space. That logic now resides in libs/libc/errno since it is now a user library interface, not a core OS interface.
  3. TLS is now enabled by default.  It is enabled in the unaligned mode for the FLAT and PROTECTED build modes but in the hightly efficient aligned mode for KERNEL build mode.
  4. There are no longer an OS system calls related to the error (with the exception of a call to get the struct tls_info_s in the unaligned TLS mode).

TLS interfaces

TLS is a non-standard, but more general interface. It differs from pthread-specific data only in that its semantics are general; the semantics of the pthread-specific data interfaces are focused on pthreads. But they really should shared the same common underly logic.

Currently, there are fourTLS interfaces:


int tls_alloc(void);
int tls_free(int tlsindex);
uintptr_t tls_get_value(int tlsindex);
int tls_set_value(int tlsindex, uintptr_t tlsvalue);


as prototyped and documented in include/nuttx/tls.h.

These interfaces are basically adaptations from the Windows TLS interfaces which are directly anlagous to the POSIX pthread-specific data interfaces, adapted to NuttX coding standards (see, for example, links available at https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc).  There are no POSIX TLS interfaces and Linux (actual GLIBC) does not provide a good mechanism; it relies on a storage class that is specific to ELF binaries. That is not useful in an embedded system where no ELF information is present.

pthread-specific data

pthread-specific data is another mechanism for accessing thread-specific data. It consists of these POSIX standard interfaces:

...

  1. Moving the pthread-specific storage out of the TCB and into the TLS data.
  2. Moving the pthread-specific data accessors out of sched/pthread and into libs/libc/pthread
  3. Remove the pthread-specific data system calls.

TLS interfaces

TLS is a non-standard, but more general interface. It differs from pthread-specific data only in that is semantics are general; the semantics of the pthread-specific data interfaces are focused on pthreads. But they really should shared the same common underly logic.

Currently, there are two TLS interfaces:

uintptr_t tls_get_element(int elem);
void tls_set_element(int elem, uintptr_t value);

...

  1. .

...

[This is a case of the bad decision to let specific tools environment drive a design. Good designs should be independent of tools].

Instead, I think we should adapt from the Windows TLS interfaces which are directly anlagous to the POSIC pthread-specific data interfaces. Here is such an adaption (following NuttX coding standards. See https://en.wikipedia.org/wiki/Thread-local_storage#Windows_implementation):

int tls_alloc(void);
FAR void *tls_get_value(int tlsindex);
bool tls_set_value(int tlsindex, uinptr_t tlsvalue);
bool tls_free(int tlsindex);

The Windows prototypes can be found from links on this page: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc

Accessing the errno from kernel space.

...

Ideally, all of the user callable OS interfaces (the osapi()) should be moved to the location in libs/libc the system call (sycall/) should be redirected to nx_osapi(). A complication to doing this is that the OS interfaces which are also cancellation points call special internal interfaces, enter_cancellation_point() and leave_cancellation_point() that are not available from user space. So some addition partitioning would be need to accomplish this.

This separation of user and OS interfaces has not been implement as of this writing.

Process ID

Another unrelated data item that should, eventually, be included in the TLS data is the process ID (pid) if the currently exectuting thread. In some analysis of PROTECTED and KERNEL builds, it was found that getpid() was the most highly accessed OS interface. By moving the pid into TLS, we could eliminate this system call overhead (at least in the aligned TLS case).

...

include/errno.h        - Defines current errno access
include/nuttx/tls.h    - Defines the tls_info_s structure
include/nuttx/sched.h  - TheGroup errnorelated and pthread-specific data
sched/errno/*TLS structures
libs/libc/errno          - The oldTLS-based errno access logic.  Move to libs/libc/errno or tls
libs/libc/tls          - The newimplementation TLSof andthe possiblemost errno access logic
TLS interfaces
sched/pthreadgroup - Group-related implementation of certain TLS pthread_key*.c, pthread_*specific.c - Move to libs/libcinterfaces libs/libc/pthread - The implementation of the pthread-specific dta interfaces