linuxthreads for hppa (1/3)
PATCH 1/1 linuxthreads for hppa (1/3)
libc-alpha,
I've split linuxthreads for HPPA into 3 digestible patches:
1. Linuxthreads general changes.
2. Linuxthreads sysdep changes.
3. Linuxthreads changes for HPPA.
===
1. Linuxthreads general changes.
Tested on i386, Alpha, and HPPA. Debian has been using this code since 2.3.1. All of this code revolves around two central architecture issues:
a. HPPA needs an abstraction for it's atomic lock type. b. The lock type cannot be initialized to zero. c. HPPA's stack grows up.
NTPL and TLS are next on the plate for HPPA. Thanks for being patient.
Cheers,
Carlos
===
linuxthreads/descr.h | 2 linuxthreads/pt-machine.c | 4 - linuxthreads/spinlock.c | 22 +++--- linuxthreads/spinlock.h | 26 +++++-- linuxthreads/manager.c | 5 + linuxthreads/pthread.c | 36 +++++++--- 6 files changed, 66 insertions(+), 29 deletions(-)
===
2003-10-06 Carlos O'Donell <[email protected]>
* linuxthreads/descr.h: Define p_spinlock as __atomic_lock_t in struct pthread_atomic.
* linuxthreads/pt-machine.c: Define testandset to take __atomic_lock_t *spinlock.
* linuxthreads/pthread.c (__pthread_initialize_minimal):
Use __LT_INITIALIZER_NOT_ZERO instead of __LT_SPINLOCK_INIT. (__pthread_self_stack): _STACK_GROWS_UP case added. (__pthread_find_self): Likewise.
* linuxthreads/spinlock.c: __pthread_acquire call takes __atomic_lock_t *spinlock, define abandoned as __atomic_lock_t in struct wait_node, use __pthread_lock_define_initialized for wait_node_free_list.
(__pthread_alt_lock): Use __LT_SPINLOCK_INIT to clear abandoned. (__pthread_alt_timedlock): Likewise. (__pthread_alt_unlock): Use lock_held. (__pthread_release): Call takes __atomic_lock_t *spinlock. (__pthread_compare_and_swap): Likewise. (__pthread_acquire): Likewise.
* linuxthreads/spinlock.h: Define lock_held, define __pthread_lock_define_initialized for __LT_INITIALIZER_NOT_ZERO, __pthread_compare_and_swap takes __atomic_lock_t *spinlock. (compare_and_swap): All versions takes __atomic_lock_t *spinlock. (compare_and_swap_with_release_semantics): Likewise.
* linuxthreads/manager.c (thread_segment): _STACK_GROWS_UP case added.
linuxthreads/descr.h +1 -1
@@ -70,7 +70,7 @@/* Atomic counter made possible by compare_and_swap */ struct pthread_atomic {long p_count; -int p_spinlock; +__atomic_lock_t p_spinlock; };
linuxthreads/pt-machine.c +3 -1
@@ -19,7 +19,9 @@#define PT_EI -extern long int testandset (int *spinlock); +#include <pthread.h> + +extern long int testandset (__atomic_lock_t *spinlock);extern int __compare_and_swap (long int *p,long int oldval,long int newval);#include <pt-machine.h>
linuxthreads/pthread.c +26 -10
@@ -300,9 +300,9 @@ __pthread_initialize_minimal(void)pthread_descr self;/* First of all init __pthread_handles[0] and [1] if needed. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif # ifndef SHARED /* Unlike in the dynamically linked case the dynamic linker has not
@@ -370,7 +370,7 @@ cannot allocate TLS data structures for# endif /* self->p_start_args need not be initialized, it's all zero. */ self->p_userstack =1 ; -# if __LT_SPINLOCK_INIT !=0 +# ifdef __LT_INITIALIZER_NOT_ZERO self->p_resume_count = (struct pthread_atomic ) __ATOMIC_INITIALIZER;# endif self->p_alloca_cutoff = __MAX_ALLOCA_CUTOFF;
@@ -384,9 +384,9 @@ cannot allocate TLS data structures for#else /* USE_TLS */ /* First of all init __pthread_handles[0] and [1]. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif __pthread_handles[0 ].h_descr = &__pthread_initial_thread; __pthread_handles[1 ].h_descr = &__pthread_manager_thread;
@@ -893,7 +893,11 @@ pthread_descr __pthread_find_self(void)/* __pthread_handles[0] is the initial thread, __pthread_handles[1] is the manager threads handled specially in thread_self(), so start at 2 */ h = __pthread_handles +2 ; +# ifdef _STACK_GROWS_UP +while (! (sp >= (char *) h->h_descr && sp < h->h_descr->p_guardaddr)) h++; +# else while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++; +# endif return h->h_descr; }
@@ -905,16 +909,28 @@ pthread_descr __pthread_self_stack(void)pthread_handle h;if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos) -return manager_thread; +return manager_thread; + h = __pthread_handles +2 ; # ifdef USE_TLS +# ifdef _STACK_GROWS_UP + while (h->h_descr == NULL + || ! (sp >= (char *) h->h_descr->p_stackaddr && + sp < (char *) h->h_descr->p_guardaddr)) +# else while (h->h_descr == NULL - || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= h->h_bottom)) + || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= (char *) h->h_bottom)) +# endif h++; # else -while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) +# ifdef _STACK_GROWS_UP + while ( !(sp >= (char *) h->h_descr && sp < (char *) h->h_descr->p_guardaddr)) +# else + while ( !(sp <= (char *) h->h_descr && sp >= (char *) h->h_bottom)) +# endif h++; # endif + return h->h_descr; }
linuxthreads/spinlock.c +11 -11
@@ -24,9 +24,9 @@#include "spinlock.h" #include "restart.h" -static void __pthread_acquire (int * spinlock); +static void __pthread_acquire (__atomic_lock_t * spinlock); -static inline void __pthread_release (int * spinlock) +static inline void __pthread_release (__atomic_lock_t * spinlock) {WRITE_MEMORY_BARRIER (); *spinlock = __LT_SPINLOCK_INIT;
@@ -269,11 +269,11 @@struct wait_node {struct wait_node *next;/* Next node in null terminated linked list */ pthread_descr thr;/* The thread waiting with this node */ -int abandoned;/* Atomic flag */ +__atomic_lock_t abandoned;/* Atomic flag */ };static long wait_node_free_list; -static int wait_node_free_list_spinlock; +__pthread_lock_define_initialized (static, wait_node_free_list_spinlock);/* Allocate a new node from the head of the free list using an atomic operation, or else using malloc if that list is empty. A fundamental
@@ -376,7 +376,7 @@if (self ==NULL ) self =thread_self (); - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) lock->__status; wait_node.thr = self; lock->__status = (long ) &wait_node;
@@ -402,7 +402,7 @@ wait_node.thr = self; newstatus = (long ) &wait_node; } - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -451,7 +451,7 @@if (self ==NULL ) self =thread_self (); - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) lock->__status; p_wait_node->thr = self; lock->__status = (long ) p_wait_node;
@@ -474,7 +474,7 @@ p_wait_node->thr = self; newstatus = (long ) p_wait_node; } - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -574,7 +574,7 @@while (p_node != (struct wait_node *)1 ) {int prio; -if (p_node->abandoned) { +if (lock_held (&p_node->abandoned)) {/* Remove abandoned node. */ #if definedTEST_FOR_COMPARE_AND_SWAP if (!__pthread_has_cas)
@@ -662,7 +662,7 @@#if !definedHAS_COMPARE_AND_SWAP || definedTEST_FOR_COMPARE_AND_SWAP int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {int res;
@@ -699,7 +699,7 @@- When nanosleep() returns, we try again, doing MAX_SPIN_COUNT sched_yield(), then sleeping again if needed. */ -static void __pthread_acquire (int * spinlock) +static void __pthread_acquire (__atomic_lock_t * spinlock) {int cnt =0 ;struct timespec tm;
linuxthreads/spinlock.h +20 -6
@@ -33,14 +33,28 @@#endif #endif +/* Define lock_held for all arches that don't need a modified copy. */ +#ifndef __LT_INITIALIZER_NOT_ZERO +# define lock_held (p) *(p) +#endif + +/* Initliazers for possibly complex structures */ +#ifdef __LT_INITIALIZER_NOT_ZERO +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME = __LT_SPINLOCK_ALT_INIT +#else +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME +#endif +#if defined(TEST_FOR_COMPARE_AND_SWAP )extern int __pthread_has_cas;extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {if (__builtin_expect (__pthread_has_cas,1 ))return __compare_and_swap (ptr, oldval, newval);
@@ -58,7 +72,7 @@static inline int compare_and_swap_with_release_semantics (long * ptr,long oldval, -long newval,int * spinlock) +long newval,__atomic_lock_t * spinlock) {return __compare_and_swap_with_release_semantics (ptr, oldval, newval);
@@ -67,7 +81,7 @@#endif static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __compare_and_swap (ptr, oldval, newval); }
@@ -75,10 +89,10 @@#else extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __pthread_compare_and_swap (ptr, oldval, newval, spinlock); }
linuxthreads/manager.c +5 -0
@@ -70,8 +70,13 @@ static pthread_descr manager_thread;#else static inline pthread_descr thread_segment (int seg) { +# ifdef _STACK_GROWS_UP +return (pthread_descr)(THREAD_STACK_START_ADDRESS + (seg -1 ) *STACK_SIZE ) + +1 ; +# else return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg -1 ) *STACK_SIZE ) -1 ; +# endif }#endif
PATCH 1/1 linuxthreads for hppa (1/3, Round 2)
libc-alpha,
Changes:
a. Removed _STACK_GROWS_UP changes.
b. Fixed formatting.
c. Fixed Changelog entry.
d. Added olsemaphore patch.
---
I've split linuxthreads for HPPA into 3 digestible patches:
1. Linuxthreads general changes.
2. Linuxthreads sysdep changes.
3. Linuxthreads changes for HPPA.
===
1. Linuxthreads general changes.
Tested on i386, Alpha, and HPPA. Debian has been using this code since 2.3.1. All of this code revolves around two central architecture issues:
a. HPPA needs an abstraction for it's atomic lock type. b. The lock type cannot be initialized to zero. c. HPPA's stack grows up.
NTPL and TLS are next on the plate for HPPA. Thanks for being patient.
Cheers,
Carlos
===
linuxthreads/descr.h | 2 linuxthreads/pt-machine.c | 4 + linuxthreads/pthread.c | 14 ++--- linuxthreads/spinlock.c | 22 ++++---- linuxthreads/spinlock.h | 26 +++++++--- linuxthreads/oldsemaphore.c | 2 6 files changed, 43 insertions(+), 27 deletions(-)
===
2003-10-12 Carlos O'Donell <[email protected]>
* descr.h: Define p_spinlock as __atomic_lock_t
in struct pthread_atomic.
* pt-machine.c: Define testandset to take __atomic_lock_t *spinlock.
* pthread.c (__pthread_initialize_minimal): Use __LT_INITIALIZER_NOT_ZERO instead of __LT_SPINLOCK_INIT.
* spinlock.c: __pthread_acquire call takes __atomic_lock_t *spinlock, define abandoned as __atomic_lock_t in struct wait_node, use __pthread_lock_define_initialized for wait_node_free_list.
(__pthread_alt_lock): Use __LT_SPINLOCK_INIT to clear abandoned. (__pthread_alt_timedlock): Likewise. (__pthread_alt_unlock): Use lock_held. (__pthread_release): Call takes __atomic_lock_t *spinlock. (__pthread_compare_and_swap): Likewise. (__pthread_acquire): Likewise.
* spinlock.h: Define lock_held, define __pthread_lock_define_initialized for __LT_INITIALIZER_NOT_ZERO, __pthread_compare_and_swap takes __atomic_lock_t *spinlock. (compare_and_swap): All versions takes __atomic_lock_t *spinlock. (compare_and_swap_with_release_semantics): Likewise.
* oldsemaphore.c: sem_spinlock in struct old_sem_t is an __atomic_lock_t.
linuxthreads/descr.h +1 -1
@@ -70,7 +70,7 @@/* Atomic counter made possible by compare_and_swap */ struct pthread_atomic {long p_count; -int p_spinlock; +__atomic_lock_t p_spinlock; };
linuxthreads/pt-machine.c +3 -1
@@ -19,7 +19,9 @@#define PT_EI -extern long int testandset (int *spinlock); +#include <pthread.h> + +extern long int testandset (__atomic_lock_t *spinlock);extern int __compare_and_swap (long int *p,long int oldval,long int newval);#include <pt-machine.h>
linuxthreads/pthread.c +7 -7
@@ -300,9 +300,9 @@ __pthread_initialize_minimal(void)pthread_descr self;/* First of all init __pthread_handles[0] and [1] if needed. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif # ifndef SHARED /* Unlike in the dynamically linked case the dynamic linker has not
@@ -370,7 +370,7 @@ cannot allocate TLS data structures for# endif /* self->p_start_args need not be initialized, it's all zero. */ self->p_userstack =1 ; -# if __LT_SPINLOCK_INIT !=0 +# ifdef __LT_INITIALIZER_NOT_ZERO self->p_resume_count = (struct pthread_atomic ) __ATOMIC_INITIALIZER;# endif self->p_alloca_cutoff = __MAX_ALLOCA_CUTOFF;
@@ -384,9 +384,9 @@ cannot allocate TLS data structures for#else /* USE_TLS */ /* First of all init __pthread_handles[0] and [1]. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif __pthread_handles[0 ].h_descr = &__pthread_initial_thread; __pthread_handles[1 ].h_descr = &__pthread_manager_thread;
linuxthreads/spinlock.c +11 -11
@@ -24,9 +24,9 @@#include "spinlock.h" #include "restart.h" -static void __pthread_acquire (int * spinlock); +static void __pthread_acquire (__atomic_lock_t * spinlock); -static inline void __pthread_release (int * spinlock) +static inline void __pthread_release (__atomic_lock_t * spinlock) {WRITE_MEMORY_BARRIER (); *spinlock = __LT_SPINLOCK_INIT;
@@ -269,11 +269,11 @@struct wait_node {struct wait_node *next;/* Next node in null terminated linked list */ pthread_descr thr;/* The thread waiting with this node */ -int abandoned;/* Atomic flag */ +__atomic_lock_t abandoned;/* Atomic flag */ };static long wait_node_free_list; -static int wait_node_free_list_spinlock; +__pthread_lock_define_initialized (static, wait_node_free_list_spinlock);/* Allocate a new node from the head of the free list using an atomic operation, or else using malloc if that list is empty. A fundamental
@@ -376,7 +376,7 @@if (self ==NULL ) self =thread_self (); - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) lock->__status; wait_node.thr = self; lock->__status = (long ) &wait_node;
@@ -402,7 +402,7 @@ wait_node.thr = self; newstatus = (long ) &wait_node; } - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -451,7 +451,7 @@if (self ==NULL ) self =thread_self (); - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) lock->__status; p_wait_node->thr = self; lock->__status = (long ) p_wait_node;
@@ -474,7 +474,7 @@ p_wait_node->thr = self; newstatus = (long ) p_wait_node; } - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -574,7 +574,7 @@while (p_node != (struct wait_node *)1 ) {int prio; -if (p_node->abandoned) { +if (lock_held (&p_node->abandoned)) {/* Remove abandoned node. */ #if definedTEST_FOR_COMPARE_AND_SWAP if (!__pthread_has_cas)
@@ -662,7 +662,7 @@#if !definedHAS_COMPARE_AND_SWAP || definedTEST_FOR_COMPARE_AND_SWAP int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {int res;
@@ -699,7 +699,7 @@- When nanosleep() returns, we try again, doing MAX_SPIN_COUNT sched_yield(), then sleeping again if needed. */ -static void __pthread_acquire (int * spinlock) +static void __pthread_acquire (__atomic_lock_t * spinlock) {int cnt =0 ;struct timespec tm;
linuxthreads/spinlock.h +20 -6
@@ -33,14 +33,28 @@#endif #endif +/* Define lock_held for all arches that don't need a modified copy. */ +#ifndef __LT_INITIALIZER_NOT_ZERO +# define lock_held (p) *(p) +#endif + +/* Initliazers for possibly complex structures */ +#ifdef __LT_INITIALIZER_NOT_ZERO +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME = __LT_SPINLOCK_ALT_INIT +#else +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME +#endif +#if defined(TEST_FOR_COMPARE_AND_SWAP )extern int __pthread_has_cas;extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {if (__builtin_expect (__pthread_has_cas,1 ))return __compare_and_swap (ptr, oldval, newval);
@@ -58,7 +72,7 @@static inline int compare_and_swap_with_release_semantics (long * ptr,long oldval, -long newval,int * spinlock) +long newval,__atomic_lock_t * spinlock) {return __compare_and_swap_with_release_semantics (ptr, oldval, newval);
@@ -67,7 +81,7 @@#endif static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __compare_and_swap (ptr, oldval, newval); }
@@ -75,10 +89,10 @@#else extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __pthread_compare_and_swap (ptr, oldval, newval, spinlock); }
linuxthreads/oldsemaphore.c +1 -1
@@ -31,7 +31,7 @@typedef struct {long int sem_status; -int sem_spinlock; +__atomic_lock_t sem_spinlock; }old_sem_t ;extern int __old_sem_init (old_sem_t *__sem,int __pshared,unsigned int __value);
PATCH 1/1 linuxthreads for hppa (1/3, Round 2)
In reply to Carlos O'Donelllibc-alpha,
Changes:
a. Removed _STACK_GROWS_UP changes.
b. Fixed formatting.
c. Fixed Changelog entry.
d. Added olsemaphore patch.
---
I've split linuxthreads for HPPA into 3 digestible patches:
1. Linuxthreads general changes.
2. Linuxthreads sysdep changes.
3. Linuxthreads changes for HPPA.
===
1. Linuxthreads general changes.
Tested on i386, Alpha, and HPPA. Debian has been using this code since 2.3.1. All of this code revolves around two central architecture issues:
a. HPPA needs an abstraction for it's atomic lock type. b. The lock type cannot be initialized to zero. c. HPPA's stack grows up.
NTPL and TLS are next on the plate for HPPA. Thanks for being patient.
Cheers,
Carlos
===
linuxthreads/descr.h | 2 linuxthreads/pt-machine.c | 4 + linuxthreads/pthread.c | 14 ++--- linuxthreads/spinlock.c | 22 ++++---- linuxthreads/spinlock.h | 26 +++++++--- linuxthreads/oldsemaphore.c | 2 6 files changed, 43 insertions(+), 27 deletions(-)
===
2003-10-12 Carlos O'Donell <[email protected]>
* descr.h: Define p_spinlock as __atomic_lock_t
in struct pthread_atomic.
* pt-machine.c: Define testandset to take __atomic_lock_t *spinlock.
* pthread.c (__pthread_initialize_minimal): Use __LT_INITIALIZER_NOT_ZERO instead of __LT_SPINLOCK_INIT.
* spinlock.c: __pthread_acquire call takes __atomic_lock_t *spinlock, define abandoned as __atomic_lock_t in struct wait_node, use __pthread_lock_define_initialized for wait_node_free_list.
(__pthread_alt_lock): Use __LT_SPINLOCK_INIT to clear abandoned. (__pthread_alt_timedlock): Likewise. (__pthread_alt_unlock): Use lock_held. (__pthread_release): Call takes __atomic_lock_t *spinlock. (__pthread_compare_and_swap): Likewise. (__pthread_acquire): Likewise.
* spinlock.h: Define lock_held, define __pthread_lock_define_initialized for __LT_INITIALIZER_NOT_ZERO, __pthread_compare_and_swap takes __atomic_lock_t *spinlock. (compare_and_swap): All versions takes __atomic_lock_t *spinlock. (compare_and_swap_with_release_semantics): Likewise.
* oldsemaphore.c: sem_spinlock in struct old_sem_t is an __atomic_lock_t.
linuxthreads/descr.h +1 -1
@@ -70,7 +70,7 @@/* Atomic counter made possible by compare_and_swap */ struct pthread_atomic {long p_count; -int p_spinlock; +__atomic_lock_t p_spinlock; };
linuxthreads/pt-machine.c +3 -1
@@ -19,7 +19,9 @@#define PT_EI -extern long int testandset (int *spinlock); +#include <pthread.h> + +extern long int testandset (__atomic_lock_t *spinlock);extern int __compare_and_swap (long int *p,long int oldval,long int newval);#include <pt-machine.h>
linuxthreads/pthread.c +7 -7
@@ -300,9 +300,9 @@ __pthread_initialize_minimal(void)pthread_descr self;/* First of all init __pthread_handles[0] and [1] if needed. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif # ifndef SHARED /* Unlike in the dynamically linked case the dynamic linker has not
@@ -370,7 +370,7 @@ cannot allocate TLS data structures for# endif /* self->p_start_args need not be initialized, it's all zero. */ self->p_userstack =1 ; -# if __LT_SPINLOCK_INIT !=0 +# ifdef __LT_INITIALIZER_NOT_ZERO self->p_resume_count = (struct pthread_atomic ) __ATOMIC_INITIALIZER;# endif self->p_alloca_cutoff = __MAX_ALLOCA_CUTOFF;
@@ -384,9 +384,9 @@ cannot allocate TLS data structures for#else /* USE_TLS */ /* First of all init __pthread_handles[0] and [1]. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif __pthread_handles[0 ].h_descr = &__pthread_initial_thread; __pthread_handles[1 ].h_descr = &__pthread_manager_thread;
linuxthreads/spinlock.c +11 -11
@@ -24,9 +24,9 @@#include "spinlock.h" #include "restart.h" -static void __pthread_acquire (int * spinlock); +static void __pthread_acquire (__atomic_lock_t * spinlock); -static inline void __pthread_release (int * spinlock) +static inline void __pthread_release (__atomic_lock_t * spinlock) {WRITE_MEMORY_BARRIER (); *spinlock = __LT_SPINLOCK_INIT;
@@ -269,11 +269,11 @@struct wait_node {struct wait_node *next;/* Next node in null terminated linked list */ pthread_descr thr;/* The thread waiting with this node */ -int abandoned;/* Atomic flag */ +__atomic_lock_t abandoned;/* Atomic flag */ };static long wait_node_free_list; -static int wait_node_free_list_spinlock; +__pthread_lock_define_initialized (static, wait_node_free_list_spinlock);/* Allocate a new node from the head of the free list using an atomic operation, or else using malloc if that list is empty. A fundamental
@@ -376,7 +376,7 @@if (self ==NULL ) self =thread_self (); - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) lock->__status; wait_node.thr = self; lock->__status = (long ) &wait_node;
@@ -402,7 +402,7 @@ wait_node.thr = self; newstatus = (long ) &wait_node; } - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -451,7 +451,7 @@if (self ==NULL ) self =thread_self (); - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) lock->__status; p_wait_node->thr = self; lock->__status = (long ) p_wait_node;
@@ -474,7 +474,7 @@ p_wait_node->thr = self; newstatus = (long ) p_wait_node; } - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -574,7 +574,7 @@while (p_node != (struct wait_node *)1 ) {int prio; -if (p_node->abandoned) { +if (lock_held (&p_node->abandoned)) {/* Remove abandoned node. */ #if definedTEST_FOR_COMPARE_AND_SWAP if (!__pthread_has_cas)
@@ -662,7 +662,7 @@#if !definedHAS_COMPARE_AND_SWAP || definedTEST_FOR_COMPARE_AND_SWAP int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {int res;
@@ -699,7 +699,7 @@- When nanosleep() returns, we try again, doing MAX_SPIN_COUNT sched_yield(), then sleeping again if needed. */ -static void __pthread_acquire (int * spinlock) +static void __pthread_acquire (__atomic_lock_t * spinlock) {int cnt =0 ;struct timespec tm;
linuxthreads/spinlock.h +20 -6
@@ -33,14 +33,28 @@#endif #endif +/* Define lock_held for all arches that don't need a modified copy. */ +#ifndef __LT_INITIALIZER_NOT_ZERO +# define lock_held (p) *(p) +#endif + +/* Initliazers for possibly complex structures */ +#ifdef __LT_INITIALIZER_NOT_ZERO +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME = __LT_SPINLOCK_ALT_INIT +#else +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME +#endif +#if defined(TEST_FOR_COMPARE_AND_SWAP )extern int __pthread_has_cas;extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {if (__builtin_expect (__pthread_has_cas,1 ))return __compare_and_swap (ptr, oldval, newval);
@@ -58,7 +72,7 @@static inline int compare_and_swap_with_release_semantics (long * ptr,long oldval, -long newval,int * spinlock) +long newval,__atomic_lock_t * spinlock) {return __compare_and_swap_with_release_semantics (ptr, oldval, newval);
@@ -67,7 +81,7 @@#endif static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __compare_and_swap (ptr, oldval, newval); }
@@ -75,10 +89,10 @@#else extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __pthread_compare_and_swap (ptr, oldval, newval, spinlock); }
linuxthreads/oldsemaphore.c +1 -1
@@ -31,7 +31,7 @@typedef struct {long int sem_status; -int sem_spinlock; +__atomic_lock_t sem_spinlock; }old_sem_t ;extern int __old_sem_init (old_sem_t *__sem,int __pshared,unsigned int __value);
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I think I've asked this before:
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.
Why? No unnecessary changes.
guardaddr))
linuxthreads/pthread.c pthread_descr __pthread_self_stack(void) · line 923
Quoted 5 lines
linuxthreads/pthread.c +3
-1+# else while (h->h_descr ==NULL - || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= h->h_bottom)) + || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= (char *) h->h_bottom)) +# endif
No unnecessary changes. Leave the code you're not using alone.
linuxthreads/pthread.c pthread_descr __pthread_self_stack(void) · line 926
Quoted 4 lines
h++; # elselinuxthreads/pthread.c +1
-1-while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) +# ifdef _STACK_GROWS_UP
And again.
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jNd02ijCOnn/RHQRAl6CAJ0Tv6yItJOX52RZu71GKSrGFUfMtACgnf6i Jy0mt+OERsR8N35JOFozwPU=
=kNiu
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I think I've asked this before:
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.
Why? No unnecessary changes.
guardaddr))
linuxthreads/pthread.c pthread_descr __pthread_self_stack(void) · line 923
Quoted 5 lines
linuxthreads/pthread.c +3
-1+# else while (h->h_descr ==NULL - || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= h->h_bottom)) + || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= (char *) h->h_bottom)) +# endif
No unnecessary changes. Leave the code you're not using alone.
linuxthreads/pthread.c pthread_descr __pthread_self_stack(void) · line 926
Quoted 4 lines
h++; # elselinuxthreads/pthread.c +1
-1-while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) +# ifdef _STACK_GROWS_UP
And again.
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jNd02ijCOnn/RHQRAl6CAJ0Tv6yItJOX52RZu71GKSrGFUfMtACgnf6i Jy0mt+OERsR8N35JOFozwPU=
=kNiu
-----END PGP SIGNATURE-----
Quoted 6 lines · Ulrich Drepper
I think I've asked this before:
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.Why? No unnecessary changes.
__LT_SPINLOCK_INIT is the value of the structure and used for initialization e.g. { 1, 1, 1, 1 }. It can no longer be used in a macro evaluation like "#if __LT_SPINLOCK_INIT". Instead the other macros was added.
Quoted 2 lines
No unnecessary changes. Leave the code you're not using alone. And again.
I made the mistake of adding my STACK_GROWS_UP fixes to this patch set. If you note I have submitted a "Round 2" set of patches that remove these changes.
Cheeers,
Carlos.
Quoted 6 lines · Ulrich Drepper
I think I've asked this before:
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.Why? No unnecessary changes.
__LT_SPINLOCK_INIT is the value of the structure and used for initialization e.g. { 1, 1, 1, 1 }. It can no longer be used in a macro evaluation like "#if __LT_SPINLOCK_INIT". Instead the other macros was added.
Quoted 2 lines
No unnecessary changes. Leave the code you're not using alone. And again.
I made the mistake of adding my STACK_GROWS_UP fixes to this patch set. If you note I have submitted a "Round 2" set of patches that remove these changes.
Cheeers,
Carlos.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 6 lines · Carlos O'Donell
Quoted 3 lines
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.Why? No unnecessary changes.
__LT_SPINLOCK_INITis the value of the structure and used for
The
- -# if __LT_SPINLOCK_INIT != 0
- - __pthread_handles[0].h_lock = __LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO
+ __pthread_handles[0].h_lock = __LOCK_ALT_INITIALIZER;
+ __pthread_handles[1].h_lock = __LOCK_ALT_INITIALIZER;
part is what I meant. There is no reason to change the name.
Look at your change, no changes of code which are not needed. Clean up the patches to follow the coding standard, preprocessor indentation, etc etc.
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jOGV2ijCOnn/RHQRAhQUAJ9/9i66NJnsUCcLb6eLUVOKIUXUzgCeOibq l0Nqbif38PD+KbJgZqJVq20=
=4y0s
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 6 lines · Carlos O'Donell
Quoted 3 lines
Quoted 1 line
Use
__LT_INITIALIZER_NOT_ZEROinstead of__LT_SPINLOCK_INIT.Why? No unnecessary changes.
__LT_SPINLOCK_INITis the value of the structure and used for
The
- -# if __LT_SPINLOCK_INIT != 0
- - __pthread_handles[0].h_lock = __LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO
+ __pthread_handles[0].h_lock = __LOCK_ALT_INITIALIZER;
+ __pthread_handles[1].h_lock = __LOCK_ALT_INITIALIZER;
part is what I meant. There is no reason to change the name.
Look at your change, no changes of code which are not needed. Clean up the patches to follow the coding standard, preprocessor indentation, etc etc.
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jOGV2ijCOnn/RHQRAhQUAJ9/9i66NJnsUCcLb6eLUVOKIUXUzgCeOibq l0Nqbif38PD+KbJgZqJVq20=
=4y0s
-----END PGP SIGNATURE-----
Ulrich,
Quoted 8 lines
- -# if
__LT_SPINLOCK_INIT!= 0
- - __pthread_handles[0].h_lock =__LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock =__LOCK_INITIALIZER;linuxthreads/pthread.c +3
-0+# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;part is what I meant. There is no reason to change the name.
How do you propose it be handled? All arches define __LT_SPINLOCK_INIT and thus it cannot be used to distinguish between the two cases. Why do we distinguish between the two cases? Because a structure as an initializer has two different assignments cases, one in which it is named and one which it is not.
Quoted 3 lines
Look at your change, no changes of code which are not needed. Clean up the patches to follow the coding standard, preprocessor indentation, etc etc.
I do apologize for the STACK_GROWS_UP patches being included, and rightly so I removed them. Thank you for applying those patches.
I will go over my patches again for coding standard, preprocessor indentation and other grievences. In most cases I have tried to follow the standard.
Cheers,
Carlos.
Ulrich,
Quoted 8 lines
- -# if
__LT_SPINLOCK_INIT!= 0
- - __pthread_handles[0].h_lock =__LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock =__LOCK_INITIALIZER;linuxthreads/pthread.c +3
-0+# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;part is what I meant. There is no reason to change the name.
How do you propose it be handled? All arches define __LT_SPINLOCK_INIT and thus it cannot be used to distinguish between the two cases. Why do we distinguish between the two cases? Because a structure as an initializer has two different assignments cases, one in which it is named and one which it is not.
Quoted 3 lines
Look at your change, no changes of code which are not needed. Clean up the patches to follow the coding standard, preprocessor indentation, etc etc.
I do apologize for the STACK_GROWS_UP patches being included, and rightly so I removed them. Thank you for applying those patches.
I will go over my patches again for coding standard, preprocessor indentation and other grievences. In most cases I have tried to follow the standard.
Cheers,
Carlos.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 10 lines · Carlos O'Donell
Ulrich,
Quoted 7 lines
- -# if
__LT_SPINLOCK_INIT!= 0
- - __pthread_handles[0].h_lock =__LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock =__LOCK_INITIALIZER;linuxthreads/pthread.c +3
-0+# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;
Quoted 4 lines
Quoted 1 line
part is what I meant. There is no reason to change the name.
How do you propose it be handled? All arches define
__LT_SPINLOCK_INIT
I'm talking about this __LOCK_INITIALIZER -> __LOCK_ALT_INITIALIZER change. Why do you claim the right to rename the symbol?
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jYW52ijCOnn/RHQRAsmEAJ0cmMRxfMlyduuTG9TQMnATJVRJQQCgu/Vy aL6qdcssSoUjY7D7oCnKXII=
=VzEk
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 10 lines · Carlos O'Donell
Ulrich,
Quoted 7 lines
- -# if
__LT_SPINLOCK_INIT!= 0
- - __pthread_handles[0].h_lock =__LOCK_INITIALIZER;
- - __pthread_handles[1].h_lock =__LOCK_INITIALIZER;linuxthreads/pthread.c +3
-0+# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;
Quoted 4 lines
Quoted 1 line
part is what I meant. There is no reason to change the name.
How do you propose it be handled? All arches define
__LT_SPINLOCK_INIT
I'm talking about this __LOCK_INITIALIZER -> __LOCK_ALT_INITIALIZER change. Why do you claim the right to rename the symbol?
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/jYW52ijCOnn/RHQRAsmEAJ0cmMRxfMlyduuTG9TQMnATJVRJQQCgu/Vy aL6qdcssSoUjY7D7oCnKXII=
=VzEk
-----END PGP SIGNATURE-----
Quoted 4 lines · Ulrich Drepper
Quoted 1 line
How do you propose it be handled? All arches define
__LT_SPINLOCK_INITI'm talking about this
__LOCK_INITIALIZER->__LOCK_ALT_INITIALIZERchange. Why do you claim the right to rename the symbol?
The original __LOCK_INITIALIZER did not have a cast to (int).
The new __LOCK_INITIALIZER does not have a cast to (struct _pthread_fastlock)
When using a structure in an assignment within a function the named initializer version is required, such that the constructor can setup the object. Instead of using __LOCK_INITIALIZER which is already expected to be of a certain type without a cast, I created __LOCK_ALT_INITIALIZER and made 2 changes instead of the 6 or more that would be required had I reversed the semantics.
The same logic applied when I defined __LT_SPINLOCK_ALT_INIT. In order to minimize changes the default behaviour is to use the named init, the ALT behaviour does not. The ALT case is hidden inside __pthread_lock_define_initialized and cannot use a cast.
Should you like, I could reverse the behaviour of the above __LOCK_ALT_INITIALIZER, but I would have to make changes to initspin.h and pthread.h so the initialization macros work.
My net is currently down and I cannot verify if initspin.h and pthread.h are the only files that would require changes.
In summary I chose the semantics to _minimize_ code change. If you prefer header changes over core .c file changes then I can reverse the semantics of __LOCK_INITIALIZER with that of the ALT version.
c.
Quoted 4 lines · Ulrich Drepper
Quoted 1 line
How do you propose it be handled? All arches define
__LT_SPINLOCK_INITI'm talking about this
__LOCK_INITIALIZER->__LOCK_ALT_INITIALIZERchange. Why do you claim the right to rename the symbol?
The original __LOCK_INITIALIZER did not have a cast to (int).
The new __LOCK_INITIALIZER does not have a cast to (struct _pthread_fastlock)
When using a structure in an assignment within a function the named initializer version is required, such that the constructor can setup the object. Instead of using __LOCK_INITIALIZER which is already expected to be of a certain type without a cast, I created __LOCK_ALT_INITIALIZER and made 2 changes instead of the 6 or more that would be required had I reversed the semantics.
The same logic applied when I defined __LT_SPINLOCK_ALT_INIT. In order to minimize changes the default behaviour is to use the named init, the ALT behaviour does not. The ALT case is hidden inside __pthread_lock_define_initialized and cannot use a cast.
Should you like, I could reverse the behaviour of the above __LOCK_ALT_INITIALIZER, but I would have to make changes to initspin.h and pthread.h so the initialization macros work.
My net is currently down and I cannot verify if initspin.h and pthread.h are the only files that would require changes.
In summary I chose the semantics to _minimize_ code change. If you prefer header changes over core .c file changes then I can reverse the semantics of __LOCK_INITIALIZER with that of the ALT version.
c.