66#include < linux/perf_event.h> // for perf event constants
77#include < sys/ioctl.h> // for ioctl
88#include < unistd.h> // for syscall
9- # include < iostream >
9+
1010#include < cerrno> // for errno
1111#include < cstring> // for memset
1212#include < stdexcept>
1313
1414#include < vector>
1515
1616template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
17- int group;
18- bool working;
17+ int fd;
1918 perf_event_attr attribs;
2019 int num_events;
2120 std::vector<uint64_t > temp_result_vec;
22- std::vector<int > fds ;
21+ std::vector<uint64_t > ids ;
2322
2423public:
25- explicit LinuxEvents (std::vector<int > config_vec) : group(- 1 ), working( true ) {
24+ LinuxEvents (std::vector<int > config_vec) : fd( 0 ) {
2625 memset (&attribs, 0 , sizeof (attribs));
2726 attribs.type = TYPE;
2827 attribs.size = sizeof (attribs);
@@ -36,16 +35,16 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
3635 const int cpu = -1 ; // all CPUs
3736 const unsigned long flags = 0 ;
3837
38+ int group = -1 ; // no group
3939 num_events = config_vec.size ();
4040 uint32_t i = 0 ;
4141 for (auto config : config_vec) {
4242 attribs.config = config;
43- int fd = syscall (__NR_perf_event_open, &attribs, pid, cpu, group, flags);
43+ fd = syscall (__NR_perf_event_open, &attribs, pid, cpu, group, flags);
4444 if (fd == -1 ) {
4545 report_error (" perf_event_open" );
4646 }
47-
48- fds.push_back (fd);
47+ ioctl (fd, PERF_EVENT_IOC_ID, &ids[i++]);
4948 if (group == -1 ) {
5049 group = fd;
5150 }
@@ -54,28 +53,24 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
5453 temp_result_vec.resize (num_events * 2 + 1 );
5554 }
5655
57- ~LinuxEvents () {
58- for (auto fd : fds) {
59- close (fd);
60- }
61- }
56+ ~LinuxEvents () { close (fd); }
6257
6358 inline void start () {
64- if (ioctl (group , PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1 ) {
59+ if (ioctl (fd , PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1 ) {
6560 report_error (" ioctl(PERF_EVENT_IOC_RESET)" );
6661 }
6762
68- if (ioctl (group , PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
63+ if (ioctl (fd , PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
6964 report_error (" ioctl(PERF_EVENT_IOC_ENABLE)" );
7065 }
7166 }
7267
7368 inline void end (std::vector<unsigned long long > &results) {
74- if (ioctl (group , PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
69+ if (ioctl (fd , PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
7570 report_error (" ioctl(PERF_EVENT_IOC_DISABLE)" );
7671 }
7772
78- if (read (group , &temp_result_vec[0 ], temp_result_vec.size () * 8 ) == -1 ) {
73+ if (read (fd , &temp_result_vec[0 ], temp_result_vec.size () * 8 ) == -1 ) {
7974 report_error (" read" );
8075 }
8176 // our actual results are in slots 1,3,5, ... of this structure
@@ -87,9 +82,7 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
8782
8883private:
8984 void report_error (const std::string &context) {
90- if (working)
91- std::cerr << (context + " : " + std::string (strerror (errno))) << std::endl;
92- working = false ;
85+ throw std::runtime_error (context + " : " + std::string (strerror (errno)));
9386 }
9487};
95- #endif
88+ #endif
0 commit comments