[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[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 = &current->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 */




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]