2003-08-11  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* dlfcn/default.c (main): Cast dlsym loaded value to same type as main.
	Address passed to test_in_mod1 and test_in_mod2 without casting.
	* dlfcn/defaultmod1.c: Change prototype of test_in_mod1.
	(test_in_mod1): Cast dlsym loaded value to same type as mainp.
	* dlfcn/defaultmod2.c: Change prototype of test_in_mod2.
	(test_in_mod2): Cast dlsym loaded value to same type as mainp.

2003-08-15  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/sparc/sparc32/elf/configure.in (libc_cv_sparc32_tls):
	Change quotes before using [].

	* sysdeps/unix/sysv/linux/sparc/sys/user.h: New file.

	* sysdeps/sparc/sparc32/bits/atomic.h (__sparc32_atomic_lock):
	Renamed to...
	(__sparc32_atomic_locks): ...this.  Change into 64-byte array.
	(__sparc32_atomic_do_lock, __sparc32_atomic_do_unlock): Add addr
	argument.  Select one of 64 locks from address bits.
	(atomic_compare_and_exchange_val_acq,
	atomic_compare_and_exchange_bool_acq): Pass memory address to
	__sparc32_atomic_do_{,un}lock.
This commit is contained in:
Ulrich Drepper 2003-08-15 03:58:56 +00:00
parent 1ee598e6cd
commit d57a3f0e02
7 changed files with 138 additions and 22 deletions

View File

@ -1,3 +1,28 @@
2003-08-11 Carlos O'Donell <carlos@baldric.uwo.ca>
* dlfcn/default.c (main): Cast dlsym loaded value to same type as main.
Address passed to test_in_mod1 and test_in_mod2 without casting.
* dlfcn/defaultmod1.c: Change prototype of test_in_mod1.
(test_in_mod1): Cast dlsym loaded value to same type as mainp.
* dlfcn/defaultmod2.c: Change prototype of test_in_mod2.
(test_in_mod2): Cast dlsym loaded value to same type as mainp.
2003-08-15 Jakub Jelinek <jakub@redhat.com>
* sysdeps/sparc/sparc32/elf/configure.in (libc_cv_sparc32_tls):
Change quotes before using [].
* sysdeps/unix/sysv/linux/sparc/sys/user.h: New file.
* sysdeps/sparc/sparc32/bits/atomic.h (__sparc32_atomic_lock):
Renamed to...
(__sparc32_atomic_locks): ...this. Change into 64-byte array.
(__sparc32_atomic_do_lock, __sparc32_atomic_do_unlock): Add addr
argument. Select one of 64 locks from address bits.
(atomic_compare_and_exchange_val_acq,
atomic_compare_and_exchange_bool_acq): Pass memory address to
__sparc32_atomic_do_{,un}lock.
2003-08-14 Ulrich Drepper <drepper@redhat.com> 2003-08-14 Ulrich Drepper <drepper@redhat.com>
* assert/assert.h (assert): Use !! in front of expression to allow * assert/assert.h (assert): Use !! in front of expression to allow

View File

@ -36,7 +36,7 @@ main (int argc, char *argv[])
printf ("%s: main not found\n", __FILE__); printf ("%s: main not found\n", __FILE__);
result = 1; result = 1;
} }
else if (p != (void *) &main) else if ((int (*)(int, char **))p != main)
{ {
printf ("%s: wrong address returned for main\n", __FILE__); printf ("%s: wrong address returned for main\n", __FILE__);
result = 1; result = 1;
@ -72,9 +72,9 @@ main (int argc, char *argv[])
else else
printf ("%s: found_in_mod2 correctly found\n", __FILE__); printf ("%s: found_in_mod2 correctly found\n", __FILE__);
result |= test_in_mod1 ((void *) &main); result |= test_in_mod1 (main);
result |= test_in_mod2 ((void *) &main); result |= test_in_mod2 (main);
return result; return result;
} }

View File

