From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21749 invoked by alias); 25 May 2007 00:35:26 -0000 Received: (qmail 21716 invoked by uid 22791); 25 May 2007 00:35:11 -0000 X-Spam-Check-By: sourceware.org Received: from are.twiddle.net (HELO are.twiddle.net) (64.81.246.98) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 25 May 2007 00:35:04 +0000 Received: from are.twiddle.net (localhost.localdomain [127.0.0.1]) by are.twiddle.net (8.13.8/8.13.6) with ESMTP id l4P0Z2Nm004934 for ; Thu, 24 May 2007 17:35:02 -0700 Received: (from rth@localhost) by are.twiddle.net (8.13.8/8.13.8/Submit) id l4P0Z2TW004933 for libc-hacker@sources.redhat.com; Thu, 24 May 2007 17:35:02 -0700 Date: Fri, 25 May 2007 00:35:00 -0000 From: Richard Henderson To: libc-hacker@sources.redhat.com Subject: gscope + private_futex for alpha Message-ID: <20070525003502.GA4853@twiddle.net> Mail-Followup-To: libc-hacker@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2007-05/txt/msg00022.txt.bz2 It seems like much of this same code could be shared with all of the targets, particularly those that define TLS_DTV_AT_TP. r~ 2007-05-24 Richard Henderson * descr.h (struct pthread): Add header.gscope_flag and header.private_futex. * nptl/sysdeps/alpha/tls.h (THREAD_GSCOPE_FLAG_UNUSED): New. (THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT): New. (THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG): New. (THREAD_GSCOPE_WAIT): New. * nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_PRIVATE_FLAG): New. (lll_futex_wait_flags): New. * nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c (__pthread_once): Pass FUTEX_PRIVATE_FLAG or header.private_futex down to the futex call. Index: nptl/descr.h =================================================================== RCS file: /cvs/glibc/libc/nptl/descr.h,v retrieving revision 1.39 diff -u -p -d -r1.39 descr.h --- nptl/descr.h 11 May 2007 06:11:48 -0000 1.39 +++ nptl/descr.h 24 May 2007 23:49:08 -0000 @@ -131,6 +131,8 @@ struct pthread struct { int multiple_threads; + int gscope_flag; + int private_futex; } header; #endif Index: nptl/sysdeps/alpha/tls.h =================================================================== RCS file: /cvs/glibc/libc/nptl/sysdeps/alpha/tls.h,v retrieving revision 1.7 diff -u -p -d -r1.7 tls.h --- nptl/sysdeps/alpha/tls.h 27 Oct 2006 23:11:43 -0000 1.7 +++ nptl/sysdeps/alpha/tls.h 24 May 2007 23:49:08 -0000 @@ -121,6 +121,36 @@ typedef struct #define THREAD_SETMEM_NC(descr, member, idx, value) \ descr->member[idx] = (value) +/* Get and set the global scope generation counter in the TCB head. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 + +#define THREAD_GSCOPE_RESET_FLAG() \ + do { \ + int __res = atomic_exchange_rel(&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ + } while (0) + +#define THREAD_GSCOPE_SET_FLAG() \ + do { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + __sync_synchronize (); \ + } while (0) + +#ifdef PTR_DEMANGLE +# define THREAD_GSCOPE_WAIT() \ + do { \ + void (*ptr)(void) = GL(dl_wait_lookup_done); \ + PTR_DEMANGLE (ptr); \ + ptr (); \ + } while (0) +#else +# define THREAD_GSCOPE_WAIT() GL(dl_wait_lookup_done) () +#endif + #endif /* __ASSEMBLER__ */ #endif /* tls.h */ Index: nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h =================================================================== RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h,v retrieving revision 1.8 diff -u -p -d -r1.8 lowlevellock.h --- nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h 29 Jul 2006 05:06:07 -0000 1.8 +++ nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h 24 May 2007 23:49:08 -0000 @@ -36,6 +36,7 @@ #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 +#define FUTEX_PRIVATE_FLAG 128 /* Initializer for compatibility lock. */ #define LLL_MUTEX_LOCK_INITIALIZER (0) @@ -49,6 +50,15 @@ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \ }) +#define lll_futex_wait_flags(futexp, val, flags) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), FUTEX_WAIT | (flags), (val), 0); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \ + }) + #define lll_futex_timed_wait(futexp, val, timespec) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ Index: nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c =================================================================== RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c,v retrieving revision 1.2 diff -u -p -d -r1.2 pthread_once.c --- nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c 8 Sep 2004 06:11:35 -0000 1.2 +++ nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c 24 May 2007 23:49:08 -0000 @@ -34,6 +34,12 @@ clear_once_control (void *arg) int __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) { +#ifdef __ASSUME_PRIVATE_FUTEX + const int futex_private_flag = FUTEX_PRIVATE_FLAG; +#else + const int futex_private_flag = THREAD_SELF->header.private_futex; +#endif + for (;;) { int oldval; @@ -72,7 +78,7 @@ __pthread_once (pthread_once_t *once_con break; /* Same generation, some other thread was faster. Wait. */ - lll_futex_wait (once_control, oldval); + lll_futex_wait_flags (once_control, oldval, futex_private_flag); } /* This thread is the first here. Do the initialization.