From 75311719d35dc0c132e46f883beaeb5b3d9eb75a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 28 Aug 1998 14:02:28 +0000 Subject: [PATCH] Update. 1998-08-28 13:58 Ulrich Drepper * internals.h: Also define THREAD_GETMEM_NC and THREAD_SETMEM_NC to access thread data with non-constant offsets. * specific.c: Use THREAD_GETMEM_NC and THREAD_SETMEM_NC where necessary. * sysdeps/i386/useldt.h: Fix typo. Add THREAD_GETMEM_NC and THREAD_SETMEM_NC definitions. * sysdeps/sparc/sparc32/pt-machine.h: Define THREAD_GETMEM_NC and THREAD_SETMEM_NC. * sysdeps/sparc/sparc64/pt-machine.h: Likewise. --- linuxthreads/ChangeLog | 14 +++++++ linuxthreads/internals.h | 6 +++ linuxthreads/specific.c | 28 +++++++------- linuxthreads/sysdeps/i386/useldt.h | 50 ++++++++++++++++++++++++- linuxthreads/sysdeps/sparc/sparc32/pt-machine.h | 2 + linuxthreads/sysdeps/sparc/sparc64/pt-machine.h | 2 + 6 files changed, 86 insertions(+), 16 deletions(-) diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 00f52d6..b8cad4c 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,17 @@ +1998-08-28 13:58 Ulrich Drepper + + * internals.h: Also define THREAD_GETMEM_NC and THREAD_SETMEM_NC to + access thread data with non-constant offsets. + * specific.c: Use THREAD_GETMEM_NC and THREAD_SETMEM_NC where + necessary. + + * sysdeps/i386/useldt.h: Fix typo. Add THREAD_GETMEM_NC and + THREAD_SETMEM_NC definitions. + + * sysdeps/sparc/sparc32/pt-machine.h: Define THREAD_GETMEM_NC and + THREAD_SETMEM_NC. + * sysdeps/sparc/sparc64/pt-machine.h: Likewise. + 1998-08-26 15:46 Ulrich Drepper * internals.h: Define THREAD_GETMEM and THREAD_SETMEM to default if diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h index d418fe2..d11cf84 100644 --- a/linuxthreads/internals.h +++ b/linuxthreads/internals.h @@ -28,9 +28,15 @@ #ifndef THREAD_GETMEM # define THREAD_GETMEM(descr, member) descr->member #endif +#ifndef THREAD_GETMEM_NC +# define THREAD_GETMEM_NC(descr, member) descr->member +#endif #ifndef THREAD_SETMEM # define THREAD_SETMEM(descr, member, value) descr->member = (value) #endif +#ifndef THREAD_SETMEM_NC +# define THREAD_SETMEM_NC(descr, member, value) descr->member = (value) +#endif /* Arguments passed to thread creation routine */ diff --git a/linuxthreads/specific.c b/linuxthreads/specific.c index 4ebbad7..2df477a 100644 --- a/linuxthreads/specific.c +++ b/linuxthreads/specific.c @@ -99,13 +99,13 @@ int __pthread_setspecific(pthread_key_t key, const void * pointer) return EINVAL; idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; - if (THREAD_GETMEM(self, p_specific[idx1st]) == NULL) { - THREAD_SETMEM(self, p_specific[idx1st], - calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *))); - if (THREAD_GETMEM(self, p_specific[idx1st]) == NULL) + if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL) { + void *newp = calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *)); + if (newp == NULL) return ENOMEM; + THREAD_SETMEM_NC(self, p_specific[idx1st], newp); } - THREAD_GETMEM(self, p_specific[idx1st])[idx2nd] = (void *) pointer; + THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd] = (void *) pointer; return 0; } weak_alias (__pthread_setspecific, pthread_setspecific) @@ -121,10 +121,10 @@ void * __pthread_getspecific(pthread_key_t key) return NULL; idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; - if (THREAD_GETMEM(self, p_specific[idx1st]) == NULL + if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL || !pthread_keys[key].in_use) return NULL; - return THREAD_GETMEM(self, p_specific[idx1st])[idx2nd]; + return THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd]; } weak_alias (__pthread_getspecific, pthread_getspecific) @@ -142,20 +142,20 @@ void __pthread_destroy_specifics() round++) { found_nonzero = 0; for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) - if (THREAD_GETMEM(self, p_specific[i]) != NULL) + if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) for (j = 0; j < PTHREAD_KEY_2NDLEVEL_SIZE; j++) { destr = pthread_keys[i * PTHREAD_KEY_2NDLEVEL_SIZE + j].destr; - data = THREAD_GETMEM(self, p_specific[i])[j]; + data = THREAD_GETMEM_NC(self, p_specific[i])[j]; if (destr != NULL && data != NULL) { - THREAD_GETMEM(self, p_specific[i])[j] = NULL; + THREAD_GETMEM_NC(self, p_specific[i])[j] = NULL; destr(data); found_nonzero = 1; } } } for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) { - if (THREAD_GETMEM(self, p_specific[i]) != NULL) - free(THREAD_GETMEM(self, p_specific[i])); + if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) + free(THREAD_GETMEM_NC(self, p_specific[i])); } } @@ -165,7 +165,7 @@ int __libc_internal_tsd_set(enum __libc_tsd_key_t key, const void * pointer) { pthread_descr self = thread_self(); - THREAD_SETMEM(self, p_libc_specific[key], (void *) pointer); + THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer); return 0; } @@ -173,5 +173,5 @@ void * __libc_internal_tsd_get(enum __libc_tsd_key_t key) { pthread_descr self = thread_self(); - return THREAD_GETMEM(self, p_libc_specific[key]); + return THREAD_GETMEM_NC(self, p_libc_specific[key]); } diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h index 53cf522..1a789e2 100644 --- a/linuxthreads/sysdeps/i386/useldt.h +++ b/linuxthreads/sysdeps/i386/useldt.h @@ -82,7 +82,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); ({ \ __typeof__ (descr->member) __value; \ if (sizeof (__value) == 1) \ - __asm__ __volatile__ ("movb %%gs:%P1,%b0" \ + __asm__ __volatile__ ("movb %%gs:%P2,%b0" \ : "=r" (__value) \ : "0" (0), \ "i" (offsetof (struct _pthread_descr_struct, \ @@ -101,7 +101,31 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); __value; \ }) -/* Set member of the thread descriptor directly. */ +/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +#define THREAD_GETMEM_NC(descr, member) \ +({ \ + __typeof__ (descr->member) __value; \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %%gs:(%2),%b0" \ + : "=r" (__value) \ + : "0" (0), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 4) \ + /* There should not be any value with a size other than 1 or 4. */ \ + abort (); \ + \ + __asm__ __volatile__ ("movl %%gs:(%1),%0" \ + : "=r" (__value) \ + : "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + } \ + __value; \ +}) + +/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ #define THREAD_SETMEM(descr, member, value) \ ({ \ __typeof__ (descr->member) __value = (value); \ @@ -122,3 +146,25 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); member))); \ } \ }) + +/* Set member of the thread descriptor directly. */ +#define THREAD_SETMEM_NC(descr, member, value) \ +({ \ + __typeof__ (descr->member) __value = (value); \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %0,%%gs:(%1)" : \ + : "r" (__value), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 4) \ + /* There should not be any value with a size other than 1 or 4. */ \ + abort (); \ + \ + __asm__ __volatile__ ("movl %0,%%gs:(%1)" : \ + : "r" (__value), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + } \ +}) diff --git a/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h b/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h index 7eea8d4..894972d 100644 --- a/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h +++ b/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h @@ -56,4 +56,6 @@ register struct _pthread_descr_struct *__thread_self __asm__("%g6"); /* 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) diff --git a/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h b/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h index e94e1a5..24c2141 100644 --- a/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h +++ b/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h @@ -68,4 +68,6 @@ __compare_and_swap (long int *p, long int oldval, long int newval) /* 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) -- 2.7.4