diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/x86')
40 files changed, 782 insertions, 64 deletions
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile index 6412a9ef36..d6be472612 100644 --- a/sysdeps/unix/sysv/linux/x86/Makefile +++ b/sysdeps/unix/sysv/linux/x86/Makefile @@ -5,14 +5,21 @@ abi-variants := 32 64 x32 abi-32-options := -D__i386__ -U__x86_64__ abi-32-condition := !defined __x86_64__ -abi-32-ld-soname := ld-linux.so.2 abi-64-options := -U__i386__ -D__x86_64__ -U__ILP32__ -D__LP64__ abi-64-condition := defined __x86_64__ && defined __LP64__ -abi-64-ld-soname := ld-linux-x86-64.so.2 abi-x32-options := -U__i386__ -D__x86_64__ -D__ILP32__ -U__LP64__ abi-x32-condition := defined __x86_64__ && defined __ILP32__ -abi-x32-ld-soname := ld-linux-x32.so.2 ifeq ($(subdir),misc) sysdep_headers += sys/elf.h sys/perm.h sys/reg.h sys/vm86.h sys/debugreg.h sys/io.h endif + +ifeq ($(subdir),nptl) +libpthread-sysdep_routines += init-arch +libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \ + elision-trylock +endif + +ifeq ($(subdir),elf) +sysdep_routines += dl-vdso +endif diff --git a/sysdeps/unix/sysv/linux/x86/bits/environments.h b/sysdeps/unix/sysv/linux/x86/bits/environments.h index df40aefd9c..172bfa4b03 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/environments.h +++ b/sysdeps/unix/sysv/linux/x86/bits/environments.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2014 Free Software Foundation, Inc. +/* Copyright (C) 1999-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/epoll.h b/sysdeps/unix/sysv/linux/x86/bits/epoll.h index 58ae8e97e2..851498add5 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/epoll.h +++ b/sysdeps/unix/sysv/linux/x86/bits/epoll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/fcntl.h b/sysdeps/unix/sysv/linux/x86/bits/fcntl.h index 783cb82c59..dac3bfb792 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/x86/bits/fcntl.h @@ -1,5 +1,5 @@ /* O_*, F_*, FD_* bit values for Linux/x86. - Copyright (C) 2001-2014 Free Software Foundation, Inc. + Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h b/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h index 6a09392149..8567f293a1 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h @@ -1,5 +1,5 @@ /* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h index 79e73d55bc..f8066a73e7 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/mman.h +++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h @@ -1,5 +1,5 @@ /* Definitions for POSIX memory map interface. Linux/x86_64 version. - Copyright (C) 2001-2014 Free Software Foundation, Inc. + Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/msq.h b/sysdeps/unix/sysv/linux/x86/bits/msq.h index 590494f691..126f47f15e 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/msq.h +++ b/sysdeps/unix/sysv/linux/x86/bits/msq.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2014 Free Software Foundation, Inc. +/* Copyright (C) 1995-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/sem.h b/sysdeps/unix/sysv/linux/x86/bits/sem.h index c45e9b93cf..098938113f 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sem.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sem.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/shm.h b/sysdeps/unix/sysv/linux/x86/bits/shm.h index c205e62927..d8c03dfbcc 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/shm.h +++ b/sysdeps/unix/sysv/linux/x86/bits/shm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2014 Free Software Foundation, Inc. +/* Copyright (C) 1995-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h b/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h index e742cba7f6..3b9f7d6913 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/siginfo.h b/sysdeps/unix/sysv/linux/x86/bits/siginfo.h index 44f293eb20..3151bf3c5a 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/siginfo.h +++ b/sysdeps/unix/sysv/linux/x86/bits/siginfo.h @@ -1,5 +1,5 @@ /* siginfo_t, sigevent and constants. Linux x86-64 version. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2015 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 @@ -108,6 +108,11 @@ typedef struct { void *si_addr; /* Faulting insn/memory ref. */ short int si_addr_lsb; /* Valid LSB of the reported address. */ + struct + { + void *_lower; + void *_upper; + } si_addr_bnd; } _sigfault; /* SIGPOLL. */ @@ -141,6 +146,8 @@ typedef struct # define si_ptr _sifields._rt.si_sigval.sival_ptr # define si_addr _sifields._sigfault.si_addr # define si_addr_lsb _sifields._sigfault.si_addr_lsb +# define si_lower _sifields._sigfault.si_addr_bnd._lower +# define si_upper _sifields._sigfault.si_addr_bnd._upper # define si_band _sifields._sigpoll.si_band # define si_fd _sifields._sigpoll.si_fd # define si_call_addr _sifields._sigsys._call_addr @@ -173,114 +180,120 @@ enum }; +# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 /* `si_code' values for SIGILL signal. */ enum { ILL_ILLOPC = 1, /* Illegal opcode. */ -# define ILL_ILLOPC ILL_ILLOPC +# define ILL_ILLOPC ILL_ILLOPC ILL_ILLOPN, /* Illegal operand. */ -# define ILL_ILLOPN ILL_ILLOPN +# define ILL_ILLOPN ILL_ILLOPN ILL_ILLADR, /* Illegal addressing mode. */ -# define ILL_ILLADR ILL_ILLADR +# define ILL_ILLADR ILL_ILLADR ILL_ILLTRP, /* Illegal trap. */ -# define ILL_ILLTRP ILL_ILLTRP +# define ILL_ILLTRP ILL_ILLTRP ILL_PRVOPC, /* Privileged opcode. */ -# define ILL_PRVOPC ILL_PRVOPC +# define ILL_PRVOPC ILL_PRVOPC ILL_PRVREG, /* Privileged register. */ -# define ILL_PRVREG ILL_PRVREG +# define ILL_PRVREG ILL_PRVREG ILL_COPROC, /* Coprocessor error. */ -# define ILL_COPROC ILL_COPROC +# define ILL_COPROC ILL_COPROC ILL_BADSTK /* Internal stack error. */ -# define ILL_BADSTK ILL_BADSTK +# define ILL_BADSTK ILL_BADSTK }; /* `si_code' values for SIGFPE signal. */ enum { FPE_INTDIV = 1, /* Integer divide by zero. */ -# define FPE_INTDIV FPE_INTDIV +# define FPE_INTDIV FPE_INTDIV FPE_INTOVF, /* Integer overflow. */ -# define FPE_INTOVF FPE_INTOVF +# define FPE_INTOVF FPE_INTOVF FPE_FLTDIV, /* Floating point divide by zero. */ -# define FPE_FLTDIV FPE_FLTDIV +# define FPE_FLTDIV FPE_FLTDIV FPE_FLTOVF, /* Floating point overflow. */ -# define FPE_FLTOVF FPE_FLTOVF +# define FPE_FLTOVF FPE_FLTOVF FPE_FLTUND, /* Floating point underflow. */ -# define FPE_FLTUND FPE_FLTUND +# define FPE_FLTUND FPE_FLTUND FPE_FLTRES, /* Floating point inexact result. */ -# define FPE_FLTRES FPE_FLTRES +# define FPE_FLTRES FPE_FLTRES FPE_FLTINV, /* Floating point invalid operation. */ -# define FPE_FLTINV FPE_FLTINV +# define FPE_FLTINV FPE_FLTINV FPE_FLTSUB /* Subscript out of range. */ -# define FPE_FLTSUB FPE_FLTSUB +# define FPE_FLTSUB FPE_FLTSUB }; /* `si_code' values for SIGSEGV signal. */ enum { SEGV_MAPERR = 1, /* Address not mapped to object. */ -# define SEGV_MAPERR SEGV_MAPERR +# define SEGV_MAPERR SEGV_MAPERR SEGV_ACCERR /* Invalid permissions for mapped object. */ -# define SEGV_ACCERR SEGV_ACCERR +# define SEGV_ACCERR SEGV_ACCERR }; /* `si_code' values for SIGBUS signal. */ enum { BUS_ADRALN = 1, /* Invalid address alignment. */ -# define BUS_ADRALN BUS_ADRALN +# define BUS_ADRALN BUS_ADRALN BUS_ADRERR, /* Non-existant physical address. */ -# define BUS_ADRERR BUS_ADRERR +# define BUS_ADRERR BUS_ADRERR BUS_OBJERR, /* Object specific hardware error. */ -# define BUS_OBJERR BUS_OBJERR +# define BUS_OBJERR BUS_OBJERR BUS_MCEERR_AR, /* Hardware memory error: action required. */ -# define BUS_MCEERR_AR BUS_MCEERR_AR +# define BUS_MCEERR_AR BUS_MCEERR_AR BUS_MCEERR_AO /* Hardware memory error: action optional. */ -# define BUS_MCEERR_AO BUS_MCEERR_AO +# define BUS_MCEERR_AO BUS_MCEERR_AO }; +# endif +# ifdef __USE_XOPEN_EXTENDED /* `si_code' values for SIGTRAP signal. */ enum { TRAP_BRKPT = 1, /* Process breakpoint. */ -# define TRAP_BRKPT TRAP_BRKPT +# define TRAP_BRKPT TRAP_BRKPT TRAP_TRACE /* Process trace trap. */ -# define TRAP_TRACE TRAP_TRACE +# define TRAP_TRACE TRAP_TRACE }; +# endif +# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 /* `si_code' values for SIGCHLD signal. */ enum { CLD_EXITED = 1, /* Child has exited. */ -# define CLD_EXITED CLD_EXITED +# define CLD_EXITED CLD_EXITED CLD_KILLED, /* Child was killed. */ -# define CLD_KILLED CLD_KILLED +# define CLD_KILLED CLD_KILLED CLD_DUMPED, /* Child terminated abnormally. */ -# define CLD_DUMPED CLD_DUMPED +# define CLD_DUMPED CLD_DUMPED CLD_TRAPPED, /* Traced child has trapped. */ -# define CLD_TRAPPED CLD_TRAPPED +# define CLD_TRAPPED CLD_TRAPPED CLD_STOPPED, /* Child has stopped. */ -# define CLD_STOPPED CLD_STOPPED +# define CLD_STOPPED CLD_STOPPED CLD_CONTINUED /* Stopped child has continued. */ -# define CLD_CONTINUED CLD_CONTINUED +# define CLD_CONTINUED CLD_CONTINUED }; /* `si_code' values for SIGPOLL signal. */ enum { POLL_IN = 1, /* Data input available. */ -# define POLL_IN POLL_IN +# define POLL_IN POLL_IN POLL_OUT, /* Output buffers available. */ -# define POLL_OUT POLL_OUT +# define POLL_OUT POLL_OUT POLL_MSG, /* Input message available. */ -# define POLL_MSG POLL_MSG +# define POLL_MSG POLL_MSG POLL_ERR, /* I/O error. */ -# define POLL_ERR POLL_ERR +# define POLL_ERR POLL_ERR POLL_PRI, /* High priority input available. */ -# define POLL_PRI POLL_PRI +# define POLL_PRI POLL_PRI POLL_HUP /* Device disconnected. */ -# define POLL_HUP POLL_HUP +# define POLL_HUP POLL_HUP }; +# endif # undef __need_siginfo_t #endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/stat.h b/sysdeps/unix/sysv/linux/x86/bits/stat.h index 6fcb869cf9..63dccfca7b 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/stat.h +++ b/sysdeps/unix/sysv/linux/x86/bits/stat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2014 Free Software Foundation, Inc. +/* Copyright (C) 1999-2015 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 @@ -81,7 +81,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#if defined __USE_MISC || defined __USE_XOPEN2K8 +#ifdef __USE_XOPEN2K8 /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -142,7 +142,7 @@ struct stat64 # endif __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ -# if defined __USE_MISC || defined __USE_XOPEN2K8 +# ifdef __USE_XOPEN2K8 /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h b/sysdeps/unix/sysv/linux/x86/bits/sysctl.h index 65146e4e48..daaf6fc618 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sysctl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2014 Free Software Foundation, Inc. +/* Copyright (C) 2012-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index 2e0984c8e1..8889bc0039 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -1,5 +1,5 @@ /* bits/typesizes.h -- underlying types for *_t. Linux/x86-64 version. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.c b/sysdeps/unix/sysv/linux/x86/elision-conf.c new file mode 100644 index 0000000000..84902aca3c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.c @@ -0,0 +1,83 @@ +/* elision-conf.c: Lock elision tunable parameters. + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include <pthreadP.h> +#include <init-arch.h> +#include <elision-conf.h> +#include <unistd.h> + +/* Reasonable initial tuning values, may be revised in the future. + This is a conservative initial value. */ + +struct elision_config __elision_aconf = + { + /* How often to not attempt to use elision if a transaction aborted + because the lock is already acquired. Expressed in number of lock + acquisition attempts. */ + .skip_lock_busy = 3, + /* How often to not attempt to use elision if a transaction aborted due + to reasons other than other threads' memory accesses. Expressed in + number of lock acquisition attempts. */ + .skip_lock_internal_abort = 3, + /* How often we retry using elision if there is chance for the transaction + to finish execution (e.g., it wasn't aborted due to the lock being + already acquired. */ + .retry_try_xbegin = 3, + /* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */ + .skip_trylock_internal_abort = 3, + }; + +/* Set when the CPU supports elision. When false elision is never attempted. + */ + +int __elision_available attribute_hidden; + +/* Force elision for all new locks. This is used to decide whether existing + DEFAULT locks should be automatically upgraded to elision in + pthread_mutex_lock(). Disabled for suid programs. Only used when elision + is available. */ + +int __pthread_force_elision attribute_hidden; + +/* Initialize elison. */ + +static void +elision_init (int argc __attribute__ ((unused)), + char **argv __attribute__ ((unused)), + char **environ) +{ + __elision_available = HAS_RTM; +#ifdef ENABLE_LOCK_ELISION + __pthread_force_elision = __libc_enable_secure ? 0 : __elision_available; +#endif + if (!HAS_RTM) + __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */ +} + +#ifdef SHARED +# define INIT_SECTION ".init_array" +#else +# define INIT_SECTION ".preinit_array" +#endif + +void (*const __pthread_init_array []) (int, char **, char **) + __attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) = +{ + &elision_init +}; diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.h b/sysdeps/unix/sysv/linux/x86/elision-conf.h new file mode 100644 index 0000000000..186df3d0bb --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.h @@ -0,0 +1,43 @@ +/* elision-conf.h: Lock elision tunable parameters. + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ +#ifndef _ELISION_CONF_H +#define _ELISION_CONF_H 1 + +#include <pthread.h> +#include <cpuid.h> +#include <time.h> + +/* Should make sure there is no false sharing on this. */ + +struct elision_config +{ + int skip_lock_busy; + int skip_lock_internal_abort; + int retry_try_xbegin; + int skip_trylock_internal_abort; +}; + +extern struct elision_config __elision_aconf attribute_hidden; + +extern int __elision_available attribute_hidden; +extern int __pthread_force_elision attribute_hidden; + +/* Tell the test suite to test elision for this architecture. */ +#define HAVE_ELISION 1 + +#endif diff --git a/sysdeps/unix/sysv/linux/x86/elision-lock.c b/sysdeps/unix/sysv/linux/x86/elision-lock.c new file mode 100644 index 0000000000..c4ba880370 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-lock.c @@ -0,0 +1,95 @@ +/* elision-lock.c: Elided pthread mutex lock. + Copyright (C) 2011-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include "pthreadP.h" +#include "lowlevellock.h" +#include "hle.h" +#include <elision-conf.h> + +#if !defined(LLL_LOCK) && !defined(EXTRAARG) +/* Make sure the configuration code is always linked in for static + libraries. */ +#include "elision-conf.c" +#endif + +#ifndef EXTRAARG +#define EXTRAARG +#endif +#ifndef LLL_LOCK +#define LLL_LOCK(a,b) lll_lock(a,b), 0 +#endif + +#define aconf __elision_aconf + +/* Adaptive lock using transactions. + By default the lock region is run as a transaction, and when it + aborts or the lock is busy the lock adapts itself. */ + +int +__lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) +{ + if (*adapt_count <= 0) + { + unsigned status; + int try_xbegin; + + for (try_xbegin = aconf.retry_try_xbegin; + try_xbegin > 0; + try_xbegin--) + { + if ((status = _xbegin()) == _XBEGIN_STARTED) + { + if (*futex == 0) + return 0; + + /* Lock was busy. Fall back to normal locking. + Could also _xend here but xabort with 0xff code + is more visible in the profiler. */ + _xabort (_ABORT_LOCK_BUSY); + } + + if (!(status & _XABORT_RETRY)) + { + if ((status & _XABORT_EXPLICIT) + && _XABORT_CODE (status) == _ABORT_LOCK_BUSY) + { + /* Right now we skip here. Better would be to wait a bit + and retry. This likely needs some spinning. */ + if (*adapt_count != aconf.skip_lock_busy) + *adapt_count = aconf.skip_lock_busy; + } + /* Internal abort. There is no chance for retry. + Use the normal locking and next time use lock. + Be careful to avoid writing to the lock. */ + else if (*adapt_count != aconf.skip_lock_internal_abort) + *adapt_count = aconf.skip_lock_internal_abort; + break; + } + } + } + else + { + /* Use a normal lock until the threshold counter runs out. + Lost updates possible. */ + (*adapt_count)--; + } + + /* Use a normal lock here. */ + return LLL_LOCK ((*futex), private); +} diff --git a/sysdeps/unix/sysv/linux/x86/elision-timed.c b/sysdeps/unix/sysv/linux/x86/elision-timed.c new file mode 100644 index 0000000000..5ec7083390 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-timed.c @@ -0,0 +1,26 @@ +/* elision-timed.c: Lock elision timed lock. + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <elision-conf.h> +#include "lowlevellock.h" +#define __lll_lock_elision __lll_timedlock_elision +#define EXTRAARG const struct timespec *t, +#undef LLL_LOCK +#define LLL_LOCK(a, b) lll_timedlock(a, t, b) +#include "elision-lock.c" diff --git a/sysdeps/unix/sysv/linux/x86/elision-trylock.c b/sysdeps/unix/sysv/linux/x86/elision-trylock.c new file mode 100644 index 0000000000..c1c4f58b39 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-trylock.c @@ -0,0 +1,71 @@ +/* elision-trylock.c: Lock eliding trylock for pthreads. + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pthreadP.h> +#include <lowlevellock.h> +#include "hle.h" +#include <elision-conf.h> + +#define aconf __elision_aconf + +/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is + the adaptation counter in the mutex. */ + +int +__lll_trylock_elision (int *futex, short *adapt_count) +{ + /* Implement POSIX semantics by forbiding nesting + trylock. Sorry. After the abort the code is re-executed + non transactional and if the lock was already locked + return an error. */ + _xabort (_ABORT_NESTED_TRYLOCK); + + /* Only try a transaction if it's worth it. */ + if (*adapt_count <= 0) + { + unsigned status; + + if ((status = _xbegin()) == _XBEGIN_STARTED) + { + if (*futex == 0) + return 0; + + /* Lock was busy. Fall back to normal locking. + Could also _xend here but xabort with 0xff code + is more visible in the profiler. */ + _xabort (_ABORT_LOCK_BUSY); + } + + if (!(status & _XABORT_RETRY)) + { + /* Internal abort. No chance for retry. For future + locks don't try speculation for some time. */ + if (*adapt_count != aconf.skip_trylock_internal_abort) + *adapt_count = aconf.skip_trylock_internal_abort; + } + /* Could do some retries here. */ + } + else + { + /* Lost updates are possible, but harmless. */ + (*adapt_count)--; + } + + return lll_trylock (*futex); +} diff --git a/sysdeps/unix/sysv/linux/x86/elision-unlock.c b/sysdeps/unix/sysv/linux/x86/elision-unlock.c new file mode 100644 index 0000000000..529946319c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/elision-unlock.c @@ -0,0 +1,33 @@ +/* elision-unlock.c: Commit an elided pthread lock. + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include "pthreadP.h" +#include "lowlevellock.h" +#include "hle.h" + +int +__lll_unlock_elision(int *lock, int private) +{ + /* When the lock was free we're in a transaction. + When you crash here you unlocked a free lock. */ + if (*lock == 0) + _xend(); + else + lll_unlock ((*lock), private); + return 0; +} diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h new file mode 100644 index 0000000000..e40a23df65 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/force-elision.h @@ -0,0 +1,26 @@ +/* force-elision.h: Automatic enabling of elision for mutexes + Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +/* Automatically enable elision for existing user lock kinds. */ +#define FORCE_ELISION(m, s) \ + if (__pthread_force_elision \ + && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ + { \ + mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ + s; \ + } diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c new file mode 100644 index 0000000000..440cb0243a --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c @@ -0,0 +1,61 @@ +/* gettimeofday - get the time. Linux/x86 version. + Copyright (C) 2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/time.h> + +#ifdef SHARED + +# include <dl-vdso.h> +# include <errno.h> + +static int +__gettimeofday_syscall (struct timeval *tv, struct timezone *tz) +{ + return INLINE_SYSCALL (gettimeofday, 2, tv, tz); +} + +void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday"); + +void * +gettimeofday_ifunc (void) +{ + PREPARE_VERSION_KNOWN (linux26, LINUX_2_6); + + /* If the vDSO is not available we fall back to syscall. */ + return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26) + ?: (void*) (&__gettimeofday_syscall)); +} +asm (".type __gettimeofday, %gnu_indirect_function"); + +libc_ifunc_hidden_def(__gettimeofday) + +#else + +# include <sysdep.h> +# include <errno.h> + +int +__gettimeofday (struct timeval *tv, struct timezone *tz) +{ + return INLINE_SYSCALL (gettimeofday, 2, tv, tz); +} +libc_hidden_def (__gettimeofday) + +#endif +weak_alias (__gettimeofday, gettimeofday) +libc_hidden_weak (gettimeofday) diff --git a/sysdeps/unix/sysv/linux/x86/hle.h b/sysdeps/unix/sysv/linux/x86/hle.h new file mode 100644 index 0000000000..4a7b9e3bf7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/hle.h @@ -0,0 +1,75 @@ +/* Shared RTM header. Emulate TSX intrinsics for compilers and assemblers + that do not support the intrinsics and instructions yet. */ +#ifndef _HLE_H +#define _HLE_H 1 + +#ifdef __ASSEMBLER__ + +.macro XBEGIN target + .byte 0xc7,0xf8 + .long \target-1f +1: +.endm + +.macro XEND + .byte 0x0f,0x01,0xd5 +.endm + +.macro XABORT code + .byte 0xc6,0xf8,\code +.endm + +.macro XTEST + .byte 0x0f,0x01,0xd6 +.endm + +#endif + +/* Official RTM intrinsics interface matching gcc/icc, but works + on older gcc compatible compilers and binutils. + We should somehow detect if the compiler supports it, because + it may be able to generate slightly better code. */ + +#define _XBEGIN_STARTED (~0u) +#define _XABORT_EXPLICIT (1 << 0) +#define _XABORT_RETRY (1 << 1) +#define _XABORT_CONFLICT (1 << 2) +#define _XABORT_CAPACITY (1 << 3) +#define _XABORT_DEBUG (1 << 4) +#define _XABORT_NESTED (1 << 5) +#define _XABORT_CODE(x) (((x) >> 24) & 0xff) + +#define _ABORT_LOCK_BUSY 0xff +#define _ABORT_LOCK_IS_LOCKED 0xfe +#define _ABORT_NESTED_TRYLOCK 0xfd + +#ifndef __ASSEMBLER__ + +#define __force_inline __attribute__((__always_inline__)) inline + +static __force_inline int _xbegin(void) +{ + int ret = _XBEGIN_STARTED; + asm volatile (".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory"); + return ret; +} + +static __force_inline void _xend(void) +{ + asm volatile (".byte 0x0f,0x01,0xd5" ::: "memory"); +} + +static __force_inline void _xabort(const unsigned int status) +{ + asm volatile (".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); +} + +static __force_inline int _xtest(void) +{ + unsigned char out; + asm volatile (".byte 0x0f,0x01,0xd6 ; setnz %0" : "=r" (out) :: "memory"); + return out; +} + +#endif +#endif diff --git a/sysdeps/unix/sysv/linux/x86/init-arch.c b/sysdeps/unix/sysv/linux/x86/init-arch.c new file mode 100644 index 0000000000..00a94d83dc --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/init-arch.c @@ -0,0 +1 @@ +#include <sysdeps/x86_64/multiarch/init-arch.c> diff --git a/sysdeps/unix/sysv/linux/x86/init-arch.h b/sysdeps/unix/sysv/linux/x86/init-arch.h new file mode 100644 index 0000000000..cd2d0befee --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/init-arch.h @@ -0,0 +1 @@ +#include <sysdeps/x86_64/multiarch/init-arch.h> diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h new file mode 100644 index 0000000000..f3a8f077d3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h @@ -0,0 +1,36 @@ +/* Resolve function pointers to VDSO functions. + Copyright (C) 2005-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _LIBC_VDSO_H +#define _LIBC_VDSO_H + +#include <time.h> +#include <sys/time.h> + +#ifdef SHARED + +# include <sysdep-vdso.h> + +extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) + attribute_hidden; + +extern long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *); + +#endif + +#endif /* _LIBC_VDSO_H */ diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c new file mode 100644 index 0000000000..efcae8a80b --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2013-2015 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, see + <http://www.gnu.org/licenses/>. */ + +/* The cond lock is not actually elided yet, but we still need to handle + already elided locks. */ +#include <elision-conf.h> + +#include <nptl/pthread_mutex_cond_lock.c> diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c new file mode 100644 index 0000000000..f18f971c68 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c @@ -0,0 +1,22 @@ +/* Elided version of pthread_mutex_lock. + Copyright (C) 2011-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <elision-conf.h> +#include "force-elision.h" + +#include "nptl/pthread_mutex_lock.c" diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c new file mode 100644 index 0000000000..c2c4958af4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c @@ -0,0 +1,22 @@ +/* Elided version of pthread_mutex_timedlock. + Copyright (C) 2011-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <elision-conf.h> +#include "force-elision.h" + +#include "nptl/pthread_mutex_timedlock.c" diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c new file mode 100644 index 0000000000..ce070f2f0c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c @@ -0,0 +1,22 @@ +/* Elided version of pthread_mutex_trylock. + Copyright (C) 2011-2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <elision-conf.h> +#include "force-elision.h" + +#include "nptl/pthread_mutex_trylock.c" diff --git a/sysdeps/unix/sysv/linux/x86/sys/debugreg.h b/sysdeps/unix/sysv/linux/x86/sys/debugreg.h index 939d7f363f..bdafdeafd4 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/debugreg.h +++ b/sysdeps/unix/sysv/linux/x86/sys/debugreg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/elf.h b/sysdeps/unix/sysv/linux/x86/sys/elf.h index d7b62dc205..ba63bdfa99 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/elf.h +++ b/sysdeps/unix/sysv/linux/x86/sys/elf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2014 Free Software Foundation, Inc. +/* Copyright (C) 1998-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/io.h b/sysdeps/unix/sysv/linux/x86/sys/io.h index e30d37fe21..7ad4db6a45 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/io.h +++ b/sysdeps/unix/sysv/linux/x86/sys/io.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2014 Free Software Foundation, Inc. +/* Copyright (C) 1996-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/perm.h b/sysdeps/unix/sysv/linux/x86/sys/perm.h index 39ebda3144..c58efc0c93 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/perm.h +++ b/sysdeps/unix/sysv/linux/x86/sys/perm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2014 Free Software Foundation, Inc. +/* Copyright (C) 1996-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/procfs.h b/sysdeps/unix/sysv/linux/x86/sys/procfs.h index 62c9d8c2ee..2706a34c21 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/procfs.h +++ b/sysdeps/unix/sysv/linux/x86/sys/procfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/reg.h b/sysdeps/unix/sysv/linux/x86/sys/reg.h index 9871196287..1b3152de38 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/reg.h +++ b/sysdeps/unix/sysv/linux/x86/sys/reg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h index 8665cf8111..b9a0a1154d 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h +++ b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/user.h b/sysdeps/unix/sysv/linux/x86/sys/user.h index 5531c85440..8bc9242694 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/user.h +++ b/sysdeps/unix/sysv/linux/x86/sys/user.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/sys/vm86.h b/sysdeps/unix/sysv/linux/x86/sys/vm86.h index c645e2c763..bcbc2f6f05 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/vm86.h +++ b/sysdeps/unix/sysv/linux/x86/sys/vm86.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2014 Free Software Foundation, Inc. +/* Copyright (C) 1996-2015 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 diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c new file mode 100644 index 0000000000..ebf092ae12 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/time.c @@ -0,0 +1,59 @@ +/* time -- Get number of seconds since Epoch. Linux/x86 version. + Copyright (C) 2015 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> + +#ifdef SHARED + +#include <dl-vdso.h> +#include <errno.h> + +static time_t +__time_syscall (time_t *t) +{ + INTERNAL_SYSCALL_DECL (err); + return INTERNAL_SYSCALL (time, err, 1, t); +} + +void *time_ifunc (void) __asm__ ("time"); + +void * +time_ifunc (void) +{ + PREPARE_VERSION_KNOWN (linux26, LINUX_2_6); + +/* If the vDSO is not available we fall back on the syscall. */ + return _dl_vdso_vsym ("__vdso_time", &linux26) + ?: (void*) &__time_syscall; +} +asm (".type time, %gnu_indirect_function"); + +libc_ifunc_hidden_def(time) + +#else + +# include <sysdep.h> + +time_t +time (time_t *t) +{ + INTERNAL_SYSCALL_DECL (err); + return INTERNAL_SYSCALL (time, err, 1, t); +} + +#endif |