66#include < linux/perf_event.h> // for perf event constants
77#include < sys/ioctl.h> // for ioctl
88#include < unistd.h> // for syscall
9-
9+ # include < iostream >
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 fd;
17+ int group;
18+ bool working;
1819 perf_event_attr attribs;
1920 int num_events;
2021 std::vector<uint64_t > temp_result_vec;
21- std::vector<uint64_t > ids ;
22+ std::vector<int > fds ;
2223
2324public:
24- LinuxEvents (std::vector<int > config_vec) : fd( 0 ) {
25+ explicit LinuxEvents (std::vector<int > config_vec) : group(- 1 ), working( true ) {
2526 memset (&attribs, 0 , sizeof (attribs));
2627 attribs.type = TYPE;
2728 attribs.size = sizeof (attribs);
@@ -35,16 +36,16 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
3536 const int cpu = -1 ; // all CPUs
3637 const unsigned long flags = 0 ;
3738
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- fd = syscall (__NR_perf_event_open, &attribs, pid, cpu, group, flags);
43+ int fd = syscall (__NR_perf_event_open, &attribs, pid, cpu, group, flags);
4444 if (fd == -1 ) {
4545 report_error (" perf_event_open" );
4646 }
47- ioctl (fd, PERF_EVENT_IOC_ID, &ids[i++]);
47+
48+ fds.push_back (fd);
4849 if (group == -1 ) {
4950 group = fd;
5051 }
@@ -53,24 +54,28 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
5354 temp_result_vec.resize (num_events * 2 + 1 );
5455 }
5556
56- ~LinuxEvents () { close (fd); }
57+ ~LinuxEvents () {
58+ for (auto fd : fds) {
59+ close (fd);
60+ }
61+ }
5762
5863 inline void start () {
59- if (ioctl (fd , PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1 ) {
64+ if (ioctl (group , PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1 ) {
6065 report_error (" ioctl(PERF_EVENT_IOC_RESET)" );
6166 }
6267
63- if (ioctl (fd , PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
68+ if (ioctl (group , PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
6469 report_error (" ioctl(PERF_EVENT_IOC_ENABLE)" );
6570 }
6671 }
6772
6873 inline void end (std::vector<unsigned long long > &results) {
69- if (ioctl (fd , PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
74+ if (ioctl (group , PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1 ) {
7075 report_error (" ioctl(PERF_EVENT_IOC_DISABLE)" );
7176 }
7277
73- if (read (fd , &temp_result_vec[0 ], temp_result_vec.size () * 8 ) == -1 ) {
78+ if (read (group , &temp_result_vec[0 ], temp_result_vec.size () * 8 ) == -1 ) {
7479 report_error (" read" );
7580 }
7681 // our actual results are in slots 1,3,5, ... of this structure
@@ -82,7 +87,9 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
8287
8388private:
8489 void report_error (const std::string &context) {
85- throw std::runtime_error (context + " : " + std::string (strerror (errno)));
90+ if (working)
91+ std::cerr << (context + " : " + std::string (strerror (errno))) << std::endl;
92+ working = false ;
8693 }
8794};
88- #endif
95+ #endif
0 commit comments