Hi Dennis,
attached are the patches from will and me as they are used in openembedded.
--
Bye Henning
Index: uClibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ uClibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S 2008-08-28 00:22:06.278340855 +0200
@@ -0,0 +1,78 @@
+/* Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Philip Blundell <[email protected]>.
+
+ 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>
+#include <kernel-features.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)
+
+#ifdef __NR_vfork
+
+#ifdef SHARED
+ ldr ip, 1f
+ ldr r0, 2f
+3: add ip, pc, ip
+ ldr r0, [ip, r0]
+#else
+ ldr r0, 1f
+#endif
+ movs r0, r0
+ bne HIDDEN_JUMPTARGET (__fork)
+
+ DO_CALL (vfork, 0)
+ cmn a1, #4096
+ RETINSTR(cc, lr)
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* Check if vfork syscall is known at all. */
+ cmn a1, #ENOSYS
+ bne PLTJMP(C_SYMBOL_NAME(__syscall_error))
+#endif
+
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* If we don't have vfork, fork is close enough. */
+ DO_CALL (fork, 0)
+ cmn a1, #4096
+ RETINSTR(cc, lr)
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
+#endif
+ b PLTJMP(C_SYMBOL_NAME(__syscall_error))
+
+#ifdef SHARED
+1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8
+2: .word __libc_pthread_functions(GOTOFF)
+#else
+ .weak pthread_create
+1: .word pthread_create
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
Index: uClibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ uClibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h 2008-08-28 00:28:04.301636993 +0200
@@ -0,0 +1,130 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Phil Blundell <[email protected]>, 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 <tls.h>
+#include <pt-machine.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+/* We push lr onto the stack, so we have to use ldmib instead of ldmia
+ to find the saved arguments. */
+# ifdef PIC
+# undef DOARGS_5
+# undef DOARGS_6
+# undef DOARGS_7
+# define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8];
+# define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5};
+# define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6};
+# endif
+
+# undef PSEUDO_RET
+# define PSEUDO_RET \
+ ldrcc pc, [sp], $4; \
+ ldr lr, [sp], $4; \
+ b PLTJMP(SYSCALL_ERROR)
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ PSEUDO_PROLOGUE; \
+ ENTRY (name); \
+ SINGLE_THREAD_P; \
+ bne .Lpseudo_cancel; \
+ DO_CALL (syscall_name, args); \
+ cmn r0, $4096; \
+ RETINSTR(cc, lr); \
+ b PLTJMP(SYSCALL_ERROR); \
+ .Lpseudo_cancel: \
+ str lr, [sp, $-4]!; \
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
+ CENABLE; \
+ mov ip, r0; /* put mask in safe place. */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ swi SYS_ify (syscall_name); /* do the call. */ \
+ str r0, [sp, $-4]!; /* save syscall return value. */ \
+ mov r0, ip; /* get mask back. */ \
+ CDISABLE; \
+ ldr r0, [sp], $4; /* retrieve return value. */ \
+ UNDOC2ARGS_##args; /* fix register damage. */ \
+ cmn r0, $4096;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+# define UNDOC2ARGS_0
+
+# define DOCARGS_1 str r0, [sp, #-4]!;
+# define UNDOCARGS_1 ldr r0, [sp], #4;
+# define UNDOC2ARGS_1
+
+# define DOCARGS_2 str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_2 ldr r0, [sp], #4; ldr r1, [sp], #4;
+# define UNDOC2ARGS_2
+
+# define DOCARGS_3 str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_3 ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
+# define UNDOC2ARGS_3
+
+# define DOCARGS_4 stmfd sp!, {r0-r3}
+# define UNDOCARGS_4 ldmfd sp!, {r0-r3}
+# define UNDOC2ARGS_4
+
+# define DOCARGS_5 stmfd sp!, {r0-r3}
+# 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
+# define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
+# define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
+# define __local_multiple_threads __pthread_multiple_threads
+# else
+# define CENABLE bl PLTJMP(__libc_enable_asynccancel)
+# define CDISABLE bl PLTJMP(__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
+# if !defined PIC
+# define SINGLE_THREAD_P \
+ ldr ip, =__local_multiple_threads; \
+ ldr ip, [ip]; \
+ teq ip, #0;
+# define PSEUDO_PROLOGUE
+# else
+# define SINGLE_THREAD_P \
+ ldr ip, 1b; \
+2: \
+ ldr ip, [pc, ip]; \
+ teq ip, #0;
+# define PSEUDO_PROLOGUE \
+ 1: .word __local_multiple_threads - 2f - 8;
+# endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
+
+#endif
Index: uClibc/libpthread/linuxthreads/descr.h
===================================================================
--- uClibc.orig/libpthread/linuxthreads/descr.h 2008-08-27 23:59:46.171809044 +0200
+++ uClibc/libpthread/linuxthreads/descr.h 2008-08-28 00:00:35.435134759 +0200
@@ -123,9 +123,9 @@
union dtv *dtvp;
pthread_descr self; /* Pointer to this structure */
int multiple_threads;
-# ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
-# endif
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} data;
void *__padding[16];
} p_header;
@@ -193,6 +193,13 @@
size_t p_alloca_cutoff; /* Maximum size which should be allocated
using alloca() instead of malloc(). */
/* New elements must be added at the end. */
+
+ /* This member must be last. */
+ char end_padding[];
+
+#define PTHREAD_STRUCT_END_PADDING \
+ (sizeof (struct _pthread_descr_struct) \
+ - offsetof (struct _pthread_descr_struct, end_padding))
} __attribute__ ((aligned(32))); /* We need to align the structure so that
doubles are aligned properly. This is 8
bytes on MIPS and 16 bytes on MIPS64.
Index: uClibc/libpthread/linuxthreads/manager.c
===================================================================
--- uClibc.orig/libpthread/linuxthreads/manager.c 2008-08-27 23:59:54.185140485 +0200
+++ uClibc/libpthread/linuxthreads/manager.c 2008-08-28 00:00:35.435134759 +0200
@@ -679,6 +679,17 @@
new_thread->p_inheritsched = attr ? attr->__inheritsched : 0;
new_thread->p_alloca_cutoff = stksize / 4 > __MAX_ALLOCA_CUTOFF
? __MAX_ALLOCA_CUTOFF : stksize / 4;
+
+ /* Copy the stack guard canary. */
+#ifdef THREAD_COPY_STACK_GUARD
+ THREAD_COPY_STACK_GUARD (new_thread);
+#endif
+
+ /* Copy the pointer guard value. */
+#ifdef THREAD_COPY_POINTER_GUARD
+ THREAD_COPY_POINTER_GUARD (new_thread);
+#endif
+
/* Initialize the thread handle */
__pthread_init_lock(&__pthread_handles[sseg].h_lock);
__pthread_handles[sseg].h_descr = new_thread;
@@ -742,15 +753,15 @@
pid = __clone2(pthread_start_thread_event,
(void **)new_thread_bottom,
(char *)stack_addr - new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#elif _STACK_GROWS_UP
pid = __clone(pthread_start_thread_event, (void *) new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#else
pid = __clone(pthread_start_thread_event, stack_addr,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#endif
saved_errno = errno;
@@ -783,15 +794,15 @@
pid = __clone2(pthread_start_thread,
(void **)new_thread_bottom,
(char *)stack_addr - new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#elif _STACK_GROWS_UP
pid = __clone(pthread_start_thread, (void *) new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#else
pid = __clone(pthread_start_thread, stack_addr,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
__pthread_sig_cancel, new_thread);
#endif /* !NEED_SEPARATE_REGISTER_STACK */
saved_errno = errno;
@@ -892,10 +903,11 @@
#ifdef _STACK_GROWS_UP
# ifdef USE_TLS
size_t stacksize = guardaddr - th->p_stackaddr;
+ guardaddr = th->p_stackaddr;
# else
size_t stacksize = guardaddr - (char *)th;
-# endif
guardaddr = (char *)th;
+# endif
#else
/* Guardaddr is always set, even if guardsize is 0. This allows
us to compute everything else. */
Index: uClibc/libpthread/linuxthreads/pthread.c
===================================================================
--- uClibc.orig/libpthread/linuxthreads/pthread.c 2008-08-28 00:00:00.825141935 +0200
+++ uClibc/libpthread/linuxthreads/pthread.c 2008-08-28 00:00:35.438472147 +0200
@@ -698,6 +698,16 @@
mgr = &__pthread_manager_thread;
#endif
+ /* Copy the stack guard canary. */
+#ifdef THREAD_COPY_STACK_GUARD
+ THREAD_COPY_STACK_GUARD (mgr);
+#endif
+
+ /* Copy the pointer guard value. */
+#ifdef THREAD_COPY_POINTER_GUARD
+ THREAD_COPY_POINTER_GUARD (mgr);
+#endif
+
__pthread_manager_request = manager_pipe[1]; /* writing end */
__pthread_manager_reader = manager_pipe[0]; /* reading end */
@@ -738,17 +748,17 @@
pid = __clone2(__pthread_manager_event,
(void **) __pthread_manager_thread_bos,
THREAD_MANAGER_STACK_SIZE,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
mgr);
#elif _STACK_GROWS_UP
pid = __clone(__pthread_manager_event,
(void **) __pthread_manager_thread_bos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
mgr);
#else
pid = __clone(__pthread_manager_event,
(void **) __pthread_manager_thread_tos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
mgr);
#endif
@@ -778,13 +788,13 @@
#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, mgr);
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
#elif _STACK_GROWS_UP
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr);
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
#else
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr);
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
#endif
}
if (__builtin_expect (pid, 0) == -1) {
@@ -971,6 +981,10 @@
struct pthread_request request;
pthread_descr self = thread_self();
+ /* Make sure we come back here after suspend(), in case we entered
+ from a signal handler. */
+ THREAD_SETMEM(self, p_signal_jmp, NULL);
+
request.req_thread = self;
request.req_kind = REQ_PROCESS_EXIT;
request.req_args.exit.code = retcode;
@@ -1198,13 +1212,13 @@
void __pthread_restart_old(pthread_descr th)
{
- if (atomic_increment(&th->p_resume_count) == -1)
+ if (pthread_atomic_increment(&th->p_resume_count) == -1)
kill(th->p_pid, __pthread_sig_restart);
}
void __pthread_suspend_old(pthread_descr self)
{
- if (atomic_decrement(&self->p_resume_count) <= 0)
+ if (pthread_atomic_decrement(&self->p_resume_count) <= 0)
__pthread_wait_for_restart_signal(self);
}
@@ -1215,7 +1229,7 @@
int was_signalled = 0;
sigjmp_buf jmpbuf;
- if (atomic_decrement(&self->p_resume_count) == 0) {
+ if (pthread_atomic_decrement(&self->p_resume_count) == 0) {
/* Set up a longjmp handler for the restart signal, unblock
the signal and sleep. */
@@ -1272,9 +1286,9 @@
being delivered. */
if (!was_signalled) {
- if (atomic_increment(&self->p_resume_count) != -1) {
+ if (pthread_atomic_increment(&self->p_resume_count) != -1) {
__pthread_wait_for_restart_signal(self);
- atomic_decrement(&self->p_resume_count); /* should be zero now! */
+ pthread_atomic_decrement(&self->p_resume_count); /* should be zero now! */
/* woke spontaneously and consumed restart signal */
return 1;
}
Index: uClibc/libpthread/linuxthreads/specific.c
===================================================================
--- uClibc.orig/libpthread/linuxthreads/specific.c 2008-08-28 00:00:07.595139286 +0200
+++ uClibc/libpthread/linuxthreads/specific.c 2008-08-28 00:00:35.438472147 +0200
@@ -104,13 +104,14 @@
that if the key is reallocated later by pthread_key_create, its
associated values will be NULL in all threads.
- If no threads have been created yet, clear it just in the
- current thread. */
+ If no threads have been created yet, or if we are exiting, clear
+ it just in the current thread. */
struct pthread_key_delete_helper_args args;
args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
- if (__pthread_manager_request != -1)
+ if (__pthread_manager_request != -1
+ && !(__builtin_expect (__pthread_exit_requested, 0)))
{
struct pthread_request request;
@@ -203,8 +204,9 @@
__pthread_lock(THREAD_GETMEM(self, p_lock), self);
for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) {
if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) {
- free(THREAD_GETMEM_NC(self, p_specific[i]));
+ void *p = THREAD_GETMEM_NC(self, p_specific[i]);
THREAD_SETMEM_NC(self, p_specific[i], NULL);
+ free(p);
}
}
__pthread_unlock(THREAD_GETMEM(self, p_lock));
Index: uClibc/libpthread/linuxthreads/spinlock.c
===================================================================
--- uClibc.orig/libpthread/linuxthreads/spinlock.c 2008-08-28 00:00:17.805140454 +0200
+++ uClibc/libpthread/linuxthreads/spinlock.c 2008-08-28 00:00:35.438472147 +0200
@@ -637,8 +637,20 @@
#if defined HAS_COMPARE_AND_SWAP
wait_node_dequeue(pp_head, pp_max_prio, p_max_prio);
#endif
+
+ /* Release the spinlock before restarting. */
+#if defined TEST_FOR_COMPARE_AND_SWAP
+ if (!__pthread_has_cas)
+#endif
+#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP
+ {
+ __pthread_release(&lock->__spinlock);
+ }
+#endif
+
restart(p_max_prio->thr);
- break;
+
+ return;
}
}
Index: uClibc/libpthread/linuxthreads/spinlock.h
===================================================================
--- uClibc.orig/libpthread/linuxthreads/spinlock.h 2008-08-28 00:00:24.768471655 +0200
+++ uClibc/libpthread/linuxthreads/spinlock.h 2008-08-28 00:02:42.971786951 +0200
@@ -172,7 +172,7 @@
/* Operations on pthread_atomic, which is defined in internals.h */
-static __inline__ long atomic_increment(struct pthread_atomic *pa)
+static __inline__ long pthread_atomic_increment(struct pthread_atomic *pa)
{
long oldval;
@@ -184,7 +184,7 @@
}
-static __inline__ long atomic_decrement(struct pthread_atomic *pa)
+static __inline__ long pthread_atomic_decrement(struct pthread_atomic *pa)
{
long oldval;
Index: uClibc-0.9.30/libpthread/linuxthreads/Makefile.in
===================================================================
--- uClibc-0.9.30.orig/libpthread/linuxthreads/Makefile.in 2009-01-11 01:09:27.008515954 +0100
+++ uClibc-0.9.30/libpthread/linuxthreads/Makefile.in 2009-01-11 01:09:35.295181636 +0100
@@ -45,7 +45,7 @@
pthread_SRC := \
attr barrier cancel condvar errno events join pthread \
lockfile manager mutex pt-machine ptcleanup \
- ptclock_gettime ptclock_settime ptfork pthandles \
+ ptclock_gettime ptclock_settime ptfork pthandles pthread_atfork \
pthread_setegid pthread_seteuid pthread_setgid pthread_setregid \
pthread_setresgid pthread_setresuid pthread_setreuid pthread_setuid \
rwlock semaphore sighandler signals specific spinlock
Index: uClibc-0.9.30/libpthread/linuxthreads/pthread_atfork.c
===================================================================
--- uClibc-0.9.30.orig/libpthread/linuxthreads/pthread_atfork.c 2009-01-11 01:09:44.931848926 +0100
+++ uClibc-0.9.30/libpthread/linuxthreads/pthread_atfork.c 2009-01-11 01:12:49.926539743 +0100
@@ -43,12 +43,8 @@
/* Hide the symbol so that no definition but the one locally in the
executable or DSO is used. */
-int
-#ifndef __pthread_atfork
-/* Don't mark the compatibility function as hidden. */
-attribute_hidden
-#endif
-__pthread_atfork (prepare, parent, child)
+
+int attribute_hidden __pthread_atfork (prepare, parent, child)
void (*prepare) (void);
void (*parent) (void);
void (*child) (void);
@@ -56,8 +52,5 @@
return __register_atfork (prepare, parent, child,
&__dso_handle == NULL ? NULL : __dso_handle);
}
-#ifndef __pthread_atfork
-extern int pthread_atfork (void (*prepare) (void), void (*parent) (void),
- void (*child) (void)) attribute_hidden;
+
strong_alias (__pthread_atfork, pthread_atfork)
-#endif
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc