diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/stdint.h | 6 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/dl-trampoline.S | 14 | ||||
-rw-r--r-- | sysdeps/unix/clock_settime.c | 92 | ||||
-rw-r--r-- | sysdeps/unix/nice.c | 15 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_settime.c | 73 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 48 |
6 files changed, 142 insertions, 106 deletions
diff --git a/sysdeps/generic/stdint.h b/sysdeps/generic/stdint.h index c860030409..2c729ad2f1 100644 --- a/sysdeps/generic/stdint.h +++ b/sysdeps/generic/stdint.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,1999,2000,2001,2006 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 @@ -297,8 +297,8 @@ typedef unsigned long long int uintmax_t; # endif /* Unsigned. */ -# define UINT8_C(c) c ## U -# define UINT16_C(c) c ## U +# define UINT8_C(c) c +# define UINT16_C(c) c # define UINT32_C(c) c ## U # if __WORDSIZE == 64 # define UINT64_C(c) c ## UL diff --git a/sysdeps/powerpc/powerpc32/dl-trampoline.S b/sysdeps/powerpc/powerpc32/dl-trampoline.S index 392c109d4c..6a158c3fff 100644 --- a/sysdeps/powerpc/powerpc32/dl-trampoline.S +++ b/sysdeps/powerpc/powerpc32/dl-trampoline.S @@ -40,8 +40,9 @@ _dl_runtime_resolve: mflr r0 # We also need to save some of the condition register fields stw r7,32(r1) - stw r0,68(r1) - cfi_offset (lr, 4) + # Don't clobber the caller's LRSAVE, it is needed by _mcount. + stw r0,48(r1) + cfi_offset (lr, -16) stw r8,36(r1) mfcr r0 stw r9,40(r1) @@ -51,7 +52,7 @@ _dl_runtime_resolve: # 'fixup' returns the address we want to branch to. mtctr r3 # Put the registers back... - lwz r0,68(r1) + lwz r0,48(r1) lwz r10,44(r1) lwz r9,40(r1) mtlr r0 @@ -128,8 +129,9 @@ _dl_prof_resolve: mflr r5 # We also need to save some of the condition register fields. stw r7,32(r1) - stw r5,324(r1) - cfi_offset (lr, 4) + # Don't clobber the caller's LRSAVE, it is needed by _mcount. + stw r5,308(r1) + cfi_offset (lr, -12) stw r8,36(r1) mfcr r0 stw r9,40(r1) @@ -154,7 +156,7 @@ _dl_prof_resolve: # 'fixup' returns the address we want to branch to. mtctr r3 # Put the registers back... - lwz r0,324(r1) + lwz r0,308(r1) lwz r10,44(r1) lwz r9,40(r1) mtlr r0 diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c index 0194999b36..a93be6349b 100644 --- a/sysdeps/unix/clock_settime.c +++ b/sysdeps/unix/clock_settime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. +/* Copyright (C) 1999-2004, 2006 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 @@ -36,6 +36,43 @@ extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) #endif +#if HP_TIMING_AVAIL +static int +hp_timing_settime (clockid_t clock_id, const struct timespec *tp) +{ + hp_timing_t tsc; + hp_timing_t usertime; + + /* First thing is to get the current time. */ + HP_TIMING_NOW (tsc); + + if (__builtin_expect (freq == 0, 0)) + { + /* This can only happen if we haven't initialized the `freq' + variable yet. Do this now. We don't have to protect this + code against multiple execution since all of them should lead + to the same result. */ + freq = __get_clockfreq (); + if (__builtin_expect (freq == 0, 0)) + /* Something went wrong. */ + return -1; + } + + /* Convert the user-provided time into CPU ticks. */ + usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull; + + /* Determine the offset and use it as the new base value. */ + if (clock_id == CLOCK_PROCESS_CPUTIME_ID + || __pthread_clock_settime == NULL) + GL(dl_cpuclock_offset) = tsc - usertime; + else + __pthread_clock_settime (clock_id, tsc - usertime); + + return 0; +} +#endif + + /* Set CLOCK to value TP. */ int clock_settime (clockid_t clock_id, const struct timespec *tp) @@ -70,55 +107,22 @@ clock_settime (clockid_t clock_id, const struct timespec *tp) #endif default: -#if HP_TIMING_AVAIL - if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) - != CLOCK_THREAD_CPUTIME_ID) +#ifdef SYSDEP_SETTIME_CPU + SYSDEP_SETTIME_CPU; #endif +#ifndef HANDLED_CPUTIME +# if HP_TIMING_AVAIL + if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID + || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID) + retval = hp_timing_settime (clock_id, tp); + else +# endif { __set_errno (EINVAL); retval = -1; - break; } - -#if HP_TIMING_AVAIL - /* FALLTHROUGH. */ - case CLOCK_PROCESS_CPUTIME_ID: - { - hp_timing_t tsc; - hp_timing_t usertime; - - /* First thing is to get the current time. */ - HP_TIMING_NOW (tsc); - - if (__builtin_expect (freq == 0, 0)) - { - /* This can only happen if we haven't initialized the `freq' - variable yet. Do this now. We don't have to protect this - code against multiple execution since all of them should - lead to the same result. */ - freq = __get_clockfreq (); - if (__builtin_expect (freq == 0, 0)) - { - /* Something went wrong. */ - retval = -1; - break; - } - } - - /* Convert the user-provided time into CPU ticks. */ - usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull; - - /* Determine the offset and use it as the new base value. */ - if (clock_id == CLOCK_PROCESS_CPUTIME_ID - || __pthread_clock_settime == NULL) - GL(dl_cpuclock_offset) = tsc - usertime; - else - __pthread_clock_settime (clock_id, tsc - usertime); - - retval = 0; - } - break; #endif + break; } return retval; diff --git a/sysdeps/unix/nice.c b/sysdeps/unix/nice.c index 1dd57fa5c0..6e75b0327b 100644 --- a/sysdeps/unix/nice.c +++ b/sysdeps/unix/nice.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1992, 1996, 1997, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1996, 1997, 2001, 2002, 2006 + 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 @@ -47,9 +48,11 @@ nice (int incr) else if (prio >= PRIO_MAX) prio = PRIO_MAX - 1; result = setpriority (PRIO_PROCESS, 0, prio); - if (result != -1) - return getpriority (PRIO_PROCESS, 0); - else - return -1; - + if (result == -1) + { + if (errno == EACCES) + errno = EPERM; + return -1; + } + return getpriority (PRIO_PROCESS, 0); } diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c index 31ba0225fb..731b7be7b8 100644 --- a/sysdeps/unix/sysv/linux/clock_settime.c +++ b/sysdeps/unix/sysv/linux/clock_settime.c @@ -16,10 +16,65 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <errno.h> #include <sysdep.h> +#include "kernel-posix-cpu-timers.h" #include <kernel-features.h> +#ifndef HAVE_CLOCK_GETTIME_VSYSCALL +# undef INTERNAL_VSYSCALL +# define INTERNAL_VSYSCALL INTERNAL_SYSCALL +# undef INLINE_VSYSCALL +# define INLINE_VSYSCALL INLINE_SYSCALL +#else +# include <bits/libc-vdso.h> +#endif + +#if __ASSUME_POSIX_CPU_TIMERS <= 0 && defined __NR_clock_settime +extern int __libc_missing_posix_timers attribute_hidden; +extern int __libc_missing_posix_cpu_timers attribute_hidden; + +static int +maybe_syscall_settime_cpu (clockid_t clock_id, const struct timespec *tp) +{ + int e = EINVAL; + + if (!__libc_missing_posix_cpu_timers) + { + INTERNAL_SYSCALL_DECL (err); + int r = INTERNAL_VSYSCALL (clock_settime, err, 2, clock_id, tp); + if (!INTERNAL_SYSCALL_ERROR_P (r, err)) + return 0; + + e = INTERNAL_SYSCALL_ERRNO (r, err); +# ifndef __ASSUME_POSIX_TIMERS + if (e == ENOSYS) + { + __libc_missing_posix_timers = 1; + __libc_missing_posix_cpu_timers = 1; + e = EINVAL; + } + else +# endif + { + if (e == EINVAL) + { + /* Check whether the kernel supports CPU clocks at all. + If not, record it for the future. */ + r = INTERNAL_VSYSCALL (clock_getres, err, 2, + MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED), + NULL); + if (INTERNAL_SYSCALL_ERROR_P (r, err)) + __libc_missing_posix_cpu_timers = 1; + } + } + } + + return e; +} +#endif + #ifdef __ASSUME_POSIX_TIMERS /* This means the REALTIME clock is definitely supported in the @@ -73,4 +128,22 @@ extern int __libc_missing_posix_timers attribute_hidden; # define HANDLED_REALTIME 1 #endif +#if __ASSUME_POSIX_CPU_TIMERS > 0 +# define HANDLED_CPUTIME 1 +# define SYSDEP_SETTIME_CPU \ + retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp) +#elif defined __NR_clock_settime +# define SYSDEP_SETTIME_CPU \ + retval = maybe_syscall_settime_cpu (clock_id, tp); \ + if (retval == 0) \ + break; \ + if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \ + { \ + __set_errno (retval); \ + retval = -1; \ + break; \ + } \ + do { } while (0) +#endif + #include <sysdeps/unix/clock_settime.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c index 40fab28d47..2ec5bd39ad 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c @@ -1,47 +1 @@ -/* pause -- suspend the process until a signal arrives. POSIX.1 version. - 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. */ - -#include <errno.h> -#include <signal.h> -#include <unistd.h> -#include <sysdep-cancel.h> - -#include <sysdep.h> -#include <sys/syscall.h> -#include <bp-checks.h> - -/* Suspend the process until a signal arrives. - This always returns -1 and sets errno to EINTR. */ -int -__libc_pause (void) -{ - sigset_t set; - - __sigemptyset (&set); - INLINE_SYSCALL (rt_sigprocmask, 4, SIG_BLOCK, CHECK_SIGSET (NULL), - CHECK_SIGSET_NULL_OK (&set), _NSIG / 8); - - /* pause is a cancellation point, but so is sigsuspend. - So no need for anything special here. */ - - return __sigsuspend (&set); -} -weak_alias (__libc_pause, pause) - -LIBC_CANCEL_HANDLED (); /* sigsuspend handles our cancellation. */ +#include <sysdeps/posix/pause.c> |