292 lines
11 KiB
Diff
292 lines
11 KiB
Diff
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;
|
|
|