diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-01-12 10:11:16 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-01-12 10:11:16 +0000 |
commit | aff4519d380c863ed0f259a1387cb473d3f3bad2 (patch) | |
tree | 825718efb1a8a4598d6de379d70a05ee034ab4f2 /linuxthreads | |
parent | 26a676d0aae53e2e770581c133356d8c0e39268c (diff) | |
download | glibc-aff4519d380c863ed0f259a1387cb473d3f3bad2.tar glibc-aff4519d380c863ed0f259a1387cb473d3f3bad2.tar.gz glibc-aff4519d380c863ed0f259a1387cb473d3f3bad2.tar.bz2 glibc-aff4519d380c863ed0f259a1387cb473d3f3bad2.zip |
Update.
2003-01-11 Jim Meyering <jim@meyering.net>
* io/ftw.c [HAVE_CONFIG_H]: Include <config.h>.
[HAVE_SYS_PARAM_H || _LIBC]: Guard inclusion of <sys/param.h>.
Include <sys/stat.h>, not <include/sys/stat.h>, if !_LIBC.
[!_LIBC] (__chdir, __closedir, __fchdir, __getcwd, __opendir): Define.
[!_LIBC] (__readdir64, __tdestroy, __tfind, __tsearch): Define.
[!_LIBC] (internal_function, dirent64, MAX): Define.
(__set_errno): Define if not already defined.
(open_dir_stream): When FTW_CHDIR is enabled, invoke opendir on
the basename, not the entire file name.
(process_entry): When FTW_CHDIR is enabled, invoke XSTAT or LXSTAT on
the basename, not the entire file name.
2003-01-12 Ulrich Drepper <drepper@redhat.com>
* string/tester.c (test_strcpy): Disable last added strcpy until
it is fixed.
2003-01-11 Philip Blundell <philb@gnu.org>
* sysdeps/unix/sysv/linux/arm/socket.S: Add cancellation support.
2003-01-11 Andreas Schwab <schwab@suse.de>
* Makerules: Add vpath for %.dynsym and %.so so that the
implicit rule chaining for check-abi works.
2003-01-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* sysdeps/unix/sysv/linux/sh/sysdep.h (SYSCALL_ERROR_HANDLER):
Add non-PIC case.
2003-01-11 Jakub Jelinek <jakub@redhat.com>
* elf/tls-macros.h [__ia64__] (__TLS_CALL_CLOBBERS): Define.
[__ia64__] (TLS_LE, TLS_IE): Fix typos. Add ;; at start of asm if
gp is used early.
[__ia64__] (TLS_LD, TLS_GD): Likewise. Use __TLS_CALL_CLOBBERS.
* elf/Makefile ($(objpfx)tst-tlsmod5.so, $(objpfx)tst-tlsmod6.so):
Ensure libc.so in DT_NEEDED.
* sysdeps/alpha/dl-machine.h (elf_machine_rela): Move
CHECK_STATIC_TLS before l_tls_offset use.
* sysdeps/i386/dl-machine.h (elf_machine_rel, elf_machine_rela):
Likewise.
* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
* sysdeps/generic/dl-tls.c (_dl_allocate_tls_storage) [TLS_DTV_AT_TP]:
Allocate TLS_PRE_TCB_SIZE bytes below result.
(_dl_deallocate_tls) [TLS_DTV_AT_TP]: Adjust before freeing.
* sysdeps/generic/libc-tls.c (__libc_setup_tls): If
TLS_INIT_TP_EXPENSIVE is not defined, allocate even if no PT_TLS
segment has been found. If TLS_DTV_AT_TP, allocate TLS_PRE_TCB_SIZE
bytes below result and add tcb_offset to memsz.
* sysdeps/ia64/dl-tls.h (__tls_get_addr): New prototype.
* sysdeps/ia64/dl-machine.h: Include tls.h.
(elf_machine_type_class): Return ELF_RTYPE_CLASS_PLT for TLS relocs
too.
(elf_machine_rela): Assume if sym_map != NULL sym is non-NULL too.
Handle R_IA64_DTPMOD*, R_IA64_DTPREL* and R_IA64_TPREL* relocations.
* sysdeps/ia64/libc-tls.c: New file.
2003-01-10 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/powerpc/powerpc64/sysdep.h (PSEUDO_RET): Add branch hit.
* sysdeps/unix/sysv/linux/powerpc/bits/stat.h (STAT_VER_LINUX):
Fix type. Move definition out of #if.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S: Add cancellation
support.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Remove
ftruncate64, pread64, pwrite64, truncate64 entries.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
(INLINE_SYSCALL): New version that supports function call like
syscalls. Add __builtin_expect.
(LOADARGS_n): Add argument size safety checks.
(INTERNAL_SYSCALL): New Macro.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/sys/procfs.h [__PPC_ELF_H]: Avoid
redefinition of elf_fpreg_t and elf_fpregset_t.
2003-01-12 Ulrich Drepper <drepper@redhat.com>
* elf/dl-close.c (_dl_close): Add several asserts. Correct and
simplify test for unloading. If loader of a DSO is unloaded do not
use its scope anymore. Fall back to own scope and adjust opencounts.
Fix several comments.
* elf/dl-deps.c (_dl_map_object_deps): Always allocate memory for
the l_searchlist, not only for l_initfini.
* elf/dl-lookup.c (add_dependencies): Avoid creating relocation
dependencies if objects cannot be removed. Remove object with the
definition as not unloadable if necessary.
* elf/reldep6.c: Create relocation dependency before closing the first
module.
2003-01-10 Guido Günther <agx@sigxcpu.org>
* elf/Makefile: Add rules to build and run reldep9 test.
* elf/reldep9.c: New file.
* elf/reldep9mod1.c: New file.
* elf/reldep9mod2.c: New file.
* elf/reldep9mod3.c: New file.
2003-01-09 Jakub Jelinek <jakub@redhat.com>
* elf/Makefile: Add rules to build and run nodelete2 test.
* elf/nodelete2.c: New file.
* elf/nodel2mod1.c: New file.
* elf/nodel2mod2.c: New file.
* elf/nodel2mod3.c: New file.
2003-01-09 Jakub Jelinek <jakub@redhat.com>
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 47 | ||||
-rw-r--r-- | linuxthreads/manager.c | 23 | ||||
-rw-r--r-- | linuxthreads/pthread.c | 75 | ||||
-rw-r--r-- | linuxthreads/sysdeps/ia64/pt-machine.h | 10 | ||||
-rw-r--r-- | linuxthreads/sysdeps/ia64/tcb-offsets.sym | 2 | ||||
-rw-r--r-- | linuxthreads/sysdeps/ia64/tls.h | 86 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h | 19 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S | 57 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile (renamed from linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile) | 0 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h | 102 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S | 57 |
11 files changed, 417 insertions, 61 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 862b5485ab..5f0c1bfb2b 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,50 @@ +2003-01-11 Philip Blundell <philb@gnu.org> + + * sysdeps/unix/sysv/linux/arm/vfork.S: New file. + * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO_RET): + Correctly unstack lr. + (UNDOARGS_5): Fix ordering of pushes and pops. + (SINGLE_THREAD_P_PIC): New. + (SINGLE_THREAD_P_INT): New. + (SINGLE_THREAD_P): Implement in terms of above. Restore lr if it + was stacked. + (PSEUDO): Use SINGLE_THREAD_P_INT. + +2003-01-11 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + * sysdeps/unix/sysv/linux/sh/vfork.S: New file. + +2003-01-11 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/ia64/tls.h (tcbhead_t): Change into dtv_t *, void *. + [HAVE_TLS_SUPPORT] (USE_TLS, TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN, + TLS_TCB_SIZE, TLS_PRE_TCB_SIZE, TLS_TCB_ALIGN, TLS_DTV_AT_TP, + INSTALL_DTV, INSTALL_NEW_DTV, GET_DTV, TLS_INIT_TP, THREAD_SELF, + INIT_THREAD_SELF): Define. + [HAVE_TLS_SUPPORT]: Include descr.h. + (NONTLS_INIT_TP): Point __thread_self at the end of dummy + struct _pthread_descr_struct. + * sysdeps/ia64/pt-machine.h (THREAD_GETMEM, THREAD_GETMEM_NC, + THREAD_SETMEM, THREAD_SETMEM_NC): Define using THREAD_SELF, + not __thread_self. + * sysdeps/ia64/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Adjust + computation. + * pthread.c (__pthread_initialize_minimal): Use tcbp, not self + for TCB pointer. + (__pthread_initialize_manager): Rename tcb to mgr. + Use tcbp for TCB pointer, if TLS_DTV_AT_TP set mgr to sizeof (struct + _pthread_descr) below tcbp, otherwise to tcbp. + * manager.c (pthread_handle_create): If TLS_DTV_AT_TP, set + new_thread to be below _dl_allocate_tls (). Adjust new_thread back + before freeing. Fix clone arguments if report_events and USE_TLS. + (pthread_free): Adjust th back before freeing. + +2003-01-10 Steven Munroe <sjmunroe@us.ibm.com> + + * sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile: Moved to ... + * sysdeps/unix/sysv/linux/powerpc/Makefile: ...here. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: New File. + 2003-01-09 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/i386/vfork.S: New file. diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index 3268ea8a41..8f9b23841b 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -590,6 +590,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread = _dl_allocate_tls (NULL); if (new_thread == NULL) return EAGAIN; +# if TLS_DTV_AT_TP + /* pthread_descr is right below TP. */ + --new_thread; +# endif #else /* Prevent warnings. */ new_thread = NULL; @@ -607,6 +611,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, if (sseg >= PTHREAD_THREADS_MAX) { #ifdef USE_TLS +# if TLS_DTV_AT_TP + ++new_thread; +# endif _dl_deallocate_tls (new_thread, true); #endif return EAGAIN; @@ -631,7 +638,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread_id = sseg + pthread_threads_counter; /* Initialize the thread descriptor. Elements which have to be initialized to zero already have this value. */ +#if defined USE_TLS && TLS_DTV_AT_TP + new_thread->p_header.data.tcb = new_thread + 1; +#else new_thread->p_header.data.tcb = new_thread; +#endif new_thread->p_header.data.self = new_thread; new_thread->p_header.data.multiple_threads = 1; new_thread->p_tid = new_thread_id; @@ -711,15 +722,15 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, other, to get less paging and fewer mmaps. */ pid = __clone2(pthread_start_thread_event, (void **)new_thread_bottom, - (char *)new_thread - new_thread_bottom, + (char *)stack_addr - new_thread_bottom, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #elif _STACK_GROWS_UP - pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom, + pid = __clone(pthread_start_thread_event, (void *) new_thread_bottom, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #else - pid = __clone(pthread_start_thread_event, (void **) new_thread, + pid = __clone(pthread_start_thread_event, stack_addr, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #endif @@ -794,6 +805,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, #endif } #ifdef USE_TLS +# if TLS_DTV_AT_TP + ++new_thread; +# endif _dl_deallocate_tls (new_thread, true); #endif __pthread_handles[sseg].h_descr = NULL; @@ -881,6 +895,9 @@ static void pthread_free(pthread_descr th) munmap(guardaddr, stacksize + guardsize); #ifdef USE_TLS +# if TLS_DTV_AT_TP + ++th; +# endif _dl_deallocate_tls (th, true); #endif } diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c index 432336258c..f72e20ee09 100644 --- a/linuxthreads/pthread.c +++ b/linuxthreads/pthread.c @@ -307,6 +307,8 @@ __pthread_initialize_minimal(void) # elif !USE___THREAD if (__builtin_expect (GL(dl_tls_max_dtv_idx) == 0, 0)) { + tcbhead_t *tcbp; + /* There is no actual TLS being used, so the thread register was not initialized in the dynamic linker. */ @@ -318,7 +320,7 @@ __pthread_initialize_minimal(void) __libc_malloc_pthread_startup (true); if (__builtin_expect (_dl_tls_setup (), 0) - || __builtin_expect ((self = _dl_allocate_tls (NULL)) == NULL, 0)) + || __builtin_expect ((tcbp = _dl_allocate_tls (NULL)) == NULL, 0)) { static const char msg[] = "\ cannot allocate TLS data structures for initial thread\n"; @@ -326,7 +328,7 @@ cannot allocate TLS data structures for initial thread\n"; msg, sizeof msg - 1)); abort (); } - const char *lossage = TLS_INIT_TP (self, 0); + const char *lossage = TLS_INIT_TP (tcbp, 0); if (__builtin_expect (lossage != NULL, 0)) { static const char msg[] = "cannot set up thread-local storage: "; @@ -343,7 +345,7 @@ cannot allocate TLS data structures for initial thread\n"; the hooks might not work with that block from the plain malloc. So we record this block as unfreeable just as the dynamic linker does when it allocates the DTV before the libc malloc exists. */ - GL(dl_initial_dtv) = GET_DTV (self); + GL(dl_initial_dtv) = GET_DTV (tcbp); __libc_malloc_pthread_startup (false); } @@ -558,7 +560,10 @@ int __pthread_initialize_manager(void) int pid; struct pthread_request request; int report_events; - pthread_descr tcb; + pthread_descr mgr; +#ifdef USE_TLS + tcbhead_t *tcbp; +#endif __pthread_multiple_threads = 1; __pthread_main_thread->p_header.data.multiple_threads = 1; @@ -588,31 +593,39 @@ int __pthread_initialize_manager(void) #ifdef USE_TLS /* Allocate memory for the thread descriptor and the dtv. */ - __pthread_handles[1].h_descr = manager_thread = tcb - = _dl_allocate_tls (NULL); - if (tcb == NULL) { + tcbp = _dl_allocate_tls (NULL); + if (tcbp == NULL) { free(__pthread_manager_thread_bos); __libc_close(manager_pipe[0]); __libc_close(manager_pipe[1]); return -1; } +# if TLS_TCB_AT_TP + mgr = (pthread_descr) tcbp; +# elif TLS_DTV_AT_TP + /* pthread_descr is located right below tcbhead_t which _dl_allocate_tls + returns. */ + mgr = (pthread_descr) tcbp - 1; +# endif + __pthread_handles[1].h_descr = manager_thread = mgr; + /* Initialize the descriptor. */ - tcb->p_header.data.tcb = tcb; - tcb->p_header.data.self = tcb; - tcb->p_header.data.multiple_threads = 1; - tcb->p_lock = &__pthread_handles[1].h_lock; + mgr->p_header.data.tcb = tcbp; + mgr->p_header.data.self = mgr; + mgr->p_header.data.multiple_threads = 1; + mgr->p_lock = &__pthread_handles[1].h_lock; # ifndef HAVE___THREAD - tcb->p_errnop = &tcb->p_errno; + mgr->p_errnop = &mgr->p_errno; # endif - tcb->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager); - tcb->p_nr = 1; + mgr->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager); + mgr->p_nr = 1; # if __LT_SPINLOCK_INIT != 0 self->p_resume_count = (struct pthread_atomic) __ATOMIC_INITIALIZER; # endif - tcb->p_alloca_cutoff = PTHREAD_STACK_MIN / 4; + mgr->p_alloca_cutoff = PTHREAD_STACK_MIN / 4; #else - tcb = &__pthread_manager_thread; + mgr = &__pthread_manager_thread; #endif __pthread_manager_request = manager_pipe[1]; /* writing end */ @@ -649,24 +662,24 @@ int __pthread_initialize_manager(void) if ((mask & (__pthread_threads_events.event_bits[idx] | event_bits)) != 0) { - __pthread_lock(tcb->p_lock, NULL); + __pthread_lock(mgr->p_lock, NULL); #ifdef NEED_SEPARATE_REGISTER_STACK pid = __clone2(__pthread_manager_event, (void **) __pthread_manager_thread_bos, THREAD_MANAGER_STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, - tcb); + mgr); #elif _STACK_GROWS_UP pid = __clone(__pthread_manager_event, (void **) __pthread_manager_thread_bos, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, - tcb); + mgr); #else pid = __clone(__pthread_manager_event, (void **) __pthread_manager_thread_tos, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, - tcb); + mgr); #endif if (pid != -1) @@ -675,18 +688,18 @@ int __pthread_initialize_manager(void) the newly created thread's data structure. We cannot let the new thread do this since we don't know whether it was already scheduled when we send the event. */ - tcb->p_eventbuf.eventdata = tcb; - tcb->p_eventbuf.eventnum = TD_CREATE; - __pthread_last_event = tcb; - tcb->p_tid = 2* PTHREAD_THREADS_MAX + 1; - tcb->p_pid = pid; + mgr->p_eventbuf.eventdata = mgr; + mgr->p_eventbuf.eventnum = TD_CREATE; + __pthread_last_event = mgr; + mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1; + mgr->p_pid = pid; /* Now call the function which signals the event. */ __linuxthreads_create_event (); } /* Now restart the thread. */ - __pthread_unlock(tcb->p_lock); + __pthread_unlock(mgr->p_lock); } } @@ -695,13 +708,13 @@ int __pthread_initialize_manager(void) #ifdef NEED_SEPARATE_REGISTER_STACK pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos, THREAD_MANAGER_STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); #elif _STACK_GROWS_UP pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); #else pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); #endif } if (__builtin_expect (pid, 0) == -1) { @@ -710,8 +723,8 @@ int __pthread_initialize_manager(void) __libc_close(manager_pipe[1]); return -1; } - tcb->p_tid = 2* PTHREAD_THREADS_MAX + 1; - tcb->p_pid = pid; + mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1; + mgr->p_pid = pid; /* Make gdb aware of new thread manager */ if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0) { diff --git a/linuxthreads/sysdeps/ia64/pt-machine.h b/linuxthreads/sysdeps/ia64/pt-machine.h index 5c4dde2fca..4b88a00509 100644 --- a/linuxthreads/sysdeps/ia64/pt-machine.h +++ b/linuxthreads/sysdeps/ia64/pt-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent pthreads configuration and inline functions. IA-64 version. - Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -64,10 +64,10 @@ register struct _pthread_descr_struct *__thread_self __asm__("r13"); /* Access to data in the thread descriptor is easy. */ -#define THREAD_GETMEM(descr, member) __thread_self->member -#define THREAD_GETMEM_NC(descr, member) __thread_self->member -#define THREAD_SETMEM(descr, member, value) __thread_self->member = (value) -#define THREAD_SETMEM_NC(descr, member, value) __thread_self->member = (value) +#define THREAD_GETMEM(descr, member) THREAD_SELF->member +#define THREAD_GETMEM_NC(descr, member) THREAD_SELF->member +#define THREAD_SETMEM(descr, member, value) THREAD_SELF->member = (value) +#define THREAD_SETMEM_NC(descr, member, value) THREAD_SELF->member = (value) /* Memory barrier */ diff --git a/linuxthreads/sysdeps/ia64/tcb-offsets.sym b/linuxthreads/sysdeps/ia64/tcb-offsets.sym index aee6be2570..a1d199f44e 100644 --- a/linuxthreads/sysdeps/ia64/tcb-offsets.sym +++ b/linuxthreads/sysdeps/ia64/tcb-offsets.sym @@ -1,4 +1,4 @@ #include <sysdep.h> #include <tls.h> -MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) +MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads) - sizeof (struct _pthread_descr_struct) diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h index 544da6e694..b2c47c00a6 100644 --- a/linuxthreads/sysdeps/ia64/tls.h +++ b/linuxthreads/sysdeps/ia64/tls.h @@ -1,5 +1,5 @@ /* Definitions for thread-local data handling. linuxthreads/IA-64 version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,35 +33,91 @@ typedef union dtv } dtv_t; -/* FIXME: Only temporary. When TLS is supported on IA-64, - pthread_descr struct needs to be immediately below r13 and - at r13 a struct { dtv_t *dtv; void *private; }. */ typedef struct { - void *tcb; /* Pointer to the TCB. Not necessary the - thread descriptor used by libpthread. */ dtv_t *dtv; - void *self; /* Pointer to the thread descriptor. */ - int multiple_threads; + void *private; } tcbhead_t; #else /* __ASSEMBLER__ */ # include <tcb-offsets.h> #endif /* __ASSEMBLER__ */ -#undef USE_TLS +#ifdef HAVE_TLS_SUPPORT -#if USE_TLS +/* Signal that TLS support is available. */ +# define USE_TLS 1 + +# ifndef __ASSEMBLER__ +/* This is the size of the initial TCB. */ +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size of the TCB. */ +# define TLS_TCB_SIZE sizeof (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) + +/* The DTV is allocated at the TP; the TCB is placed elsewhere. */ +# define TLS_DTV_AT_TP 1 + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(tcbp, dtvp) \ + ((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1 + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(DTV) \ + (((tcbhead_t *)__thread_self)->dtv = (DTV)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(tcbp) \ + (((tcbhead_t *) (tcbp))->dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(tcbp, secondcall) \ + (__thread_self = (tcbp), NULL) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *)__thread_self)->dtv) + +/* Return the thread descriptor for the current thread. */ +# undef THREAD_SELF +# define THREAD_SELF (__thread_self - 1) + +# undef INIT_THREAD_SELF +# define INIT_THREAD_SELF(descr, nr) \ + (__thread_self = (struct _pthread_descr_struct *)(descr) + 1) + +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +# endif #else -#define NONTLS_INIT_TP \ - do { \ - static const tcbhead_t nontls_init_tp \ - = { .multiple_threads = 0 }; \ - __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \ +# ifndef __ASSEMBLER__ +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +# define NONTLS_INIT_TP \ + do { \ + static struct _pthread_descr_struct nontls_init_tp \ + = { .p_header.data.multiple_threads = 0 }; \ + __thread_self = ((__typeof (__thread_self)) &nontls_init_tp) + 1; \ } while (0) +#endif + #endif /* USE_TLS */ #endif /* tls.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h index 5f3709f742..38e472d2ba 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h @@ -27,6 +27,7 @@ # undef PSEUDO_RET # define PSEUDO_RET \ ldrcc pc, [sp], $4; \ + ldr lr, [sp], $4; \ b PLTJMP(SYSCALL_ERROR) # undef PSEUDO @@ -34,7 +35,7 @@ .section ".text"; \ PSEUDO_PROLOGUE; \ ENTRY (name) \ - SINGLE_THREAD_P; \ + SINGLE_THREAD_P_INT; \ bne .Lpseudo_cancel; \ DO_CALL (syscall_name, args); \ cmn r0, $4096; \ @@ -74,7 +75,7 @@ # define UNDOC2ARGS_4 # define DOCARGS_5 stmfd sp!, {r0-r3} -# define UNDOCARGS_5 str r4, [sp, #-4]!; ldmfd sp, {r0-r4} +# define UNDOCARGS_5 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24] # define UNDOC2ARGS_5 ldr r4, [sp], #20 # ifdef IS_IN_libpthread @@ -92,10 +93,11 @@ extern int __local_multiple_threads attribute_hidden; # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) # else # if !defined PIC -# define SINGLE_THREAD_P \ +# define SINGLE_THREAD_P_INT \ ldr ip, =__local_multiple_threads; \ ldr ip, [ip]; \ teq ip, #0; +# define SINGLE_THREAD_P SINGLE_THREAD_P_INT # define MAYBE_SAVE_LR \ str lr, [sp, $-4]!; # define PSEUDO_RET_MOV \ @@ -103,14 +105,19 @@ extern int __local_multiple_threads attribute_hidden; b PLTJMP(SYSCALL_ERROR) # define PSEUDO_PROLOGUE # else -# define SINGLE_THREAD_P \ - str lr, [sp, $-4]!; \ +# define SINGLE_THREAD_P_PIC(reg) \ ldr ip, 1b; \ - ldr lr, 2b; \ + ldr reg, 2b; \ 3: \ add ip, pc, ip; \ ldr ip, [ip, lr]; \ teq ip, #0; +# define SINGLE_THREAD_P_INT \ + str lr, [sp, $-4]!; \ + SINGLE_THREAD_P_PIC(lr) +# define SINGLE_THREAD_P \ + SINGLE_THREAD_P_INT; \ + ldr lr, [sp], $4 # define PSEUDO_PROLOGUE \ 1: .word _GLOBAL_OFFSET_TABLE_ - 3f - 8; \ 2: .word __local_multiple_threads(GOTOFF); diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S new file mode 100644 index 0000000000..6092bd9fd4 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S @@ -0,0 +1,57 @@ +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Philip Blundell <philb@gnu.org>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep-cancel.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address +pace. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new +rocess, + and the process ID of the new process to the old process. */ + + PSEUDO_PROLOGUE + +ENTRY (__vfork) + +#ifdef __NR_vfork + SINGLE_THREAD_P + bne HIDDEN_JUMPTARGET (__fork) + swi __NR_vfork + cmn a1, #4096 + RETINSTR(movcc, pc, lr) + + /* Check if vfork syscall is known at all. */ + ldr a2, =-ENOSYS + teq a1, a2 + bne PLTJMP(C_SYMBOL_NAME(__syscall_error)) +#endif + + /* If we don't have vfork, fork is close enough. */ + swi __NR_fork + cmn a1, #4096 + RETINSTR(movcc, pc, lr) + b PLTJMP(C_SYMBOL_NAME(__syscall_error)) + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile index e98c9bd866..e98c9bd866 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h new file mode 100644 index 0000000000..58257a17b2 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .section ".text"; \ + ENTRY (name) \ + SINGLE_THREAD_P; \ + bne- .Lpseudo_cancel; \ + DO_CALL (SYS_ify (syscall_name)); \ + PSEUDO_RET; \ + .Lpseudo_cancel: \ + stdu 1,-128(1); \ + mflr 9; \ + std 9,128+16(1); \ + DOCARGS_##args; /* save syscall args around CENABLE. */ \ + CENABLE; \ + std 3,72(1); /* store CENABLE return value (MASK). */ \ + UNDOCARGS_##args; /* restore syscall args. */ \ + DO_CALL (SYS_ify (syscall_name)); \ + mfcr 0; /* save CR/R3 around CDISABLE. */ \ + std 3,64(1); \ + std 0,8(1); \ + ld 3,72(1); /* pass MASK to CDISABLE. */ \ + CDISABLE; \ + ld 9,128+16(1); \ + ld 0,8(1); /* restore CR/R3. */ \ + ld 3,64(1); \ + mtlr 9; \ + mtcr 0; \ + addi 1,1,128; + +# define DOCARGS_0 +# define UNDOCARGS_0 + +# define DOCARGS_1 std 3,80(1); DOCARGS_0 +# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0 + +# define DOCARGS_2 std 4,88(1); DOCARGS_1 +# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1 + +# define DOCARGS_3 std 5,96(1); DOCARGS_2 +# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2 + +# define DOCARGS_4 std 6,104(1); DOCARGS_3 +# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3 + +# define DOCARGS_5 std 7,112(1); DOCARGS_4 +# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4 + +# define DOCARGS_6 std 8,120(1); DOCARGS_5 +# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5 + +# ifdef IS_IN_libpthread +# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel) +# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel) +# define __local_multiple_threads __pthread_multiple_threads +# else +# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel) +# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel) +# define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +# define SINGLE_THREAD_P \ + ld 10,__local_multiple_threads@got(2); \ + ld 10,0(10); \ + cmpdi 10,0 +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S new file mode 100644 index 0000000000..f796e31088 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S @@ -0,0 +1,57 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep-cancel.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) + SINGLE_THREAD_P + bf .Lhidden_fork + + mov.w .L1, r3 + trapa #0x10 + mov r0, r1 + mov #-12, r2 + shad r2, r1 + not r1, r1 // r1=0 means r0 = -1 to -4095 + tst r1, r1 // i.e. error in linux + bf .Lpseudo_end + SYSCALL_ERROR_HANDLER +.Lpseudo_end: + rts + nop +.L1: .word __NR_vfork + +.Lhidden_fork: + mov.l .L2, r1 + braf r1 + nop +1: + .align 2 +.L2: .long HIDDEN_JUMPTARGET(__fork)-1b + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) |