]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / get_clockfreq.c
CommitLineData
7006f757 1/* Get frequency of the system processor. powerpc/Linux version.
f7a9f785 2 Copyright (C) 2000-2016 Free Software Foundation, Inc.
7006f757
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
7006f757
UD
18
19#include <ctype.h>
20#include <fcntl.h>
d44a052c 21#include <stdint.h>
7006f757
UD
22#include <string.h>
23#include <unistd.h>
24#include <libc-internal.h>
8c2e201b 25#include <sysdep.h>
7bf8fb10 26#include <libc-vdso.h>
6b2ba95b 27#include <not-cancel.h>
7006f757
UD
28
29hp_timing_t
30__get_clockfreq (void)
31{
6b2ba95b
AZ
32 hp_timing_t result = 0L;
33
34#ifdef SHARED
35 /* The vDSO does not return an error (it clear cr0.so on returning). */
36 INTERNAL_SYSCALL_DECL (err);
37 result =
38 INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
39#else
7006f757
UD
40 /* We read the information from the /proc filesystem. /proc/cpuinfo
41 contains at least one line like:
8c2e201b 42 timebase : 33333333
7006f757 43 We search for this line and convert the number into an integer. */
34caaafd 44 int fd = open_not_cancel_2 ("/proc/cpuinfo", O_RDONLY);
6b2ba95b
AZ
45 if (__glibc_likely (fd != -1))
46 return result;
7006f757 47
6b2ba95b
AZ
48 /* The timebase will be in the 1st 1024 bytes for systems with up
49 to 8 processors. If the first read returns less then 1024
50 bytes read, we have the whole cpuinfo and can start the scan.
51 Otherwise we will have to read more to insure we have the
52 timebase value in the scan. */
53 char buf[1024];
54 ssize_t n;
7006f757 55
6b2ba95b
AZ
56 n = __read_nocancel (fd, buf, sizeof (buf));
57 if (n == sizeof (buf))
7006f757 58 {
6b2ba95b
AZ
59 /* We are here because the 1st read returned exactly sizeof
60 (buf) bytes. This implies that we are not at EOF and may
61 not have read the timebase value yet. So we need to read
62 more bytes until we know we have EOF. We copy the lower
63 half of buf to the upper half and read sizeof (buf)/2
64 bytes into the lower half of buf and repeat until we
65 reach EOF. We can assume that the timebase will be in
66 the last 512 bytes of cpuinfo, so two 512 byte half_bufs
67 will be sufficient to contain the timebase and will
68 handle the case where the timebase spans the half_buf
69 boundry. */
70 const ssize_t half_buf = sizeof (buf) / 2;
71 while (n >= half_buf)
72 {
73 memcpy (buf, buf + half_buf, half_buf);
74 n = __read_nocancel (fd, buf + half_buf, half_buf);
75 }
76 if (n >= 0)
77 n += half_buf;
78 }
79 __close_nocancel (fd);
7006f757 80
6b2ba95b
AZ
81 if (__glibc_likely (n > 0))
82 {
83 char *mhz = memmem (buf, n, "timebase", 7);
84
85 if (__glibc_likely (mhz != NULL))
7006f757 86 {
6b2ba95b 87 char *endp = buf + n;
8c2e201b 88
6b2ba95b
AZ
89 /* Search for the beginning of the string. */
90 while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
91 ++mhz;
7006f757 92
6b2ba95b 93 while (mhz < endp && *mhz != '\n')
7006f757 94 {
6b2ba95b 95 if (*mhz >= '0' && *mhz <= '9')
7006f757 96 {
6b2ba95b
AZ
97 result *= 10;
98 result += *mhz - '0';
7006f757 99 }
6b2ba95b
AZ
100
101 ++mhz;
7006f757 102 }
7006f757 103 }
7006f757 104 }
6b2ba95b 105#endif
7006f757 106
6b2ba95b 107 return result;
7006f757 108}