mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 22:10:13 +00:00
* 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:
parent
c1bf9f14ab
commit
b5f13526e2
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user