This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] Native POSIX Thread Library(NPTL) ARM Supporting Patches (1/3)
- From: "Hu, Boris" <boris dot hu at intel dot com>
- To: "Linux-Arm-Kernel (E-mail)" <linux-arm-kernel at lists dot arm dot linux dot org dot uk>, "Libc-Alpha (E-mail)" <libc-alpha at sources dot redhat dot com>, "NPTL list (E-mail)" <phil-list at redhat dot com>
- Date: Fri, 23 May 2003 16:23:02 +0800
- Subject: [PATCH] Native POSIX Thread Library(NPTL) ARM Supporting Patches (1/3)
Native POSIX Thread Library(NPTL) is an enhanced implementation of
POSIX thread library and tries to replace the linuxthreads implementation
with the help of linux kernel.It is designed and implemented by
Ulrich Drepper and Ingo Molnar. Its design document could be found
at: http://people.redhat.com/drepper/nptl-design.pdf. The latest
source code could be found at ftp://people.redhat.com/drepper/nptl/.
To enable nptl in one platfrom, three components need be touched: linux kernel,
glibc, and nptl. Meanwhile, a TLS(Thread Local Storage) feature support is
required in the toolchain. (Its document could be found at
http://people.redhat.com/drepper/tls.pdf)
However, TLS is absent in arm toolchain. So here is a work-around way.
In the linux kernel, a thread register is simulated by an additional field(pd_addr)
to thread_struct and two system calls(sys_get/set_thread_area()). __thread
keyword is disabled in glibc and nptl. Moreover, some code related TLS in nptl
is protected by the glibc macro USE_TLS.
So far, all tests in nptl-0.20 have passed in the arm-linux-2.5.59 on pxa-250 platform. :p
TODO
--------
* Add TLS support to arm toolchain.
* Adapt the nptl version to the latest version.
Toolchain
----------
* arm-linux-gcc: 3.2.1
* arm-linux-binutils: 2.13.90.0.20
* arm-linux-glibc: 2.2.5-2
Codebase
---------
* glibc-2.3.2:
http://ftp.gnu.org/gnu/glibc/glibc-2.3.2.tar.bz2
* linuxthreads-2.3.2:
http://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.3.tar.bz2
* nptl-0.20:
ftp://people.redhat.com/drepper/nptl/nptl-0.20.tar.bz2
* linux-2.5.59-rmk1-pxa1:
http://www.kernel.org/pub/linux/kernel/v2.5/linux-2.5.59.tar.bz2
ftp://ftp.arm.linux.org.uk/pub/armlinux/kernel/v2.5/patch-2.5.59-rmk1.gz
ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/diff-2.5.59-rmk1-pxa1.gz
Patches
--------------
* arm-kernel-2.5.59-nptl.diff
* glibc-2.3.2-arm-nptl.diff
* arm-nptl-0.20.diff
They could also be found at: http://xcgl-port.sourceforge.net/nptl.html
Steps to build kernel
-----------------------------
# tar xjvf linux-2.5.59.tar.bz2
# cd linux-2.5.59
# gzip -dc ../patch-2.5.59-rmk1.gz | patch -p1
# gzip -dc ../diff-2.5.59-rmk1-pxa1.gz | patch -p1
# patch -p1 < arm-kernel-2.5.59-nptl.diff
# make XXX_config (board related)
# make menuconfig
Select "File System"-->Virtual memory file sytem support (former shm fs)
# make oldconfig
# make dep
# make zImage
# When it boots, type the following command in the target board
mount -t tmpfs none /dev/shm/
Steps to build glibc & nptl
-----------------------------------
# tar xjvf glibc-2.3.2.tar.bz2
# tar xjvf glibc-linuxthreads-2.3.2.tar.bz2 -C glibc-2.3.2
# tar xjvf nptl-0.20.tar.bz2 -C glibc-2.3.2
# cd glibc-2.3.2; patch -p1 < glibc-2.3.2-arm-nptl.diff
# cd nptl; patch -p1 < arm-nptl-0.20.diff
# cd ..; cd ..;
# mkdir glibc-2.3.2-build
# cd glibc-2.3.2-build
# ../glibc-2.3.2/configure arm-linux --prefix=/tmp/install --enable-add-ons=nptl
--without-tls --without-__thread --build=i686-pc-linux-gnu
--with-headers=/nptl_test/linux-2.5.59/include
# make -j2
# make subdirs=nptl tests # to build the test cases of nptl
Questions, comments, etc. very welcome!
TIA,
Boris (Hu Jiang Tao)
----------------------------------
This email message contains solely
my own personal views, and not
necessarily those of my employer.
----------------------------------
$ diffstat arm-kernel-2.5.59-nptl.diff
arch/arm/kernel/calls.S | 6 +++---
arch/arm/kernel/process.c | 33 +++++++++++++++++++++++++++++++++
arch/arm/kernel/sys_arm.c | 12 ++++++------
include/asm-arm/processor.h | 8 ++++++++
include/asm-arm/unistd.h | 6 ++++++
5 files changed, 56 insertions(+), 9 deletions(-)
diff -urN -X dontdiff arm-linux-2.5.59.orig/arch/arm/kernel/calls.S arm-linux-2.5.59.boris/arch/arm/kernel/calls.S
--- arm-linux-2.5.59.orig/arch/arm/kernel/calls.S 2003-05-22 10:00:30.000000000 +0800
+++ arm-linux-2.5.59.boris/arch/arm/kernel/calls.S 2003-05-22 09:52:56.000000000 +0800
@@ -268,9 +268,9 @@
.long sys_epoll_ctl
.long sys_epoll_wait
.long sys_remap_file_pages
- .long sys_ni_syscall /* sys_set_thread_area */
-/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
- .long sys_ni_syscall /* sys_set_tid_address */
+ .long sys_set_thread_area
+/* 255 */ .long sys_get_thread_area
+ .long sys_set_tid_address
__syscall_end:
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -urN -X dontdiff arm-linux-2.5.59.orig/arch/arm/kernel/process.c arm-linux-2.5.59.boris/arch/arm/kernel/process.c
--- arm-linux-2.5.59.orig/arch/arm/kernel/process.c 2003-05-22 10:00:30.000000000 +0800
+++ arm-linux-2.5.59.boris/arch/arm/kernel/process.c 2003-05-22 14:02:45.000000000 +0800
@@ -337,6 +337,9 @@
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
thread->cpu_context.sp = (unsigned long)childregs;
thread->cpu_context.pc = (unsigned long)ret_from_fork;
+
+ if( clone_flags & CLONE_SETTLS )
+ p->thread.pd_addr = childregs->ARM_r4 ; // set a new TLS for the child thread
return 0;
}
@@ -441,3 +444,33 @@
} while (count ++ < 16);
return 0;
}
+
+/*
+ * Set a given TLS descriptor
+ */
+asmlinkage int sys_set_thread_area(struct user_desc *u_info)
+{
+ struct thread_struct *t = ¤t->thread;
+ struct user_desc info;
+
+ if (copy_from_user(&info, u_info, sizeof(info)))
+ return -EFAULT;
+ t->pd_addr = info.pd_addr;
+
+ return 0;
+}
+
+/*
+ * Get current thread TLS descriptor
+ */
+asmlinkage int sys_get_thread_area(struct user_desc *u_info)
+{
+ struct user_desc info;
+
+ info.pd_addr = current->thread.pd_addr;
+
+ if (copy_to_user(u_info, &info, sizeof(info)))
+ return -EFAULT;
+
+ return 0;
+}
diff -urN -X dontdiff arm-linux-2.5.59.orig/arch/arm/kernel/sys_arm.c arm-linux-2.5.59.boris/arch/arm/kernel/sys_arm.c
--- arm-linux-2.5.59.orig/arch/arm/kernel/sys_arm.c 2003-05-22 10:00:30.000000000 +0800
+++ arm-linux-2.5.59.boris/arch/arm/kernel/sys_arm.c 2003-05-22 09:52:56.000000000 +0800
@@ -249,17 +249,17 @@
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
{
struct task_struct *p;
+ int *parent_tidptr, *child_tidptr;
+ int *pd;
- /*
- * We don't support SETTID / CLEARTID
- */
- if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID))
- return -EINVAL;
+ parent_tidptr = regs->ARM_r2;
+ child_tidptr = regs->ARM_r3;
+ pd = regs->ARM_r4;
if (!newsp)
newsp = regs->ARM_sp;
- p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
+ p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, parent_tidptr, child_tidptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
diff -urN -X dontdiff arm-linux-2.5.59.orig/include/asm-arm/processor.h arm-linux-2.5.59.boris/include/asm-arm/processor.h
--- arm-linux-2.5.59.orig/include/asm-arm/processor.h 2003-05-22 09:59:15.000000000 +0800
+++ arm-linux-2.5.59.boris/include/asm-arm/processor.h 2003-05-22 16:56:58.000000000 +0800
@@ -50,6 +50,8 @@
unsigned long address;
unsigned long trap_no;
unsigned long error_code;
+
+ void * pd_addr; /* address of struct pthread */
/* debugging */
struct debug_info debug;
};
@@ -73,4 +75,10 @@
#endif
+
+struct user_desc {
+ void * pd_addr; /* address of struct pthread */
+};
+
+
#endif /* __ASM_ARM_PROCESSOR_H */
diff -urN -X dontdiff arm-linux-2.5.59.orig/include/asm-arm/unistd.h arm-linux-2.5.59.boris/include/asm-arm/unistd.h
--- arm-linux-2.5.59.orig/include/asm-arm/unistd.h 2003-05-22 09:59:15.000000000 +0800
+++ arm-linux-2.5.59.boris/include/asm-arm/unistd.h 2003-05-22 16:55:02.000000000 +0800
@@ -279,6 +279,12 @@
#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+
+#define __NR_set_thread_area (__NR_SYSCALL_BASE+254)
+#define __NR_get_thread_area (__NR_SYSCALL_BASE+255)
+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
+
+
/* 254 for set_thread_area */
/* 255 for get_thread_area */
/* 256 for set_tid_address */