@ -9,9 +9,9 @@ found_in_mod1 (void)
} }
extern int test_in_mod1 (void *mainp); extern int test_in_mod1 (int (*mainp)(int, char **));
int int
test_in_mod1 (void *mainp) test_in_mod1 (int (*mainp)(int, char **))
{ {
int (*ifp) (void); int (*ifp) (void);
void *p; void *p;
@ -24,7 +24,7 @@ test_in_mod1 (void *mainp)
printf ("%s: main not found\n", __FILE__); printf ("%s: main not found\n", __FILE__);
result = 1; result = 1;
} }
else if (p != mainp) else if ((int (*)(int, char **))p != mainp)
{ {
printf ("%s: wrong address returned for main\n", __FILE__); printf ("%s: wrong address returned for main\n", __FILE__);
result = 1; result = 1;

View File

@ -16,9 +16,9 @@ found_in_mod2 (void)
} }
extern int test_in_mod2 (void *mainp); extern int test_in_mod2 (int (*mainp)(int, char **));
int int
test_in_mod2 (void *mainp) test_in_mod2 (int (*mainp)(int, char **))
{ {
int (*ifp) (void); int (*ifp) (void);
void *p; void *p;
@ -31,7 +31,7 @@ test_in_mod2 (void *mainp)
printf ("%s: main not found\n", __FILE__); printf ("%s: main not found\n", __FILE__);
result = 1; result = 1;
} }
else if (p != mainp) else if ((int (*)(int, char **))p != mainp)
{ {
printf ("%s: wrong address returned for main\n", __FILE__); printf ("%s: wrong address returned for main\n", __FILE__);
result = 1; result = 1;

View File

@ -22,28 +22,34 @@
#define _BITS_ATOMIC_H 1 #define _BITS_ATOMIC_H 1
/* We have no compare and swap, just test and set. /* We have no compare and swap, just test and set.
The following implementation contends on one single global lock The following implementation contends on 64 global locks
per library and assumes no variable will be accessed using atomic.h per library and assumes no variable will be accessed using atomic.h
macros from two different libraries. */ macros from two different libraries. */
volatile unsigned char __sparc32_atomic_lock volatile unsigned char __sparc32_atomic_locks[64]
__attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_lock"), __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_locks"),
visibility ("hidden"))); visibility ("hidden")));
#define __sparc32_atomic_do_lock() \ #define __sparc32_atomic_do_lock(addr) \
do \ do \
{ \ { \
unsigned int __old_lock; \ unsigned int __old_lock; \
unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \
& 63; \
do \ do \
__asm ("ldstub %1, %0" \ __asm ("ldstub %1, %0" \
: "=r" (__old_lock), "=m" (__sparc32_atomic_lock) \ : "=r" (__old_lock), \
: "m" (__sparc32_atomic_lock)); \ "=m" (__sparc32_atomic_locks[__idx]) \
: "m" (__sparc32_atomic_locks[__idx])); \
while (__old_lock); \ while (__old_lock); \
} \ } \
while (0) while (0)
#define __sparc32_atomic_do_unlock() \ #define __sparc32_atomic_do_unlock(addr) \
do __sparc32_atomic_lock = 0; while (0) do \
__sparc32_atomic_locks[(((long) addr >> 2) \
^ ((long) addr >> 12)) & 63] = 0; \
while (0)
/* The only basic operation needed is compare and exchange. */ /* The only basic operation needed is compare and exchange. */
#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
@ -51,11 +57,11 @@ volatile unsigned char __sparc32_atomic_lock
__typeof (*mem) __acev_ret; \ __typeof (*mem) __acev_ret; \
__typeof (*mem) __acev_newval = (newval); \ __typeof (*mem) __acev_newval = (newval); \
\ \
__sparc32_atomic_do_lock (); \ __sparc32_atomic_do_lock (__acev_memp); \
__acev_ret = *__acev_memp; \ __acev_ret = *__acev_memp; \
if (__acev_ret == (oldval)) \ if (__acev_ret == (oldval)) \
*__acev_memp = __acev_newval; \ *__acev_memp = __acev_newval; \
__sparc32_atomic_do_unlock (); \ __sparc32_atomic_do_unlock (__acev_memp); \
__acev_ret; }) __acev_ret; })
#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ #define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
@ -63,13 +69,13 @@ volatile unsigned char __sparc32_atomic_lock
int __aceb_ret; \ int __aceb_ret; \
__typeof (*mem) __aceb_newval = (newval); \ __typeof (*mem) __aceb_newval = (newval); \
\ \
__sparc32_atomic_do_lock (); \ __sparc32_atomic_do_lock (__aceb_memp); \
__aceb_ret = 0; \ __aceb_ret = 0; \
if (*__aceb_memp == (oldval)) \ if (*__aceb_memp == (oldval)) \
*__aceb_memp = __aceb_newval; \ *__aceb_memp = __aceb_newval; \
else \ else \
__aceb_ret = 1; \ __aceb_ret = 1; \
__sparc32_atomic_do_unlock (); \ __sparc32_atomic_do_unlock (__aceb_memp); \
__aceb_ret; }) __aceb_ret; })
#endif /* bits/atomic.h */ #endif /* bits/atomic.h */

View File

@ -29,7 +29,7 @@ baz: sethi %tgd_hi22(foo), %l1
add %o0, %l1, %l1, %tldo_add(bar) add %o0, %l1, %l1, %tldo_add(bar)
sethi %tie_hi22(foo), %l1 sethi %tie_hi22(foo), %l1
add %l1, %tie_lo10(foo), %l1 add %l1, %tie_lo10(foo), %l1
ld %l7 + %l1, %l1, %tie_ld(foo) ld [%l7 + %l1], %l1, %tie_ld(foo)
add %g7, %l1, %l1, %tie_add(foo) add %g7, %l1, %l1, %tie_add(foo)
sethi %tle_hix22(foo), %l1 sethi %tle_hix22(foo), %l1
xor %l1, %tle_lox10(foo), %l1 xor %l1, %tle_lox10(foo), %l1

View File

@ -0,0 +1,85 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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. */
#ifndef _SYS_USER_H
#define _SYS_USER_H 1
struct sunos_regs
{
unsigned int psr, pc, npc, y;
unsigned int regs[15];
};
struct sunos_fpqueue
{
unsigned int *addr;
unsigned int inst;
};
struct sunos_fp
{
union
{
unsigned int regs[32];
double reg_dbls[16];
} fregs;
unsigned int fsr;
unsigned int flags;
unsigned int extra;
unsigned int fpq_count;
struct sunos_fpqueue fpq[16];
};
struct sunos_fpu
{
struct sunos_fp fpstatus;
};
/* The SunOS core file header layout. */
struct user {
unsigned int magic;
unsigned int len;
struct sunos_regs regs;
struct
{
unsigned char a_dynamic :1;
unsigned char a_toolversion :7;
unsigned char a_machtype;
unsigned short a_info;
unsigned int a_text;
unsigned int a_data;
unsigned int a_bss;
unsigned int a_syms;
unsigned int a_entry;
unsigned int a_trsize;
unsigned int a_drsize;
} uexec;
int signal;
size_t u_tsize;
size_t u_dsize;
size_t u_ssize;
char u_comm[17];
struct sunos_fpu fpu;
unsigned int sigcode;
};
#define NBPG 0x2000
#define UPAGES 1
#define SUNOS_CORE_MAGIC 0x080456
#endif