* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h

(__lll_private_flag): Define.
	(lll_futex_wait): Define as a wrapper around lll_futex_timed_wait.
	(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Use
	__lll_private_flag.
	(lll_private_futex_wait, lll_private_futex_timedwait,
	lll_private_futex_wake): Define as wrapper around non-_private
	macros.
	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
	(__lll_private_flag): Define.
	(lll_futex_timed_wait, lll_futex_wake): Use __lll_private_flag.
	(lll_private_futex_wait, lll_private_futex_timedwait,
	lll_private_futex_wake): Define as wrapper around non-_private
	macros.
This commit is contained in:
Ulrich Drepper 2007-07-24 06:43:01 +00:00
parent c1bf9f14ab
commit b5f13526e2
5 changed files with 260 additions and 275 deletions

View File

@ -1012,6 +1012,34 @@ next_prime (uint32_t seed)
module name offset
(following last entry with step count 0)
*/
static struct hash_entry *hash_table;
static size_t hash_size;
/* Function to insert the names. */
static void name_insert (const void *nodep, VISIT value, int level)
{
struct name *name;
unsigned int idx;
unsigned int hval2;
if (value != leaf && value != postorder)
return;
name = *(struct name **) nodep;
idx = name->hashval % hash_size;
hval2 = 1 + name->hashval % (hash_size - 2);
while (hash_table[idx].string_offset != 0)
if ((idx += hval2) >= hash_size)
idx -= hash_size;
hash_table[idx].string_offset = strtaboffset (name->strent);
assert (name->module_idx != -1);
hash_table[idx].module_idx = name->module_idx;
}
static int
write_output (void)
{
@ -1019,8 +1047,6 @@ write_output (void)
char *string_table;
size_t string_table_size;
struct gconvcache_header header;
struct hash_entry *hash_table;
size_t hash_size;
struct module_entry *module_table;
char *extra_table;
char *cur_extra_table;
@ -1033,31 +1059,6 @@ write_output (void)
char tmpfname[(output_file == NULL ? sizeof finalname : output_file_len + 1)
+ strlen (".XXXXXX")];
/* Function to insert the names. */
auto void
name_insert (const void *nodep, VISIT value, int level)
{
struct name *name;
unsigned int idx;
unsigned int hval2;
if (value != leaf && value != postorder)
return;
name = *(struct name **) nodep;
idx = name->hashval % hash_size;
hval2 = 1 + name->hashval % (hash_size - 2);
while (hash_table[idx].string_offset != 0)
if ((idx += hval2) >= hash_size)
idx -= hash_size;
hash_table[idx].string_offset = strtaboffset (name->strent);
assert (name->module_idx != -1);
hash_table[idx].module_idx = name->module_idx;
}
/* Open the output file. */
if (output_file == NULL)
{

View File

@ -1936,6 +1936,137 @@ output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
return retval | ((elem->section->ruleidx & 0x7f) << 24);
}
/* If localedef is every threaded, this would need to be __thread var. */
static struct
{
struct obstack *weightpool;
struct obstack *extrapool;
struct obstack *indpool;
struct locale_collate_t *collate;
struct collidx_table *tablewc;
} atwc;
static void add_to_tablewc (uint32_t ch, struct element_t *runp);
static void
add_to_tablewc (uint32_t ch, struct element_t *runp)
{
if (runp->wcnext == NULL && runp->nwcs == 1)
{
int32_t weigthidx = output_weightwc (atwc.weightpool, atwc.collate,
runp);
collidx_table_add (atwc.tablewc, ch, weigthidx);
}
else
{
/* As for the singlebyte table, we recognize sequences and
compress them. */
struct element_t *lastp;
collidx_table_add (atwc.tablewc, ch,
-(obstack_object_size (atwc.extrapool)
/ sizeof (uint32_t)));
do
{
/* Store the current index in the weight table. We know that
the current position in the `extrapool' is aligned on a
32-bit address. */
int32_t weightidx;
int added;
/* Find out wether this is a single entry or we have more than
one consecutive entry. */
if (runp->wcnext != NULL
&& runp->nwcs == runp->wcnext->nwcs
&& wmemcmp ((wchar_t *) runp->wcs,
(wchar_t *)runp->wcnext->wcs,
runp->nwcs - 1) == 0
&& (runp->wcs[runp->nwcs - 1]
== runp->wcnext->wcs[runp->nwcs - 1] + 1))
{
int i;
struct element_t *series_startp = runp;
struct element_t *curp;
/* Now add first the initial byte sequence. */
added = (1 + 1 + 2 * (runp->nwcs - 1)) * sizeof (int32_t);
if (sizeof (int32_t) == sizeof (int))
obstack_make_room (atwc.extrapool, added);
/* More than one consecutive entry. We mark this by having
a negative index into the indirect table. */
obstack_int32_grow_fast (atwc.extrapool,
-(obstack_object_size (atwc.indpool)
/ sizeof (int32_t)));
obstack_int32_grow_fast (atwc.extrapool, runp->nwcs - 1);
do
runp = runp->wcnext;
while (runp->wcnext != NULL
&& runp->nwcs == runp->wcnext->nwcs
&& wmemcmp ((wchar_t *) runp->wcs,
(wchar_t *)runp->wcnext->wcs,
runp->nwcs - 1) == 0
&& (runp->wcs[runp->nwcs - 1]
== runp->wcnext->wcs[runp->nwcs - 1] + 1));
/* Now walk backward from here to the beginning. */
curp = runp;
for (i = 1; i < runp->nwcs; ++i)
obstack_int32_grow_fast (atwc.extrapool, curp->wcs[i]);
/* Now find the end of the consecutive sequence and
add all the indeces in the indirect pool. */
do
{
weightidx = output_weightwc (atwc.weightpool, atwc.collate,
curp);
obstack_int32_grow (atwc.indpool, weightidx);
curp = curp->wclast;
}
while (curp != series_startp);
/* Add the final weight. */
weightidx = output_weightwc (atwc.weightpool, atwc.collate,
curp);
obstack_int32_grow (atwc.indpool, weightidx);
/* And add the end byte sequence. Without length this
time. */
for (i = 1; i < curp->nwcs; ++i)
obstack_int32_grow (atwc.extrapool, curp->wcs[i]);
}
else
{
/* A single entry. Simply add the index and the length and
string (except for the first character which is already
tested for). */
int i;
/* Output the weight info. */
weightidx = output_weightwc (atwc.weightpool, atwc.collate,
runp);
added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t);
if (sizeof (int) == sizeof (int32_t))
obstack_make_room (atwc.extrapool, added);
obstack_int32_grow_fast (atwc.extrapool, weightidx);
obstack_int32_grow_fast (atwc.extrapool, runp->nwcs - 1);
for (i = 1; i < runp->nwcs; ++i)
obstack_int32_grow_fast (atwc.extrapool, runp->wcs[i]);
}
/* Next entry. */
lastp = runp;
runp = runp->wcnext;
}
while (runp != NULL);
}
}
void
collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
@ -2293,132 +2424,21 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
with the same wide character and add them one after the other to
the table. In case we have more than one sequence starting with
the same byte we have to use extra indirection. */
{
auto void add_to_tablewc (uint32_t ch, struct element_t *runp);
tablewc.p = 6;
tablewc.q = 10;
collidx_table_init (&tablewc);
void add_to_tablewc (uint32_t ch, struct element_t *runp)
{
if (runp->wcnext == NULL && runp->nwcs == 1)
{
int32_t weigthidx = output_weightwc (&weightpool, collate, runp);
collidx_table_add (&tablewc, ch, weigthidx);
}
else
{
/* As for the singlebyte table, we recognize sequences and
compress them. */
struct element_t *lastp;
atwc.weightpool = &weightpool;
atwc.extrapool = &extrapool;
atwc.indpool = &indirectpool;
atwc.collate = collate;
atwc.tablewc = &tablewc;
collidx_table_add (&tablewc, ch,
-(obstack_object_size (&extrapool) / sizeof (uint32_t)));
wchead_table_iterate (&collate->wcheads, add_to_tablewc);
do
{
/* Store the current index in the weight table. We know that
the current position in the `extrapool' is aligned on a
32-bit address. */
int32_t weightidx;
int added;
memset (&atwc, 0, sizeof (atwc));
/* Find out wether this is a single entry or we have more than
one consecutive entry. */
if (runp->wcnext != NULL
&& runp->nwcs == runp->wcnext->nwcs
&& wmemcmp ((wchar_t *) runp->wcs,
(wchar_t *)runp->wcnext->wcs,
runp->nwcs - 1) == 0
&& (runp->wcs[runp->nwcs - 1]
== runp->wcnext->wcs[runp->nwcs - 1] + 1))
{
int i;
struct element_t *series_startp = runp;
struct element_t *curp;
/* Now add first the initial byte sequence. */
added = (1 + 1 + 2 * (runp->nwcs - 1)) * sizeof (int32_t);
if (sizeof (int32_t) == sizeof (int))
obstack_make_room (&extrapool, added);
/* More than one consecutive entry. We mark this by having
a negative index into the indirect table. */
obstack_int32_grow_fast (&extrapool,
-(obstack_object_size (&indirectpool)
/ sizeof (int32_t)));
obstack_int32_grow_fast (&extrapool, runp->nwcs - 1);
do
runp = runp->wcnext;
while (runp->wcnext != NULL
&& runp->nwcs == runp->wcnext->nwcs
&& wmemcmp ((wchar_t *) runp->wcs,
(wchar_t *)runp->wcnext->wcs,
runp->nwcs - 1) == 0
&& (runp->wcs[runp->nwcs - 1]
== runp->wcnext->wcs[runp->nwcs - 1] + 1));
/* Now walk backward from here to the beginning. */
curp = runp;
for (i = 1; i < runp->nwcs; ++i)
obstack_int32_grow_fast (&extrapool, curp->wcs[i]);
/* Now find the end of the consecutive sequence and
add all the indeces in the indirect pool. */
do
{
weightidx = output_weightwc (&weightpool, collate,
curp);
obstack_int32_grow (&indirectpool, weightidx);
curp = curp->wclast;
}
while (curp != series_startp);
/* Add the final weight. */
weightidx = output_weightwc (&weightpool, collate, curp);
obstack_int32_grow (&indirectpool, weightidx);
/* And add the end byte sequence. Without length this
time. */
for (i = 1; i < curp->nwcs; ++i)
obstack_int32_grow (&extrapool, curp->wcs[i]);
}
else
{
/* A single entry. Simply add the index and the length and
string (except for the first character which is already
tested for). */
int i;
/* Output the weight info. */
weightidx = output_weightwc (&weightpool, collate, runp);
added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t);
if (sizeof (int) == sizeof (int32_t))
obstack_make_room (&extrapool, added);
obstack_int32_grow_fast (&extrapool, weightidx);
obstack_int32_grow_fast (&extrapool, runp->nwcs - 1);
for (i = 1; i < runp->nwcs; ++i)
obstack_int32_grow_fast (&extrapool, runp->wcs[i]);
}
/* Next entry. */
lastp = runp;
runp = runp->wcnext;
}
while (runp != NULL);
}
}
tablewc.p = 6;
tablewc.q = 10;
collidx_table_init (&tablewc);
wchead_table_iterate (&collate->wcheads, add_to_tablewc);
collidx_table_finalize (&tablewc);
}
collidx_table_finalize (&tablewc);
/* Now add the four tables. */
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC));

