Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
dcdb
dcdb
Commits
189ec008
Commit
189ec008
authored
Dec 21, 2018
by
Micha Mueller
Browse files
Perf plugin: add support for single_counters in config files
parent
9aa3d09a
Changes
3
Hide whitespace changes
Inline
Side-by-side
config/perfevent.conf
View file @
189ec008
...
...
@@ -16,6 +16,15 @@ template_group def2 {
mqttpart
xx
}
template_single_counter
def3
{
interval
2000
mqttpart
xx
minValues
3
cpus
1
-
3
type
PERF_TYPE_HARDWARE
config
PERF_COUNT_HW_CACHE_REFERENCES
}
group
hw_i
{
default
def1
mqttpart
xx
...
...
@@ -44,23 +53,19 @@ group hw_bm {
}
}
group
cache
{
interval
2000
mqttpart
xx
single_counter
cacheReferences
{
default
def3
cpus
2
-
3
mqttsuffix
10
}
single_counter
cacheMisses
{
interval
2000
mqttpart
xxxx
minValues
3
cpus
2
-
3
counter
references
{
mqttsuffix
10
type
PERF_TYPE_HARDWARE
config
PERF_COUNT_HW_CACHE_REFERENCES
}
counter
misses
{
mqttsuffix
20
type
PERF_TYPE_HARDWARE
config
PERF_COUNT_HW_CACHE_MISSES
}
cpus
2
-
3
type
PERF_TYPE_HARDWARE
config
PERF_COUNT_HW_CACHE_MISSES
}
group
sw
{
...
...
src/sensors/perfevent/PerfeventConfigurator.cpp
View file @
189ec008
...
...
@@ -124,57 +124,88 @@ bool PerfeventConfigurator::readConfig(std::string cfgPath) {
auto
ret
=
_templateSensorGroups
.
insert
(
std
::
pair
<
std
::
string
,
PerfSensorGroup
*>
(
val
.
second
.
data
(),
group
));
if
(
!
ret
.
second
)
{
LOG
(
warning
)
<<
"Template "
<<
_groupName
<<
" "
<<
val
.
second
.
data
()
<<
" already exists! Omitting..."
;
delete
group
;
}
}
else
{
LOG
(
warning
)
<<
"Template "
<<
_groupName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
delete
group
;
}
}
//template single sensor
}
else
if
(
boost
::
iequals
(
val
.
first
,
"template_single_"
+
_baseName
))
{
LOG
(
debug
)
<<
"Template single "
<<
_baseName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
"
;
if
(
!
val
.
second
.
empty
())
{
PerfSensorGroup
*
group
=
new
PerfSensorGroup
(
val
.
second
.
data
());
if
(
readSensorGroup
(
*
group
,
val
.
second
))
{
//check if cpus-list is given for this template single counter
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
cpus
=
val
.
second
.
get_child_optional
(
"cpus"
);
if
(
cpus
)
{
LOG
(
debug
)
<<
"Reading CPUs for
\"
"
<<
val
.
second
.
data
()
<<
"
\"
"
;
std
::
set
<
int
>
cpuVec
=
parseCpuString
(
cpus
.
get
().
data
());
_templateCpus
.
insert
(
templateCpuMap_t
::
value_type
(
val
.
second
.
data
(),
cpuVec
));
}
//group which consists of only one sensor
PerfSensorBase
*
sensor
=
new
PerfSensorBase
(
val
.
second
.
data
());
if
(
readSensorBase
(
*
sensor
,
val
.
second
))
{
group
->
pushBackSensor
(
sensor
);
auto
ret
=
_templateSensorGroups
.
insert
(
std
::
pair
<
std
::
string
,
PerfSensorGroup
*>
(
val
.
second
.
data
(),
group
));
if
(
!
ret
.
second
)
{
LOG
(
warning
)
<<
"Template single "
<<
_baseName
<<
" "
<<
val
.
second
.
data
()
<<
" already exists! Omitting..."
;
delete
group
;
}
}
else
{
LOG
(
warning
)
<<
"Template single "
<<
_baseName
<<
" "
<<
val
.
second
.
data
()
<<
" could not be read! Omitting"
;
delete
sensor
;
delete
group
;
}
}
else
{
LOG
(
warning
)
<<
"Template single "
<<
_baseName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
delete
group
;
}
}
}
else
if
(
boost
::
iequals
(
val
.
first
,
_groupName
))
{
LOG
(
debug
)
<<
_groupName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
"
;
if
(
!
val
.
second
.
empty
())
{
PerfSensorGroup
group
(
val
.
second
.
data
());
if
(
readSensorGroup
(
group
,
val
.
second
))
{
//now for the cpus...
//initialize set with cpuIDs
//default cpuSet: contains all cpuIDs
std
::
set
<
int
>
cpuSet
;
for
(
int
i
=
0
;
i
<
get_nprocs
();
i
++
)
{
cpuSet
.
insert
(
i
);
}
//check if (differing) cpus-list is given; if so, overwrite default cpuVec
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
cpus
=
val
.
second
.
get_child_optional
(
"cpus"
);
if
(
cpus
)
{
//cpu list given
cpuSet
=
parseCpuString
(
cpus
.
get
().
data
());
}
else
{
//cpu list not given, but perhaps template counter has one
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
def
=
val
.
second
.
get_child_optional
(
"default"
);
if
(
def
)
{
templateCpuMap_t
::
iterator
itC
=
_templateCpus
.
find
(
def
.
get
().
data
());
if
(
itC
!=
_templateCpus
.
end
())
{
cpuSet
=
itC
->
second
;
}
}
}
if
(
group
.
getMqttPart
().
size
()
==
0
)
{
LOG
(
warning
)
<<
_groupName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
has no mqttPart entry set. This is required as a place holder for the CPU id!"
;
}
//customize perfCounterGroup for every CPU
for
(
auto
i
:
cpuSet
)
{
PerfSensorGroup
*
perfSG
=
new
PerfSensorGroup
(
group
);
perfSG
->
setGroupName
(
SensorBase
::
formatName
(
perfSG
->
getGroupName
(),
i
));
perfSG
->
setCpuId
(
i
);
perfSG
->
setMqttPart
(
formatMqttCPU
(
group
.
getMqttPart
(),
i
)
+
"/"
);
for
(
auto
s
:
perfSG
->
getSensors
())
s
->
setName
(
s
->
getName
(),
i
);
storeSensorGroup
(
perfSG
);
}
customizeAndStore
(
group
,
val
.
second
);
}
else
{
LOG
(
warning
)
<<
_groupName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
}
}
//single sensor
}
else
if
(
boost
::
iequals
(
val
.
first
,
"single_"
+
_baseName
))
{
LOG
(
debug
)
<<
"Single "
<<
_baseName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
"
;
if
(
!
val
.
second
.
empty
())
{
PerfSensorGroup
group
(
val
.
second
.
data
());
if
(
readSensorGroup
(
group
,
val
.
second
))
{
//group which consists of only one sensor
PerfSensorBase
*
sensor
;
//perhaps one sensor is already present because it was copied from the template group
if
(
group
.
getSensors
().
size
()
!=
0
)
{
sensor
=
dynamic_cast
<
PerfSensorBase
*>
(
group
.
getSensors
()[
0
]);
sensor
->
setName
(
val
.
second
.
data
());
if
(
readSensorBase
(
*
sensor
,
val
.
second
))
{
customizeAndStore
(
group
,
val
.
second
);
}
else
{
LOG
(
warning
)
<<
"Single "
<<
_baseName
<<
" "
<<
val
.
second
.
data
()
<<
" could not be read! Omitting"
;
}
}
else
{
sensor
=
new
PerfSensorBase
(
val
.
second
.
data
());
if
(
readSensorBase
(
*
sensor
,
val
.
second
))
{
group
.
pushBackSensor
(
sensor
);
customizeAndStore
(
group
,
val
.
second
);
}
else
{
LOG
(
warning
)
<<
"Single "
<<
_baseName
<<
" "
<<
val
.
second
.
data
()
<<
" could not be read! Omitting"
;
delete
sensor
;
}
}
}
else
{
LOG
(
warning
)
<<
"Single "
<<
_baseName
<<
"
\"
"
<<
val
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
}
}
}
else
{
LOG
(
error
)
<<
"
\"
"
<<
val
.
first
<<
"
\"
: unknown construct!"
;
return
false
;
...
...
@@ -191,3 +222,42 @@ bool PerfeventConfigurator::readConfig(std::string cfgPath) {
_templateCpus
.
clear
();
return
true
;
}
void
PerfeventConfigurator
::
customizeAndStore
(
PerfSensorGroup
&
group
,
CFG_VAL
cfg
)
{
//initialize set with cpuIDs
//default cpuSet: contains all cpuIDs
std
::
set
<
int
>
cpuSet
;
for
(
int
i
=
0
;
i
<
get_nprocs
();
i
++
)
{
cpuSet
.
insert
(
i
);
}
//check if (differing) cpus-list is given; if so, overwrite default cpuVec
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
cpus
=
cfg
.
get_child_optional
(
"cpus"
);
if
(
cpus
)
{
//cpu list given
cpuSet
=
parseCpuString
(
cpus
.
get
().
data
());
}
else
{
//cpu list not given, but perhaps template counter has one
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
def
=
cfg
.
get_child_optional
(
"default"
);
if
(
def
)
{
templateCpuMap_t
::
iterator
itC
=
_templateCpus
.
find
(
def
.
get
().
data
());
if
(
itC
!=
_templateCpus
.
end
())
{
cpuSet
=
itC
->
second
;
}
}
}
if
(
group
.
getMqttPart
().
size
()
==
0
)
{
LOG
(
warning
)
<<
_groupName
<<
"
\"
"
<<
cfg
.
data
()
<<
"
\"
has no mqttPart entry set. This is required as a place holder for the CPU id!"
;
}
//customize perfCounterGroup for every CPU
for
(
auto
i
:
cpuSet
)
{
PerfSensorGroup
*
perfSG
=
new
PerfSensorGroup
(
group
);
perfSG
->
setGroupName
(
SensorBase
::
formatName
(
perfSG
->
getGroupName
(),
i
));
perfSG
->
setCpuId
(
i
);
perfSG
->
setMqttPart
(
formatMqttCPU
(
group
.
getMqttPart
(),
i
)
+
"/"
);
for
(
auto
s
:
perfSG
->
getSensors
())
s
->
setName
(
s
->
getName
(),
i
);
storeSensorGroup
(
perfSG
);
}
}
src/sensors/perfevent/PerfeventConfigurator.h
View file @
189ec008
...
...
@@ -29,6 +29,17 @@ protected:
bool
readConfig
(
std
::
string
cfgPath
)
override
;
private:
/**
* Takes a PerfSensorGroup and duplicates it for every CPU specified.
* Assigns one CPU value to every newly constructed group and stores them
* afterwards.
*
* @param group PerfSensorGroup which is to be customized for every CPU
* @param cfg Config tree for the group. Required to read in possibly
* differing CPU lists and default groups.
*/
void
customizeAndStore
(
PerfSensorGroup
&
group
,
CFG_VAL
cfg
);
templateCpuMap_t
_templateCpus
;
enumMap_t
_enumType
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment