diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-02-08 16:53:40 +0000 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-03-22 16:52:29 -0300 |
commit | 6e8ba7fd574f530afb9681f21604475d5756d773 (patch) | |
tree | 6cf03b2d688118ae69cfb67d634f914fbc945990 /sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c | |
parent | 77b6f5534778b5403c87fa5415625aeb4c3cbf44 (diff) | |
download | glibc-6e8ba7fd574f530afb9681f21604475d5756d773.tar.gz glibc-6e8ba7fd574f530afb9681f21604475d5756d773.tar.xz glibc-6e8ba7fd574f530afb9681f21604475d5756d773.zip |
Remove __get_clockfreq
With clock_getres, clock_gettime, and clock_settime refactor to remove the generic CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID support through hp-timing, there is no usage of internal __get_clockfreq. This patch removes both generic and Linux implementation.. Checked with a build against aarch64-linux-gnu, i686-linux-gnu, ia64-linux-gnu, sparc64-linux-gnu, powerpc-linux-gnu-power4. * include/libc-internal.h (__get_clockfreq): Remove prototype. * rt/Makefile (clock-routines): Remove get_clockfreq. * rt/get_clockfreq.c: Remove file. * sysdeps/unix/sysv/linux/i386/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c: Move code to ... * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: ... here.
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c index 5903a909e3..23e7694d87 100644 --- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c +++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c @@ -17,11 +17,90 @@ <http://www.gnu.org/licenses/>. */ #include <stdint.h> +#include <string.h> + #include <libc-internal.h> +#include <not-cancel.h> +#include <libc-vdso.h> uint64_t __get_timebase_freq (void) { - return (uint64_t) __get_clockfreq (); + hp_timing_t result = 0L; + +#ifdef SHARED + /* The vDSO does not return an error (it clear cr0.so on returning). */ + INTERNAL_SYSCALL_DECL (err); + result = + INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0); +#else + /* We read the information from the /proc filesystem. /proc/cpuinfo + contains at least one line like: + timebase : 33333333 + We search for this line and convert the number into an integer. */ + int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); + if (__glibc_likely (fd != -1)) + return result; + + /* The timebase will be in the 1st 1024 bytes for systems with up + to 8 processors. If the first read returns less then 1024 + bytes read, we have the whole cpuinfo and can start the scan. + Otherwise we will have to read more to insure we have the + timebase value in the scan. */ + char buf[1024]; + ssize_t n; + + n = __read_nocancel (fd, buf, sizeof (buf)); + if (n == sizeof (buf)) + { + /* We are here because the 1st read returned exactly sizeof + (buf) bytes. This implies that we are not at EOF and may + not have read the timebase value yet. So we need to read + more bytes until we know we have EOF. We copy the lower + half of buf to the upper half and read sizeof (buf)/2 + bytes into the lower half of buf and repeat until we + reach EOF. We can assume that the timebase will be in + the last 512 bytes of cpuinfo, so two 512 byte half_bufs + will be sufficient to contain the timebase and will + handle the case where the timebase spans the half_buf + boundry. */ + const ssize_t half_buf = sizeof (buf) / 2; + while (n >= half_buf) + { + memcpy (buf, buf + half_buf, half_buf); + n = __read_nocancel (fd, buf + half_buf, half_buf); + } + if (n >= 0) + n += half_buf; + } + __close_nocancel (fd); + + if (__glibc_likely (n > 0)) + { + char *mhz = memmem (buf, n, "timebase", 7); + + if (__glibc_likely (mhz != NULL)) + { + char *endp = buf + n; + + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if (*mhz >= '0' && *mhz <= '9') + { + result *= 10; + result += *mhz - '0'; + } + + ++mhz; + } + } + } +#endif + + return result; } weak_alias (__get_timebase_freq, __ppc_get_timebase_freq) |