View File

@ -1,3 +1,20 @@
2007-07-23 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
(__lll_private_flag): Define.
(lll_futex_wait): Define as a wrapper around lll_futex_timed_wait.
(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Use
__lll_private_flag.
(lll_private_futex_wait, lll_private_futex_timedwait,
lll_private_futex_wake): Define as wrapper around non-_private
macros.
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
(__lll_private_flag): Define.
(lll_futex_timed_wait, lll_futex_wake): Use __lll_private_flag.
(lll_private_futex_wait, lll_private_futex_timedwait,
lll_private_futex_wake): Define as wrapper around non-_private
macros.
2007-07-10 Steven Munroe <sjmunroe@us.ibm.com>
* pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Add LLL_SHARED

View File

@ -45,40 +45,55 @@
#define LLL_PRIVATE 0
#define LLL_SHARED FUTEX_PRIVATE_FLAG
#if !defined NOT_IN_libc || defined IS_IN_rtld
/* In libc.so or ld.so all futexes are private. */
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
((fl) | FUTEX_PRIVATE_FLAG)
# else
# define __lll_private_flag(fl, private) \
((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
# endif
#else
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
(((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
# else
# define __lll_private_flag(fl, private) \
(__builtin_constant_p (private) \
? ((private) == 0 \
? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
: (fl)) \
: ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
& THREAD_GETMEM (THREAD_SELF, header.private_futex))))
# endif
#endif
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
#define lll_futex_wait(futexp, val, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int opt_flags = (FUTEX_WAIT | LLL_SHARED) ^ private; \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), opt_flags, (val), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
lll_futex_timed_wait (futexp, val, NULL, private)
#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int opt_flags = (FUTEX_WAIT | LLL_SHARED) ^ private; \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), opt_flags, (val), (timespec)); \
__ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), (timespec)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
#define lll_futex_wake(futexp, nr, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int opt_flags = (FUTEX_WAKE | LLL_SHARED) ^ private; \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), opt_flags, (nr), 0); \
__ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAKE, private), \
(nr), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
@ -109,66 +124,24 @@
#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int opt_flags = (FUTEX_WAKE_OP | LLL_SHARED) ^ private; \
long int opt_flag2 = (FUTEX_OP_CLEAR_WAKE_IF_GT_ONE | LLL_SHARED) \
^ private; \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 6, \
(futexp), opt_flags, (nr_wake), \
(nr_wake2), (futexp2), \
opt_flag2); \
__ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
__lll_private_flag (FUTEX_WAKE_OP, private), \
(nr_wake), (nr_wake2), (futexp2), \
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
#define lll_private_futex_wait(futexp, val) \
lll_private_futex_timed_wait (futexp, val, NULL)
lll_futex_timed_wait (futexp, val, NULL, LLL_PRIVATE)
#define lll_private_futex_timed_wait(futexp, val, timeout) \
lll_futex_timed_wait (futexp, val, timeout, LLL_PRIVATE)
#ifdef __ASSUME_PRIVATE_FUTEX
# define lll_private_futex_timed_wait(futexp, val, timeout) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), (FUTEX_WAIT | FUTEX_PRIVATE_FLAG), \
(val), (timeout)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
# define lll_private_futex_wake(futexp, val) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), (FUTEX_WAKE | FUTEX_PRIVATE_FLAG), \
(val), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
#else
# define lll_private_futex_timed_wait(futexp, val, timeout) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAIT, (val), (timeout)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
# define lll_private_futex_wake(futexp, val) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAKE, (val), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
#endif
#define lll_private_futex_wake(futexp, val) \
lll_futex_wake (futexp, val, LLL_PRIVATE)
#ifdef UP
# define __lll_acq_instr ""

View File

@ -50,6 +50,31 @@
#define LLL_PRIVATE 0
#define LLL_SHARED FUTEX_PRIVATE_FLAG
#if !defined NOT_IN_libc || defined IS_IN_rtld
/* In libc.so or ld.so all futexes are private. */
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
((fl) | FUTEX_PRIVATE_FLAG)
# else
# define __lll_private_flag(fl, private) \
((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
# endif
#else
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
(((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
# else
# define __lll_private_flag(fl, private) \
(__builtin_constant_p (private) \
? ((private) == 0 \
? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
: (fl)) \
: ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
asm ("andl %%fs:%P1, %0" : "+r" (__fl) \
: "i" offsetof (struct pthread, header.private_futex)); \
__fl | (fl); })
# endif
#endif
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
@ -169,7 +194,8 @@ LLL_STUB_UNWIND_INFO_END
register __typeof (val) _val __asm ("edx") = (val); \
__asm __volatile ("syscall" \
: "=a" (__status) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
: "0" (SYS_futex), "D" (futex), \
"S" (__lll_private_flag (FUTEX_WAIT, private)), \
"d" (_val), "r" (__to) \
: "memory", "cc", "r11", "cx"); \
__status; \
@ -182,73 +208,21 @@ LLL_STUB_UNWIND_INFO_END
register __typeof (nr) _nr __asm ("edx") = (nr); \
__asm __volatile ("syscall" \
: "=a" (__ignore) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \
: "0" (SYS_futex), "D" (futex), \
"S" (__lll_private_flag (FUTEX_WAKE, private)), \
"d" (_nr) \
: "memory", "cc", "r10", "r11", "cx"); \
} while (0)
#define lll_private_futex_wait(futex, val) \
lll_private_futex_timed_wait (futex, val, NULL)
lll_futex_timed_wait (futex, val, NULL, LLL_PRIVATE)
#define lll_private_futex_timed_wait(futex, val, timeout) \
lll_futex_timed_wait (futex, val, timeout, LLL_PRIVATE)
#ifdef __ASSUME_PRIVATE_FUTEX
# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
register const struct timespec *__to __asm ("r10") = timeout; \
int __status; \
register __typeof (val) _val __asm ("edx") = (val); \
__asm __volatile ("syscall" \
: "=a" (__status) \
: "0" (SYS_futex), "D" (futex), \
"S" (FUTEX_WAIT | FUTEX_PRIVATE_FLAG), \
"d" (_val), "r" (__to) \
: "memory", "cc", "r11", "cx"); \
__status; \
})
# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
register __typeof (nr) _nr __asm ("edx") = (nr); \
__asm __volatile ("syscall" \
: "=a" (__ignore) \
: "0" (SYS_futex), "D" (futex), \
"S" (FUTEX_WAKE | FUTEX_PRIVATE_FLAG), \
"d" (_nr) \
: "memory", "cc", "r10", "r11", "cx"); \
} while (0)
#else
# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
register const struct timespec *__to __asm ("r10") = timeout; \
int __status; \
int __ignore; \
register __typeof (val) _val __asm ("edx") = (val); \
__asm __volatile ("movl %%fs:%P3, %%esi\n\t" \
"syscall" \
: "=a" (__status), "=S" (__ignore) \
: "0" (SYS_futex), "i" (PRIVATE_FUTEX), "D" (futex), \
"d" (_val), "r" (__to) \
: "memory", "cc", "r11", "cx"); \
__status; \
})
# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
int __ignore2; \
register __typeof (nr) _nr __asm ("edx") = (nr); \
__asm __volatile ("orl %%fs:%P3, %%esi\n\t" \
"syscall" \
: "=a" (__ignore), "=S" (__ignore2) \
: "0" (SYS_futex), "i" (PRIVATE_FUTEX), "D" (futex), \
"1" (FUTEX_WAKE), "d" (_nr) \
: "memory", "cc", "r10", "r11", "cx"); \
} while (0)
#endif
#define lll_private_futex_wake(futex, nr) \
lll_futex_wake (futex, nr, LLL_PRIVATE)
/* Does not preserve %eax and %ecx. */