blob: 4292469d14cf22d999cce520c013ca128cbcc64f [file] [log] [blame]
Moritz Pflanzerbeabe3b2017-08-31 14:56:32 +01001/*
2 * Copyright (c) 2016, 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/runtime/IScheduler.h"
25
26#include <array>
27#include <cstdlib>
28#include <cstring>
29#include <fcntl.h>
30#include <sched.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <unistd.h>
34
35namespace
36{
37unsigned int get_cpu_impl()
38{
39#ifndef BARE_METAL
40 int fd = open("/proc/cpuinfo", 0); // NOLINT
41 std::array<char, 1200> buff{ {} };
42 char *pos = nullptr;
43 char *end = nullptr;
44 bool foundid = false;
45
46 int cpu = sched_getcpu();
47
48 if(fd == -1)
49 {
50 return 0;
51 }
52
53 int charsread = read(fd, buff.data(), 1200);
54 pos = buff.data();
55 end = buff.data() + charsread;
56
57 close(fd);
58
59 /* So, to date I've encountered two formats for /proc/cpuinfo.
60 *
61 * One of them just lists processor : n for each processor (with no
62 * other info), then at the end lists part information for the current
63 * CPU.
64 *
65 * The other has an entire clause (including part number info) for each
66 * CPU in the system, with "processor : n" headers.
67 *
68 * We can cope with either of these formats by waiting to see
69 * "processor: n" (where n = our CPU ID), and then looking for the next
70 * "CPU part" field.
71 */
72 while(pos < end)
73 {
74 if(foundid && strncmp(pos, "CPU part", 8) == 0)
75 {
76 /* Found part number */
77 pos += 11;
78
79 for(char *ch = pos; ch < end; ch++)
80 {
81 if(*ch == '\n')
82 {
83 *ch = '\0';
84 break;
85 }
86 }
87
88 return strtoul(pos, nullptr, 0);
89 }
90
91 if(strncmp(pos, "processor", 9) == 0)
92 {
93 /* Found processor ID, see if it's ours. */
94 pos += 11;
95
96 for(char *ch = pos; ch < end; ch++)
97 {
98 if(*ch == '\n')
99 {
100 *ch = '\0';
101 break;
102 }
103 }
104
105 int num = strtol(pos, nullptr, 0);
106
107 if(num == cpu)
108 {
109 foundid = true;
110 }
111 }
112
113 while(pos < end)
114 {
115 char ch = *pos++;
116 if(ch == '\n' || ch == '\0')
117 {
118 break;
119 }
120 }
121 }
122#endif /* BARE_METAL */
123
124 return 0;
125}
126} // namespace
127
128namespace arm_compute
129{
130IScheduler::IScheduler()
131{
132 switch(get_cpu_impl())
133 {
134 case 0xd03:
135 _info.CPU = CPUTarget::A53;
136 break;
137 default:
Moritz Pflanzer80373f62017-09-15 10:42:58 +0100138#ifdef __arm__
139 _info.CPU = CPUTarget::ARMV7;
140#elif __aarch64__
Moritz Pflanzerbeabe3b2017-08-31 14:56:32 +0100141 _info.CPU = CPUTarget::ARMV8;
Moritz Pflanzer80373f62017-09-15 10:42:58 +0100142#else /* __arm__ || __aarch64__ */
Moritz Pflanzerbeabe3b2017-08-31 14:56:32 +0100143 _info.CPU = CPUTarget::INTRINSICS;
Moritz Pflanzer80373f62017-09-15 10:42:58 +0100144#endif /* __arm__ || __aarch64__ */
Moritz Pflanzerbeabe3b2017-08-31 14:56:32 +0100145 break;
146 }
147
148 _info.L1_size = 31000;
149 _info.L2_size = 500000;
150}
151
152void IScheduler::set_target(CPUTarget target)
153{
154 _info.CPU = target;
155}
156
157CPUInfo IScheduler::cpu_info() const
158{
159 return _info;
160}
161} // namespace arm_compute