User:Sortie/Sortix Thread Local Storage
Each thread has a user-space thread structure (struct pthread) which is used by the pthread implementation. The first member of that structure is a struct uthread, which is part of the kernel interface, and filled in by the kernel for the main thread. The first member of struct uthread is a pointer to itself as this is required on some architecturtes. The struct uthread also contains the location and size of the thread's stack; the location and size of the per-thread allocation; the location, size and alignment of the master thread local storage copy, the location and size of the argument vector allocation (argv and envp passed to main), and flags such as whether this is the first thread.
The rest of the struct pthread is exclusively used by the pthread implementation for mechanisms such as joining and detaching threads.
On i386 and x86-64, the base of the fs and gs segments are considered user-space registers and are set when creating a new thread and can be accessed/changed by the rdmsr() and wrmsr() system calls.
The kernel sets up thread local storage for the main thread during the execve() system call. It locates and loads the master thread local storage somewhere. It creates creates the per-thread allocation somewhere and sets up the thread local storage there, as well as the initializng the struct pthread (by initializing the uthread there, and zeroing the rest of the struct pthread, it finds the size of the struct pthread in the struct uthread). The thread local storage is thus operational immediately at program startup.
The errno lvalue is implemented as __thread int errno;.
- struct uthread
- struct pthread
- How the program tells the kernel the size of struct pthread
- The kernel locates the master TLS copy
- The kernel locates the size of struct pthread
- The kernel creates the main thread at the end of program loading
- The kernel switches fsbase and gsbase during context switching
- struct pthread is finalized during early program startup