X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=sysdeps%2Funix%2Fsysv%2Flinux%2Fpowerpc%2Fget_clockfreq.c;h=fe8c5a15b30205e8b9a063fbb77f1a1c983181a4;hb=6b2ba95b6baab6b1789e8823c8a808e09bc98794;hp=8b37943863eb748d6f5de2b006c3b158fd0a1da7;hpb=a1ffb40e32741f992c743e7b16c061fefa3747ac;p=platform%2Fupstream%2Fglibc.git diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c index 8b37943..fe8c5a1 100644 --- a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c +++ b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c @@ -1,5 +1,5 @@ /* Get frequency of the system processor. powerpc/Linux version. - Copyright (C) 2000-2014 Free Software Foundation, Inc. + Copyright (C) 2000-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 @@ -18,100 +18,91 @@ #include #include +#include #include #include #include #include #include +#include hp_timing_t __get_clockfreq (void) { + 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. */ - static hp_timing_t timebase_freq; - hp_timing_t result = 0L; + int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); + if (__glibc_likely (fd != -1)) + return result; - /* If this function was called before, we know the result. */ - if (timebase_freq != 0) - return timebase_freq; + /* 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; - /* If we can use the vDSO to obtain the timebase even better. */ -#ifdef SHARED - INTERNAL_SYSCALL_DECL (err); - timebase_freq = - INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, hp_timing_t, 0); - if (INTERNAL_SYSCALL_ERROR_P (timebase_freq, err) - && INTERNAL_SYSCALL_ERRNO (timebase_freq, err) == ENOSYS) -#endif + n = __read_nocancel (fd, buf, sizeof (buf)); + if (n == sizeof (buf)) { - int fd = __open ("/proc/cpuinfo", O_RDONLY); + /* 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 (fd != -1)) + if (__glibc_likely (n > 0)) + { + char *mhz = memmem (buf, n, "timebase", 7); + + if (__glibc_likely (mhz != NULL)) { - /* 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; + char *endp = buf + n; - n = __read (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 (fd, buf + half_buf, half_buf); - } - if (n >= 0) - n += half_buf; - } + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; - if (__builtin_expect (n, 1) > 0) + while (mhz < endp && *mhz != '\n') { - char *mhz = memmem (buf, n, "timebase", 7); - - if (__glibc_likely (mhz != NULL)) + if (*mhz >= '0' && *mhz <= '9') { - 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; - } + result *= 10; + result += *mhz - '0'; } - timebase_freq = result; + + ++mhz; } - __close (fd); } } +#endif - return timebase_freq; + return result; }