xref: /aosp_15_r20/external/armnn/profiling/common/src/CounterDirectory.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include <common/include/CounterDirectory.hpp>
7*89c4ff92SAndroid Build Coastguard Worker #include <common/include/CommonProfilingUtils.hpp>
8*89c4ff92SAndroid Build Coastguard Worker 
9*89c4ff92SAndroid Build Coastguard Worker #include <common/include/Assert.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <common/include/SwTrace.hpp>
11*89c4ff92SAndroid Build Coastguard Worker 
12*89c4ff92SAndroid Build Coastguard Worker #include <fmt/format.h>
13*89c4ff92SAndroid Build Coastguard Worker 
14*89c4ff92SAndroid Build Coastguard Worker namespace arm
15*89c4ff92SAndroid Build Coastguard Worker {
16*89c4ff92SAndroid Build Coastguard Worker 
17*89c4ff92SAndroid Build Coastguard Worker namespace pipe
18*89c4ff92SAndroid Build Coastguard Worker {
19*89c4ff92SAndroid Build Coastguard Worker 
RegisterCategory(const std::string & categoryName)20*89c4ff92SAndroid Build Coastguard Worker const Category* CounterDirectory::RegisterCategory(const std::string& categoryName)
21*89c4ff92SAndroid Build Coastguard Worker {
22*89c4ff92SAndroid Build Coastguard Worker     // Check that the given category name is valid
23*89c4ff92SAndroid Build Coastguard Worker     if (categoryName.empty() ||
24*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(categoryName))
25*89c4ff92SAndroid Build Coastguard Worker     {
26*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a category with an invalid name");
27*89c4ff92SAndroid Build Coastguard Worker     }
28*89c4ff92SAndroid Build Coastguard Worker 
29*89c4ff92SAndroid Build Coastguard Worker     // Check that the given category is not already registered
30*89c4ff92SAndroid Build Coastguard Worker     if (IsCategoryRegistered(categoryName))
31*89c4ff92SAndroid Build Coastguard Worker     {
32*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException(fmt::format(
33*89c4ff92SAndroid Build Coastguard Worker             "Trying to register a category already registered (\"{}\")",
34*89c4ff92SAndroid Build Coastguard Worker             categoryName));
35*89c4ff92SAndroid Build Coastguard Worker     }
36*89c4ff92SAndroid Build Coastguard Worker 
37*89c4ff92SAndroid Build Coastguard Worker     // Create the category
38*89c4ff92SAndroid Build Coastguard Worker     CategoryPtr category = std::make_unique<Category>(categoryName);
39*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(category);
40*89c4ff92SAndroid Build Coastguard Worker 
41*89c4ff92SAndroid Build Coastguard Worker     // Get the raw category pointer
42*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryPtr = category.get();
43*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(categoryPtr);
44*89c4ff92SAndroid Build Coastguard Worker 
45*89c4ff92SAndroid Build Coastguard Worker     // Register the category
46*89c4ff92SAndroid Build Coastguard Worker     m_Categories.insert(std::move(category));
47*89c4ff92SAndroid Build Coastguard Worker 
48*89c4ff92SAndroid Build Coastguard Worker     return categoryPtr;
49*89c4ff92SAndroid Build Coastguard Worker }
50*89c4ff92SAndroid Build Coastguard Worker 
RegisterDevice(const std::string & deviceName,uint16_t cores,const arm::pipe::Optional<std::string> & parentCategoryName)51*89c4ff92SAndroid Build Coastguard Worker const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
52*89c4ff92SAndroid Build Coastguard Worker                                                uint16_t cores,
53*89c4ff92SAndroid Build Coastguard Worker                                                const arm::pipe::Optional<std::string>& parentCategoryName)
54*89c4ff92SAndroid Build Coastguard Worker {
55*89c4ff92SAndroid Build Coastguard Worker     // Check that the given device name is valid
56*89c4ff92SAndroid Build Coastguard Worker     if (deviceName.empty() ||
57*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(deviceName))
58*89c4ff92SAndroid Build Coastguard Worker     {
59*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a device with an invalid name");
60*89c4ff92SAndroid Build Coastguard Worker     }
61*89c4ff92SAndroid Build Coastguard Worker 
62*89c4ff92SAndroid Build Coastguard Worker     // Check that a device with the given name is not already registered
63*89c4ff92SAndroid Build Coastguard Worker     if (IsDeviceRegistered(deviceName))
64*89c4ff92SAndroid Build Coastguard Worker     {
65*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException(fmt::format(
66*89c4ff92SAndroid Build Coastguard Worker             "Trying to register a device already registered (\"{}\")",
67*89c4ff92SAndroid Build Coastguard Worker             deviceName));
68*89c4ff92SAndroid Build Coastguard Worker     }
69*89c4ff92SAndroid Build Coastguard Worker 
70*89c4ff92SAndroid Build Coastguard Worker     // Check that a category with the given (optional) parent category name is already registered
71*89c4ff92SAndroid Build Coastguard Worker     if (parentCategoryName.has_value())
72*89c4ff92SAndroid Build Coastguard Worker     {
73*89c4ff92SAndroid Build Coastguard Worker         // Get the (optional) parent category name
74*89c4ff92SAndroid Build Coastguard Worker         const std::string& parentCategoryNameValue = parentCategoryName.value();
75*89c4ff92SAndroid Build Coastguard Worker         if (parentCategoryNameValue.empty())
76*89c4ff92SAndroid Build Coastguard Worker         {
77*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
78*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to connect a device (name: \"{}\") to an invalid "
79*89c4ff92SAndroid Build Coastguard Worker                             "parent category (name: \"{}\")",
80*89c4ff92SAndroid Build Coastguard Worker                             deviceName,
81*89c4ff92SAndroid Build Coastguard Worker                             parentCategoryNameValue));
82*89c4ff92SAndroid Build Coastguard Worker         }
83*89c4ff92SAndroid Build Coastguard Worker 
84*89c4ff92SAndroid Build Coastguard Worker         // Check that the given parent category is already registered
85*89c4ff92SAndroid Build Coastguard Worker         auto categoryIt = FindCategory(parentCategoryNameValue);
86*89c4ff92SAndroid Build Coastguard Worker         if (categoryIt == m_Categories.end())
87*89c4ff92SAndroid Build Coastguard Worker         {
88*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
89*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to connect a device (name: \"{}\") to a parent category that "
90*89c4ff92SAndroid Build Coastguard Worker                             "is not registered (name: \"{}\")",
91*89c4ff92SAndroid Build Coastguard Worker                             deviceName,
92*89c4ff92SAndroid Build Coastguard Worker                             parentCategoryNameValue));
93*89c4ff92SAndroid Build Coastguard Worker         }
94*89c4ff92SAndroid Build Coastguard Worker     }
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker     // Get the device UID
97*89c4ff92SAndroid Build Coastguard Worker     uint16_t deviceUid = GetNextUid();
98*89c4ff92SAndroid Build Coastguard Worker 
99*89c4ff92SAndroid Build Coastguard Worker     // Create the device
100*89c4ff92SAndroid Build Coastguard Worker     DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
101*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(device);
102*89c4ff92SAndroid Build Coastguard Worker 
103*89c4ff92SAndroid Build Coastguard Worker     // Get the raw device pointer
104*89c4ff92SAndroid Build Coastguard Worker     const Device* devicePtr = device.get();
105*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(devicePtr);
106*89c4ff92SAndroid Build Coastguard Worker 
107*89c4ff92SAndroid Build Coastguard Worker     // Register the device
108*89c4ff92SAndroid Build Coastguard Worker     m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
109*89c4ff92SAndroid Build Coastguard Worker 
110*89c4ff92SAndroid Build Coastguard Worker     return devicePtr;
111*89c4ff92SAndroid Build Coastguard Worker }
112*89c4ff92SAndroid Build Coastguard Worker 
RegisterCounterSet(const std::string & counterSetName,uint16_t count,const arm::pipe::Optional<std::string> & parentCategoryName)113*89c4ff92SAndroid Build Coastguard Worker const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
114*89c4ff92SAndroid Build Coastguard Worker                                                        uint16_t count,
115*89c4ff92SAndroid Build Coastguard Worker                                                        const arm::pipe::Optional<std::string>& parentCategoryName)
116*89c4ff92SAndroid Build Coastguard Worker {
117*89c4ff92SAndroid Build Coastguard Worker     // Check that the given counter set name is valid
118*89c4ff92SAndroid Build Coastguard Worker     if (counterSetName.empty() ||
119*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(counterSetName))
120*89c4ff92SAndroid Build Coastguard Worker     {
121*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter set with an invalid name");
122*89c4ff92SAndroid Build Coastguard Worker     }
123*89c4ff92SAndroid Build Coastguard Worker 
124*89c4ff92SAndroid Build Coastguard Worker     // Check that a counter set with the given name is not already registered
125*89c4ff92SAndroid Build Coastguard Worker     if (IsCounterSetRegistered(counterSetName))
126*89c4ff92SAndroid Build Coastguard Worker     {
127*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException(
128*89c4ff92SAndroid Build Coastguard Worker             fmt::format("Trying to register a counter set already registered (\"{}\")", counterSetName));
129*89c4ff92SAndroid Build Coastguard Worker     }
130*89c4ff92SAndroid Build Coastguard Worker 
131*89c4ff92SAndroid Build Coastguard Worker     // Peek the next UID, do not get an actual valid UID just now as we don't want to waste a good UID in case
132*89c4ff92SAndroid Build Coastguard Worker     // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
133*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterSetUidPeek = GetNextUid(true);
134*89c4ff92SAndroid Build Coastguard Worker 
135*89c4ff92SAndroid Build Coastguard Worker     // Check that a category with the given (optional) parent category name is already registered
136*89c4ff92SAndroid Build Coastguard Worker     if (parentCategoryName.has_value())
137*89c4ff92SAndroid Build Coastguard Worker     {
138*89c4ff92SAndroid Build Coastguard Worker         // Get the (optional) parent category name
139*89c4ff92SAndroid Build Coastguard Worker         const std::string& parentCategoryNameValue = parentCategoryName.value();
140*89c4ff92SAndroid Build Coastguard Worker         if (parentCategoryNameValue.empty())
141*89c4ff92SAndroid Build Coastguard Worker         {
142*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
143*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to connect a counter set (UID: {}) to an invalid "
144*89c4ff92SAndroid Build Coastguard Worker                                     "parent category (name: \"{}\")",
145*89c4ff92SAndroid Build Coastguard Worker                                     counterSetUidPeek,
146*89c4ff92SAndroid Build Coastguard Worker                                     parentCategoryNameValue));
147*89c4ff92SAndroid Build Coastguard Worker         }
148*89c4ff92SAndroid Build Coastguard Worker 
149*89c4ff92SAndroid Build Coastguard Worker         // Check that the given parent category is already registered
150*89c4ff92SAndroid Build Coastguard Worker         auto it = FindCategory(parentCategoryNameValue);
151*89c4ff92SAndroid Build Coastguard Worker         if (it == m_Categories.end())
152*89c4ff92SAndroid Build Coastguard Worker         {
153*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
154*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to connect a counter set (UID: {}) to a parent category "
155*89c4ff92SAndroid Build Coastguard Worker                             "that is not registered (name: \"{}\")",
156*89c4ff92SAndroid Build Coastguard Worker                             counterSetUidPeek,
157*89c4ff92SAndroid Build Coastguard Worker                             parentCategoryNameValue));
158*89c4ff92SAndroid Build Coastguard Worker         }
159*89c4ff92SAndroid Build Coastguard Worker     }
160*89c4ff92SAndroid Build Coastguard Worker 
161*89c4ff92SAndroid Build Coastguard Worker     // Get the counter set UID
162*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterSetUid = GetNextUid();
163*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterSetUid == counterSetUidPeek);
164*89c4ff92SAndroid Build Coastguard Worker 
165*89c4ff92SAndroid Build Coastguard Worker     // Create the counter set
166*89c4ff92SAndroid Build Coastguard Worker     CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
167*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterSet);
168*89c4ff92SAndroid Build Coastguard Worker 
169*89c4ff92SAndroid Build Coastguard Worker     // Get the raw counter set pointer
170*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetPtr = counterSet.get();
171*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterSetPtr);
172*89c4ff92SAndroid Build Coastguard Worker 
173*89c4ff92SAndroid Build Coastguard Worker     // Register the counter set
174*89c4ff92SAndroid Build Coastguard Worker     m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
175*89c4ff92SAndroid Build Coastguard Worker 
176*89c4ff92SAndroid Build Coastguard Worker     return counterSetPtr;
177*89c4ff92SAndroid Build Coastguard Worker }
178*89c4ff92SAndroid Build Coastguard Worker 
RegisterCounter(const std::string & applicationName,const uint16_t uid,const std::string & parentCategoryName,uint16_t counterClass,uint16_t interpolation,double multiplier,const std::string & name,const std::string & description,const arm::pipe::Optional<std::string> & units,const arm::pipe::Optional<uint16_t> & numberOfCores,const arm::pipe::Optional<uint16_t> & deviceUid,const arm::pipe::Optional<uint16_t> & counterSetUid)179*89c4ff92SAndroid Build Coastguard Worker const Counter* CounterDirectory::RegisterCounter(const std::string& applicationName,
180*89c4ff92SAndroid Build Coastguard Worker                                                  const uint16_t uid,
181*89c4ff92SAndroid Build Coastguard Worker                                                  const std::string& parentCategoryName,
182*89c4ff92SAndroid Build Coastguard Worker                                                  uint16_t counterClass,
183*89c4ff92SAndroid Build Coastguard Worker                                                  uint16_t interpolation,
184*89c4ff92SAndroid Build Coastguard Worker                                                  double multiplier,
185*89c4ff92SAndroid Build Coastguard Worker                                                  const std::string& name,
186*89c4ff92SAndroid Build Coastguard Worker                                                  const std::string& description,
187*89c4ff92SAndroid Build Coastguard Worker                                                  const arm::pipe::Optional<std::string>& units,
188*89c4ff92SAndroid Build Coastguard Worker                                                  const arm::pipe::Optional<uint16_t>& numberOfCores,
189*89c4ff92SAndroid Build Coastguard Worker                                                  const arm::pipe::Optional<uint16_t>& deviceUid,
190*89c4ff92SAndroid Build Coastguard Worker                                                  const arm::pipe::Optional<uint16_t>& counterSetUid)
191*89c4ff92SAndroid Build Coastguard Worker {
192*89c4ff92SAndroid Build Coastguard Worker     // Check that the given parent category name is valid
193*89c4ff92SAndroid Build Coastguard Worker     if (parentCategoryName.empty() ||
194*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(parentCategoryName))
195*89c4ff92SAndroid Build Coastguard Worker     {
196*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid parent category name");
197*89c4ff92SAndroid Build Coastguard Worker     }
198*89c4ff92SAndroid Build Coastguard Worker 
199*89c4ff92SAndroid Build Coastguard Worker     // Check that the given class is valid
200*89c4ff92SAndroid Build Coastguard Worker     if (counterClass != 0 && counterClass != 1)
201*89c4ff92SAndroid Build Coastguard Worker     {
202*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid class");
203*89c4ff92SAndroid Build Coastguard Worker     }
204*89c4ff92SAndroid Build Coastguard Worker 
205*89c4ff92SAndroid Build Coastguard Worker     // Check that the given interpolation is valid
206*89c4ff92SAndroid Build Coastguard Worker     if (interpolation != 0 && interpolation != 1)
207*89c4ff92SAndroid Build Coastguard Worker     {
208*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid interpolation");
209*89c4ff92SAndroid Build Coastguard Worker     }
210*89c4ff92SAndroid Build Coastguard Worker 
211*89c4ff92SAndroid Build Coastguard Worker     // Check that the given multiplier is valid
212*89c4ff92SAndroid Build Coastguard Worker     if (multiplier == .0f)
213*89c4ff92SAndroid Build Coastguard Worker     {
214*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid multiplier");
215*89c4ff92SAndroid Build Coastguard Worker     }
216*89c4ff92SAndroid Build Coastguard Worker 
217*89c4ff92SAndroid Build Coastguard Worker     // Check that the given name is valid
218*89c4ff92SAndroid Build Coastguard Worker     if (name.empty() ||
219*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(name))
220*89c4ff92SAndroid Build Coastguard Worker     {
221*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid name");
222*89c4ff92SAndroid Build Coastguard Worker     }
223*89c4ff92SAndroid Build Coastguard Worker 
224*89c4ff92SAndroid Build Coastguard Worker     // Check that the given description is valid
225*89c4ff92SAndroid Build Coastguard Worker     if (description.empty() ||
226*89c4ff92SAndroid Build Coastguard Worker             !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(description))
227*89c4ff92SAndroid Build Coastguard Worker     {
228*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid description");
229*89c4ff92SAndroid Build Coastguard Worker     }
230*89c4ff92SAndroid Build Coastguard Worker 
231*89c4ff92SAndroid Build Coastguard Worker     // Check that the given units are valid
232*89c4ff92SAndroid Build Coastguard Worker     if (units.has_value()
233*89c4ff92SAndroid Build Coastguard Worker             && !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(units.value()))
234*89c4ff92SAndroid Build Coastguard Worker     {
235*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException("Trying to register a counter with a invalid units");
236*89c4ff92SAndroid Build Coastguard Worker     }
237*89c4ff92SAndroid Build Coastguard Worker 
238*89c4ff92SAndroid Build Coastguard Worker     // Check that the given parent category is registered
239*89c4ff92SAndroid Build Coastguard Worker     auto categoryIt = FindCategory(parentCategoryName);
240*89c4ff92SAndroid Build Coastguard Worker     if (categoryIt == m_Categories.end())
241*89c4ff92SAndroid Build Coastguard Worker     {
242*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::InvalidArgumentException(
243*89c4ff92SAndroid Build Coastguard Worker             fmt::format("Trying to connect a counter to a category that is not registered (name: \"{}\")",
244*89c4ff92SAndroid Build Coastguard Worker                         parentCategoryName));
245*89c4ff92SAndroid Build Coastguard Worker     }
246*89c4ff92SAndroid Build Coastguard Worker 
247*89c4ff92SAndroid Build Coastguard Worker     // Get the parent category
248*89c4ff92SAndroid Build Coastguard Worker     const CategoryPtr& parentCategory = *categoryIt;
249*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(parentCategory);
250*89c4ff92SAndroid Build Coastguard Worker 
251*89c4ff92SAndroid Build Coastguard Worker     // Check that a counter with the given name is not already registered within the parent category
252*89c4ff92SAndroid Build Coastguard Worker     const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
253*89c4ff92SAndroid Build Coastguard Worker     for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
254*89c4ff92SAndroid Build Coastguard Worker     {
255*89c4ff92SAndroid Build Coastguard Worker         const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
256*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(parentCategoryCounter);
257*89c4ff92SAndroid Build Coastguard Worker 
258*89c4ff92SAndroid Build Coastguard Worker         if (parentCategoryCounter->m_Name == name)
259*89c4ff92SAndroid Build Coastguard Worker         {
260*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
261*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to register a counter to category \"{}\" with a name that "
262*89c4ff92SAndroid Build Coastguard Worker                             "is already used within that category (name: \"{}\")",
263*89c4ff92SAndroid Build Coastguard Worker                             parentCategoryName,
264*89c4ff92SAndroid Build Coastguard Worker                             name));
265*89c4ff92SAndroid Build Coastguard Worker         }
266*89c4ff92SAndroid Build Coastguard Worker     }
267*89c4ff92SAndroid Build Coastguard Worker 
268*89c4ff92SAndroid Build Coastguard Worker     // Check that a counter set with the given (optional) UID is already registered
269*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
270*89c4ff92SAndroid Build Coastguard Worker     if (counterSetUidValue > 0)
271*89c4ff92SAndroid Build Coastguard Worker     {
272*89c4ff92SAndroid Build Coastguard Worker         // Check that the (optional) counter set is already registered
273*89c4ff92SAndroid Build Coastguard Worker         if (!IsCounterSetRegistered(counterSetUidValue))
274*89c4ff92SAndroid Build Coastguard Worker         {
275*89c4ff92SAndroid Build Coastguard Worker             throw InvalidArgumentException(
276*89c4ff92SAndroid Build Coastguard Worker                         fmt::format("Trying to connect a counter to a counter set that is "
277*89c4ff92SAndroid Build Coastguard Worker                                     "not registered (counter set UID: {})",
278*89c4ff92SAndroid Build Coastguard Worker                                     counterSetUidValue));
279*89c4ff92SAndroid Build Coastguard Worker         }
280*89c4ff92SAndroid Build Coastguard Worker     }
281*89c4ff92SAndroid Build Coastguard Worker 
282*89c4ff92SAndroid Build Coastguard Worker     // Get the number of cores (this call may throw)
283*89c4ff92SAndroid Build Coastguard Worker     uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
284*89c4ff92SAndroid Build Coastguard Worker     uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue);
285*89c4ff92SAndroid Build Coastguard Worker 
286*89c4ff92SAndroid Build Coastguard Worker     // Get the counter UIDs and calculate the max counter UID
287*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
288*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(!counterUids.empty());
289*89c4ff92SAndroid Build Coastguard Worker     uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
290*89c4ff92SAndroid Build Coastguard Worker 
291*89c4ff92SAndroid Build Coastguard Worker     // Get the counter units
292*89c4ff92SAndroid Build Coastguard Worker     const std::string unitsValue = units.has_value() ? units.value() : "";
293*89c4ff92SAndroid Build Coastguard Worker 
294*89c4ff92SAndroid Build Coastguard Worker     // Create the counter
295*89c4ff92SAndroid Build Coastguard Worker     CounterPtr counter = std::make_shared<Counter>(applicationName,
296*89c4ff92SAndroid Build Coastguard Worker                                                    counterUids.front(),
297*89c4ff92SAndroid Build Coastguard Worker                                                    maxCounterUid,
298*89c4ff92SAndroid Build Coastguard Worker                                                    counterClass,
299*89c4ff92SAndroid Build Coastguard Worker                                                    interpolation,
300*89c4ff92SAndroid Build Coastguard Worker                                                    multiplier,
301*89c4ff92SAndroid Build Coastguard Worker                                                    name,
302*89c4ff92SAndroid Build Coastguard Worker                                                    description,
303*89c4ff92SAndroid Build Coastguard Worker                                                    unitsValue,
304*89c4ff92SAndroid Build Coastguard Worker                                                    deviceUidValue,
305*89c4ff92SAndroid Build Coastguard Worker                                                    counterSetUidValue);
306*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counter);
307*89c4ff92SAndroid Build Coastguard Worker 
308*89c4ff92SAndroid Build Coastguard Worker     // Get the raw counter pointer
309*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterPtr = counter.get();
310*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterPtr);
311*89c4ff92SAndroid Build Coastguard Worker 
312*89c4ff92SAndroid Build Coastguard Worker     // Process multiple counters if necessary
313*89c4ff92SAndroid Build Coastguard Worker     for (uint16_t counterUid : counterUids)
314*89c4ff92SAndroid Build Coastguard Worker     {
315*89c4ff92SAndroid Build Coastguard Worker         // Connect the counter to the parent category
316*89c4ff92SAndroid Build Coastguard Worker         parentCategory->m_Counters.push_back(counterUid);
317*89c4ff92SAndroid Build Coastguard Worker 
318*89c4ff92SAndroid Build Coastguard Worker         // Register the counter
319*89c4ff92SAndroid Build Coastguard Worker         m_Counters.insert(std::make_pair(counterUid, counter));
320*89c4ff92SAndroid Build Coastguard Worker     }
321*89c4ff92SAndroid Build Coastguard Worker 
322*89c4ff92SAndroid Build Coastguard Worker     return counterPtr;
323*89c4ff92SAndroid Build Coastguard Worker }
324*89c4ff92SAndroid Build Coastguard Worker 
GetCategory(const std::string & categoryName) const325*89c4ff92SAndroid Build Coastguard Worker const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
326*89c4ff92SAndroid Build Coastguard Worker {
327*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCategory(categoryName);
328*89c4ff92SAndroid Build Coastguard Worker     if (it == m_Categories.end())
329*89c4ff92SAndroid Build Coastguard Worker     {
330*89c4ff92SAndroid Build Coastguard Worker         return nullptr;
331*89c4ff92SAndroid Build Coastguard Worker     }
332*89c4ff92SAndroid Build Coastguard Worker 
333*89c4ff92SAndroid Build Coastguard Worker     const Category* category = it->get();
334*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(category);
335*89c4ff92SAndroid Build Coastguard Worker 
336*89c4ff92SAndroid Build Coastguard Worker     return category;
337*89c4ff92SAndroid Build Coastguard Worker }
338*89c4ff92SAndroid Build Coastguard Worker 
GetDevice(uint16_t deviceUid) const339*89c4ff92SAndroid Build Coastguard Worker const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
340*89c4ff92SAndroid Build Coastguard Worker {
341*89c4ff92SAndroid Build Coastguard Worker     auto it = FindDevice(deviceUid);
342*89c4ff92SAndroid Build Coastguard Worker     if (it == m_Devices.end())
343*89c4ff92SAndroid Build Coastguard Worker     {
344*89c4ff92SAndroid Build Coastguard Worker         return nullptr;
345*89c4ff92SAndroid Build Coastguard Worker     }
346*89c4ff92SAndroid Build Coastguard Worker 
347*89c4ff92SAndroid Build Coastguard Worker     const Device* device = it->second.get();
348*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(device);
349*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(device->m_Uid == deviceUid);
350*89c4ff92SAndroid Build Coastguard Worker 
351*89c4ff92SAndroid Build Coastguard Worker     return device;
352*89c4ff92SAndroid Build Coastguard Worker }
353*89c4ff92SAndroid Build Coastguard Worker 
GetCounterSet(uint16_t counterSetUid) const354*89c4ff92SAndroid Build Coastguard Worker const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
355*89c4ff92SAndroid Build Coastguard Worker {
356*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounterSet(counterSetUid);
357*89c4ff92SAndroid Build Coastguard Worker     if (it == m_CounterSets.end())
358*89c4ff92SAndroid Build Coastguard Worker     {
359*89c4ff92SAndroid Build Coastguard Worker         return nullptr;
360*89c4ff92SAndroid Build Coastguard Worker     }
361*89c4ff92SAndroid Build Coastguard Worker 
362*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSet = it->second.get();
363*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterSet);
364*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counterSet->m_Uid == counterSetUid);
365*89c4ff92SAndroid Build Coastguard Worker 
366*89c4ff92SAndroid Build Coastguard Worker     return counterSet;
367*89c4ff92SAndroid Build Coastguard Worker }
368*89c4ff92SAndroid Build Coastguard Worker 
GetCounter(uint16_t counterUid) const369*89c4ff92SAndroid Build Coastguard Worker const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
370*89c4ff92SAndroid Build Coastguard Worker {
371*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounter(counterUid);
372*89c4ff92SAndroid Build Coastguard Worker     if (it == m_Counters.end())
373*89c4ff92SAndroid Build Coastguard Worker     {
374*89c4ff92SAndroid Build Coastguard Worker         return nullptr;
375*89c4ff92SAndroid Build Coastguard Worker     }
376*89c4ff92SAndroid Build Coastguard Worker 
377*89c4ff92SAndroid Build Coastguard Worker     const Counter* counter = it->second.get();
378*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counter);
379*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counter->m_Uid <= counterUid);
380*89c4ff92SAndroid Build Coastguard Worker     ARM_PIPE_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
381*89c4ff92SAndroid Build Coastguard Worker 
382*89c4ff92SAndroid Build Coastguard Worker     return counter;
383*89c4ff92SAndroid Build Coastguard Worker }
384*89c4ff92SAndroid Build Coastguard Worker 
IsCategoryRegistered(const std::string & categoryName) const385*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsCategoryRegistered(const std::string& categoryName) const
386*89c4ff92SAndroid Build Coastguard Worker {
387*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCategory(categoryName);
388*89c4ff92SAndroid Build Coastguard Worker 
389*89c4ff92SAndroid Build Coastguard Worker     return it != m_Categories.end();
390*89c4ff92SAndroid Build Coastguard Worker }
391*89c4ff92SAndroid Build Coastguard Worker 
IsDeviceRegistered(uint16_t deviceUid) const392*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsDeviceRegistered(uint16_t deviceUid) const
393*89c4ff92SAndroid Build Coastguard Worker {
394*89c4ff92SAndroid Build Coastguard Worker     auto it = FindDevice(deviceUid);
395*89c4ff92SAndroid Build Coastguard Worker 
396*89c4ff92SAndroid Build Coastguard Worker     return it != m_Devices.end();
397*89c4ff92SAndroid Build Coastguard Worker }
398*89c4ff92SAndroid Build Coastguard Worker 
IsDeviceRegistered(const std::string & deviceName) const399*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsDeviceRegistered(const std::string& deviceName) const
400*89c4ff92SAndroid Build Coastguard Worker {
401*89c4ff92SAndroid Build Coastguard Worker     auto it = FindDevice(deviceName);
402*89c4ff92SAndroid Build Coastguard Worker 
403*89c4ff92SAndroid Build Coastguard Worker     return it != m_Devices.end();
404*89c4ff92SAndroid Build Coastguard Worker }
405*89c4ff92SAndroid Build Coastguard Worker 
IsCounterSetRegistered(uint16_t counterSetUid) const406*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsCounterSetRegistered(uint16_t counterSetUid) const
407*89c4ff92SAndroid Build Coastguard Worker {
408*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounterSet(counterSetUid);
409*89c4ff92SAndroid Build Coastguard Worker 
410*89c4ff92SAndroid Build Coastguard Worker     return it != m_CounterSets.end();
411*89c4ff92SAndroid Build Coastguard Worker }
412*89c4ff92SAndroid Build Coastguard Worker 
IsCounterSetRegistered(const std::string & counterSetName) const413*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsCounterSetRegistered(const std::string& counterSetName) const
414*89c4ff92SAndroid Build Coastguard Worker {
415*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounterSet(counterSetName);
416*89c4ff92SAndroid Build Coastguard Worker 
417*89c4ff92SAndroid Build Coastguard Worker     return it != m_CounterSets.end();
418*89c4ff92SAndroid Build Coastguard Worker }
419*89c4ff92SAndroid Build Coastguard Worker 
IsCounterRegistered(uint16_t counterUid) const420*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsCounterRegistered(uint16_t counterUid) const
421*89c4ff92SAndroid Build Coastguard Worker {
422*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounter(counterUid);
423*89c4ff92SAndroid Build Coastguard Worker 
424*89c4ff92SAndroid Build Coastguard Worker     return it != m_Counters.end();
425*89c4ff92SAndroid Build Coastguard Worker }
426*89c4ff92SAndroid Build Coastguard Worker 
IsCounterRegistered(const std::string & counterName) const427*89c4ff92SAndroid Build Coastguard Worker bool CounterDirectory::IsCounterRegistered(const std::string& counterName) const
428*89c4ff92SAndroid Build Coastguard Worker {
429*89c4ff92SAndroid Build Coastguard Worker     auto it = FindCounter(counterName);
430*89c4ff92SAndroid Build Coastguard Worker 
431*89c4ff92SAndroid Build Coastguard Worker     return it != m_Counters.end();
432*89c4ff92SAndroid Build Coastguard Worker }
433*89c4ff92SAndroid Build Coastguard Worker 
Clear()434*89c4ff92SAndroid Build Coastguard Worker void CounterDirectory::Clear()
435*89c4ff92SAndroid Build Coastguard Worker {
436*89c4ff92SAndroid Build Coastguard Worker     // Clear all the counter directory contents
437*89c4ff92SAndroid Build Coastguard Worker     m_Categories.clear();
438*89c4ff92SAndroid Build Coastguard Worker     m_Devices.clear();
439*89c4ff92SAndroid Build Coastguard Worker     m_CounterSets.clear();
440*89c4ff92SAndroid Build Coastguard Worker     m_Counters.clear();
441*89c4ff92SAndroid Build Coastguard Worker }
442*89c4ff92SAndroid Build Coastguard Worker 
FindCategory(const std::string & categoryName) const443*89c4ff92SAndroid Build Coastguard Worker CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
444*89c4ff92SAndroid Build Coastguard Worker {
445*89c4ff92SAndroid Build Coastguard Worker     return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
446*89c4ff92SAndroid Build Coastguard Worker     {
447*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(category);
448*89c4ff92SAndroid Build Coastguard Worker 
449*89c4ff92SAndroid Build Coastguard Worker         return category->m_Name == categoryName;
450*89c4ff92SAndroid Build Coastguard Worker     });
451*89c4ff92SAndroid Build Coastguard Worker }
452*89c4ff92SAndroid Build Coastguard Worker 
FindDevice(uint16_t deviceUid) const453*89c4ff92SAndroid Build Coastguard Worker DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
454*89c4ff92SAndroid Build Coastguard Worker {
455*89c4ff92SAndroid Build Coastguard Worker     return m_Devices.find(deviceUid);
456*89c4ff92SAndroid Build Coastguard Worker }
457*89c4ff92SAndroid Build Coastguard Worker 
FindDevice(const std::string & deviceName) const458*89c4ff92SAndroid Build Coastguard Worker DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
459*89c4ff92SAndroid Build Coastguard Worker {
460*89c4ff92SAndroid Build Coastguard Worker     return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
461*89c4ff92SAndroid Build Coastguard Worker     {
462*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.second);
463*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.second->m_Uid == pair.first);
464*89c4ff92SAndroid Build Coastguard Worker 
465*89c4ff92SAndroid Build Coastguard Worker         return pair.second->m_Name == deviceName;
466*89c4ff92SAndroid Build Coastguard Worker     });
467*89c4ff92SAndroid Build Coastguard Worker }
468*89c4ff92SAndroid Build Coastguard Worker 
FindCounterSet(uint16_t counterSetUid) const469*89c4ff92SAndroid Build Coastguard Worker CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
470*89c4ff92SAndroid Build Coastguard Worker {
471*89c4ff92SAndroid Build Coastguard Worker     return m_CounterSets.find(counterSetUid);
472*89c4ff92SAndroid Build Coastguard Worker }
473*89c4ff92SAndroid Build Coastguard Worker 
FindCounterSet(const std::string & counterSetName) const474*89c4ff92SAndroid Build Coastguard Worker CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
475*89c4ff92SAndroid Build Coastguard Worker {
476*89c4ff92SAndroid Build Coastguard Worker     return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
477*89c4ff92SAndroid Build Coastguard Worker     {
478*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.second);
479*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.second->m_Uid == pair.first);
480*89c4ff92SAndroid Build Coastguard Worker 
481*89c4ff92SAndroid Build Coastguard Worker         return pair.second->m_Name == counterSetName;
482*89c4ff92SAndroid Build Coastguard Worker     });
483*89c4ff92SAndroid Build Coastguard Worker }
484*89c4ff92SAndroid Build Coastguard Worker 
FindCounter(uint16_t counterUid) const485*89c4ff92SAndroid Build Coastguard Worker CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
486*89c4ff92SAndroid Build Coastguard Worker {
487*89c4ff92SAndroid Build Coastguard Worker     return m_Counters.find(counterUid);
488*89c4ff92SAndroid Build Coastguard Worker }
489*89c4ff92SAndroid Build Coastguard Worker 
FindCounter(const std::string & counterName) const490*89c4ff92SAndroid Build Coastguard Worker CountersIt CounterDirectory::FindCounter(const std::string& counterName) const
491*89c4ff92SAndroid Build Coastguard Worker {
492*89c4ff92SAndroid Build Coastguard Worker     return std::find_if(m_Counters.begin(), m_Counters.end(), [&counterName](const auto& pair)
493*89c4ff92SAndroid Build Coastguard Worker     {
494*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.second);
495*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(pair.first >= pair.second->m_Uid && pair.first <= pair.second->m_MaxCounterUid);
496*89c4ff92SAndroid Build Coastguard Worker 
497*89c4ff92SAndroid Build Coastguard Worker         return pair.second->m_Name == counterName;
498*89c4ff92SAndroid Build Coastguard Worker     });
499*89c4ff92SAndroid Build Coastguard Worker }
500*89c4ff92SAndroid Build Coastguard Worker 
GetNumberOfCores(const arm::pipe::Optional<uint16_t> & numberOfCores,uint16_t deviceUid)501*89c4ff92SAndroid Build Coastguard Worker uint16_t CounterDirectory::GetNumberOfCores(const arm::pipe::Optional<uint16_t>& numberOfCores,
502*89c4ff92SAndroid Build Coastguard Worker                                             uint16_t deviceUid)
503*89c4ff92SAndroid Build Coastguard Worker {
504*89c4ff92SAndroid Build Coastguard Worker     // To get the number of cores, apply the following rules:
505*89c4ff92SAndroid Build Coastguard Worker     //
506*89c4ff92SAndroid Build Coastguard Worker     // 1. If numberOfCores is set then take it as the deviceCores value
507*89c4ff92SAndroid Build Coastguard Worker     // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
508*89c4ff92SAndroid Build Coastguard Worker     //    if so then that devices number of cores is taken as the deviceCores value
509*89c4ff92SAndroid Build Coastguard Worker     // 3. If none of the above holds then set deviceCores to zero
510*89c4ff92SAndroid Build Coastguard Worker 
511*89c4ff92SAndroid Build Coastguard Worker     // 1. If numberOfCores is set then take it as the deviceCores value
512*89c4ff92SAndroid Build Coastguard Worker     if (numberOfCores.has_value())
513*89c4ff92SAndroid Build Coastguard Worker     {
514*89c4ff92SAndroid Build Coastguard Worker         // Get the number of cores
515*89c4ff92SAndroid Build Coastguard Worker         return numberOfCores.value();
516*89c4ff92SAndroid Build Coastguard Worker     }
517*89c4ff92SAndroid Build Coastguard Worker 
518*89c4ff92SAndroid Build Coastguard Worker     // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
519*89c4ff92SAndroid Build Coastguard Worker     //    if so then that devices number of cores is taken as the deviceCores value
520*89c4ff92SAndroid Build Coastguard Worker     if (deviceUid > 0)
521*89c4ff92SAndroid Build Coastguard Worker     {
522*89c4ff92SAndroid Build Coastguard Worker         // Check that the (optional) device is already registered
523*89c4ff92SAndroid Build Coastguard Worker         auto deviceIt = FindDevice(deviceUid);
524*89c4ff92SAndroid Build Coastguard Worker         if (deviceIt == m_Devices.end())
525*89c4ff92SAndroid Build Coastguard Worker         {
526*89c4ff92SAndroid Build Coastguard Worker             throw arm::pipe::InvalidArgumentException(
527*89c4ff92SAndroid Build Coastguard Worker                 fmt::format("Trying to connect a counter to a device that is not registered (device UID {})",
528*89c4ff92SAndroid Build Coastguard Worker                             deviceUid));
529*89c4ff92SAndroid Build Coastguard Worker         }
530*89c4ff92SAndroid Build Coastguard Worker 
531*89c4ff92SAndroid Build Coastguard Worker         // Get the associated device
532*89c4ff92SAndroid Build Coastguard Worker         const DevicePtr& device = deviceIt->second;
533*89c4ff92SAndroid Build Coastguard Worker         ARM_PIPE_ASSERT(device);
534*89c4ff92SAndroid Build Coastguard Worker 
535*89c4ff92SAndroid Build Coastguard Worker 
536*89c4ff92SAndroid Build Coastguard Worker         // Get the number of cores of the associated device
537*89c4ff92SAndroid Build Coastguard Worker         return device->m_Cores;
538*89c4ff92SAndroid Build Coastguard Worker     }
539*89c4ff92SAndroid Build Coastguard Worker 
540*89c4ff92SAndroid Build Coastguard Worker     // 3. If none of the above holds then set deviceCores to zero
541*89c4ff92SAndroid Build Coastguard Worker     return 0;
542*89c4ff92SAndroid Build Coastguard Worker }
543*89c4ff92SAndroid Build Coastguard Worker 
544*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
545*89c4ff92SAndroid Build Coastguard Worker 
546*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
547