From ad3371fbac6896adc4820434676f35bd44a24cf8 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 28 Oct 2007 01:08:55 +0000 Subject: [PATCH] [BZ #5208] 2007-10-23 Andreas Jaeger [BZ #5208] * sysdeps/unix/sysv/linux/readahead.c (__readahead): Use __LONG_LONG_PAIR to handle little endian byte order. Suggested by abhishekrai@google.com --- ChangeLog | 7 +++++++ nptl/sysdeps/pthread/malloc-machine.h | 19 +++++++++++++++---- nptl/sysdeps/unix/sysv/linux/fork.h | 3 +++ .../sysdeps/unix/sysv/linux/register-atfork.c | 12 ++++++++++++ .../unix/sysv/linux/unregister-atfork.c | 13 ++++++++++++- sysdeps/unix/sysv/linux/readahead.c | 8 +++++--- 6 files changed, 54 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7bee03ecbe..c61158200b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-10-23 Andreas Jaeger + + [BZ #5208] + * sysdeps/unix/sysv/linux/readahead.c (__readahead): Use + __LONG_LONG_PAIR to handle little endian byte order. + Suggested by abhishekrai@google.com + 2007-10-27 Ulrich Drepper * malloc/arena.c [!NO_THREADS]: Use ATFORK_MEM if defined. diff --git a/nptl/sysdeps/pthread/malloc-machine.h b/nptl/sysdeps/pthread/malloc-machine.h index efab230aa8..33a3d20531 100644 --- a/nptl/sysdeps/pthread/malloc-machine.h +++ b/nptl/sysdeps/pthread/malloc-machine.h @@ -1,6 +1,6 @@ /* Basic platform-independent macro definitions for mutexes, thread-specific data and parameters for malloc. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2007 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 @@ -38,13 +38,24 @@ extern void *__dso_handle __attribute__ ((__weak__)); #include +#define ATFORK_MEM static struct fork_handler atfork_mem + #ifdef SHARED # define thread_atfork(prepare, parent, child) \ - __register_atfork (prepare, parent, child, __dso_handle) + atfork_mem.prepare_handler = prepare; \ + atfork_mem.parent_handler = parent; \ + atfork_mem.child_handler = child; \ + atfork_mem.dso_handle = __dso_handle; \ + atfork_mem.refcntr = 1; \ + __linkin_atfork (&atfork_mem) #else # define thread_atfork(prepare, parent, child) \ - __register_atfork (prepare, parent, child, \ - &__dso_handle == NULL ? NULL : __dso_handle) + atfork_mem.prepare_handler = prepare; \ + atfork_mem.parent_handler = parent; \ + atfork_mem.child_handler = child; \ + atfork_mem.dso_handle = &__dso_handle == NULL ? NULL : __dso_handle; \ + atfork_mem.refcntr = 1; \ + __linkin_atfork (&atfork_mem) #endif /* thread specific data for glibc */ diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h index 032b68f083..a00cfabe26 100644 --- a/nptl/sysdeps/unix/sysv/linux/fork.h +++ b/nptl/sysdeps/unix/sysv/linux/fork.h @@ -55,3 +55,6 @@ extern int __register_atfork (void (*__prepare) (void), void (*__child) (void), void *dso_handle); libc_hidden_proto (__register_atfork) + +/* Add a new element to the fork list. */ +extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden; diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/sysdeps/unix/sysv/linux/register-atfork.c index 231fc9b091..71abd0fb96 100644 --- a/nptl/sysdeps/unix/sysv/linux/register-atfork.c +++ b/nptl/sysdeps/unix/sysv/linux/register-atfork.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Lock to protect allocation and deallocation of fork handlers. */ @@ -109,6 +110,17 @@ __register_atfork (prepare, parent, child, dso_handle) libc_hidden_def (__register_atfork) +void +attribute_hidden +__linkin_atfork (struct fork_handler *newp) +{ + do + newp->next = __fork_handlers; + while (catomic_compare_and_exchange_bool_acq (&__fork_handlers, + newp, newp->next) != 0); +} + + libc_freeres_fn (free_mem) { /* Get the lock to not conflict with running forks. */ diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c index 56a4f149e1..c738acd0c3 100644 --- a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c +++ b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c @@ -67,10 +67,21 @@ __unregister_atfork (dso_handle) It's a single linked list so readers are. */ do { + again: if (runp->dso_handle == dso_handle) { if (lastp == NULL) - __fork_handlers = runp->next; + { + /* We have to use an atomic operation here because + __linkin_atfork also uses one. */ + if (catomic_compare_and_exchange_bool_acq (&__fork_handlers, + runp->next, runp) + != 0) + { + runp = __fork_handlers; + goto again; + } + } else lastp->next = runp->next; diff --git a/sysdeps/unix/sysv/linux/readahead.c b/sysdeps/unix/sysv/linux/readahead.c index dc628b2b2c..c280a479c2 100644 --- a/sysdeps/unix/sysv/linux/readahead.c +++ b/sysdeps/unix/sysv/linux/readahead.c @@ -1,5 +1,5 @@ /* Provide kernel hint to read ahead. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2007 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 @@ -30,8 +30,10 @@ ssize_t __readahead (int fd, off64_t offset, size_t count) { - return INLINE_SYSCALL (readahead, 4, fd, (off_t) (offset >> 32), - (off_t) (offset & 0xffffffff), count); + return INLINE_SYSCALL (readahead, 4, fd, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff)), + count); } #else ssize_t