Mulyadi Santosa (mulyadi.santosa@xxxxxxxxx) wrote: > Hello everyone.. > > I try to observe how TLS and NPTL work on kernel side. I use Redhat 9 > with stock kernel 2.4.20-19.9 and glibc-2.3.2-11.9. > > I create a simple pthread test program which forks 2 threads and simply > print "Hello world" message. At the end, I call pthread_join two times > to cleanly terminate these two threads and finally terminate the main > program. > > Strace-ing on the program shows me these interesting outputs (i am sorry > if the line wrapping screws code pasted below): > > mmap2(NULL, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC, > MAP_PRIVATE|MAP_ANONYMOUS, > -1, 0) = 0x40037000 > brk(0) = 0x8049824 > brk(0x804a824) = 0x804a824 > brk(0) = 0x804a824 > brk(0x804b000) = 0x804b000 > mprotect(0x40037000, 4096, PROT_NONE) = 0 > clone(child_stack=0x408368d0,flags=CLONE_VM|CLONE_FS|CLONE_FILES| > CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_PARENT_SETTID| > CLONE_CHILD_CLEARTID|CLONE_DETACHED, > [4954],{entry_number:6,base_addr:0x40836cc0, > limit:1048575,seg_32bit:1,contents:0, read_exec_only:0, > limit_in_pages:1,seg_not_present:0, useable:1}) = 4954 > > On the other hand, inside arch/i386/kernel/process.c, i found codes that > handles CLONE_SETTLS flag (copy_thread() function ): > > if (clone_flags & CLONE_SETTLS) { > struct desc_struct *desc; > struct user_desc info; > int idx; > > if (copy_from_user(&info, (void *)childregs->esi, > sizeof(info))) > return -EFAULT; > if (LDT_empty(&info)) > return -EINVAL; > > idx = info.entry_number; > if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) > return -EINVAL; > > desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; > desc->a = LDT_entry_a(&info); > desc->b = LDT_entry_b(&info); > } > My questions is: > 1. What is the purpose of allocating new LDT entry? Is it to provide new > segment for freshly created thread to store its thread-local data? > > 2. Is the format of LDT entry 100% similar with GDT entry? If yes, what > is the advantage of using LDT for this threading purpose instead of > GDT? Yes, it is the same on x86. See IA-32 Arch Software Developper Manual 3 , 3.4.5.1 and 3.5. > 3. Observing strace results, it seems that the user space program > defines certain base address for new allocated segment along with other > attributes. On the kernel side, seems like these informations are > retrieved to construct new LDT entry. My early conclusions is: base > address is needed because thread local data (defined by __thread) only > contains offset, thus it needs base address to form a complete linear > address. Is this correct? > > 4. I read somewhere on the Internet that gs register is used to point on > the currently used LDT entry related with currently running thread. Is > this just a convention which is used inside the libpthread? or is there > other explanation on why using gs register for this purpose? > > thank your for your help...again, sorry for this long e-mail....... - Christophe -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/