Cygwin: flock: Fix overlap handling in lf_setlock() and lf_clearlock()
[newlib-cygwin.git] / winsup / cygwin / DevDocs / how-cygtls-works.txt
blob633c4da9656afbb96e15f89c05fc541151d09d87
1 Contributed by Max Kaehn
3 All cygwin threads have separate context in an object of class _cygtls.  The
4 storage for this object is kept on the stack in the bottom __CYGTLS_PADSIZE__
5 bytes.  Each thread references the storage via the Thread Environment Block
6 (aka Thread Information Block), which Windows maintains for each user thread
7 in the system, with the address in a segment register (FS on x86, GS on x86_64).
8 The memory is laid out as in the NT_TIB structure from <w32api/winnt.h>:
10 typedef struct _NT_TIB {
11         struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
12         PVOID StackBase;
13         PVOID StackLimit;
14         PVOID SubSystemTib;
15         _ANONYMOUS_UNION union {
16                 PVOID FiberData;
17                 DWORD Version;
18         } DUMMYUNIONNAME;
19         PVOID ArbitraryUserPointer;
20         struct _NT_TIB *Self;
21 } NT_TIB,*PNT_TIB;
23 Cygwin accesses cygtls like this (see cygtls.h):
25 #define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase \
26                                 - __CYGTLS_PADSIZE__)))
28 Initialization always goes through _cygtls::init_thread().  It works
29 in the following ways:
31 * In the main thread, _dll_crt0() provides __CYGTLS_PADSIZE__ bytes on the stack
32   and passes them to initialize_main_tls(), which calls _cygtls::init_thread().
33   It then calls dll_crt0_1(), which terminates with cygwin_exit() rather than
34   by returning, so the storage never goes out of scope.
36   If you load cygwin1.dll dynamically from a non-cygwin application, it is
37   vital that the bottom __CYGTLS_PADSIZE__ bytes of the stack are not in use
38   before you call cygwin_dll_init().  See winsup/testsuite/cygload for
39   more information.
41 * Threads other than the main thread receive DLL_THREAD_ATTACH messages
42   to dll_entry() (in init.cc).
43   - dll_entry() calls munge_threadfunc(), which grabs the function pointer
44     for the thread from the stack frame and substitutes threadfunc_fe(),
45   - which then passes the original function pointer to _cygtls::call(),
46   - which then allocates __CYGTLS_PADSIZE__ bytes on the stack and hands them
47     to call2(),
48   - which allocates an exception_list object on the stack and hands it to
49     init_exceptions() (in exceptions.cc), which attaches it to the end of
50     the list of exception handlers, changing _except_list (aka
51     tib->ExceptionList), then passes the cygtls storage to init_thread().
52     call2() calls ExitThread() instead of returning, so the storage never
53     goes out of scope.
55 Note that the padding isn't necessarily going to be just where the _cygtls
56 structure lives; it just makes sure there's enough room on the stack when the
57 __CYGTLS_PADSIZE__ bytes down from there are overwritten.
60 Debugging
62 You can examine the TIB in gdb via "info w32 tib"