Make hardware-counter.cpp compile

`g++ -std=c++11 -lpthread src/hardware-counter.cpp
src/thread-local.cpp src/test.cpp` works and runs where `src/test.cpp` is:

```

int main() {
  bool enable = true;
  std::string events = "";
  bool recordSubprocesses = false;
  HPHP::HardwareCounter::Init(enable, events, recordSubprocesses);

  HPHP::HardwareCounter::s_counter.getCheck();

  int64_t start = HPHP::HardwareCounter::GetInstructionCount();
  volatile int x;
  for (int i = 0; i < 1000000; i++) {
    x += i;
  }
  int64_t end = HPHP::HardwareCounter::GetInstructionCount();

  printf("%d\n", end - start);
}
```
This commit is contained in:
Ben Alpert 2015-09-18 21:43:47 -07:00
parent 42e523ea4d
commit e922f869e6
5 changed files with 44 additions and 39 deletions

View File

@ -7,14 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "hphp/util/hardware-counter.h"
#include "hardware-counter.h"
#ifndef NO_HARDWARE_COUNTERS
#include <folly/ScopeGuard.h>
#include "hphp/util/logger.h"
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
@ -28,8 +24,6 @@
#include <asm/unistd.h>
#include <sys/prctl.h>
#include <linux/perf_event.h>
#include <folly/String.h>
#include <folly/Memory.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@ -80,14 +74,14 @@ public:
inited = true;
m_fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0);
if (m_fd < 0) {
Logger::Verbose("perf_event_open failed with: %s",
folly::errnoStr(errno).c_str());
// Logger::Verbose("perf_event_open failed with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
if (ioctl(m_fd, PERF_EVENT_IOC_ENABLE, 0) < 0) {
Logger::Warning("perf_event failed to enable: %s",
folly::errnoStr(errno).c_str());
// Logger::Warning("perf_event failed to enable: %s",
// folly::errnoStr(errno).c_str());
close();
m_err = -1;
return;
@ -136,15 +130,15 @@ public:
extra = 0;
if (m_fd > 0) {
if (ioctl (m_fd, PERF_EVENT_IOC_RESET, 0) < 0) {
Logger::Warning("perf_event failed to reset with: %s",
folly::errnoStr(errno).c_str());
// Logger::Warning("perf_event failed to reset with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
auto ret = ::read(m_fd, reset_values, sizeof(reset_values));
if (ret != sizeof(reset_values)) {
Logger::Warning("perf_event failed to reset with: %s",
folly::errnoStr(errno).c_str());
// Logger::Warning("perf_event failed to reset with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
@ -358,7 +352,7 @@ bool HardwareCounter::addPerfEvent(const char* event) {
found = true;
type = perfTable[i].type;
} else if (type != perfTable[i].type) {
Logger::Warning("failed to find perf event: %s", event);
// Logger::Warning("failed to find perf event: %s", event);
return false;
}
config |= perfTable[i].config;
@ -377,12 +371,13 @@ bool HardwareCounter::addPerfEvent(const char* event) {
}
if (!found || *ev) {
Logger::Warning("failed to find perf event: %s", event);
// Logger::Warning("failed to find perf event: %s", event);
return false;
}
auto hwc = folly::make_unique<HardwareCounterImpl>(type, config, event);
std::unique_ptr<HardwareCounterImpl> hwc(
new HardwareCounterImpl(type, config, event));
if (hwc->m_err) {
Logger::Warning("failed to set perf event: %s", event);
// Logger::Warning("failed to set perf event: %s", event);
return false;
}
m_counters.emplace_back(std::move(hwc));
@ -407,25 +402,27 @@ bool HardwareCounter::eventExists(const char *event) {
return false;
}
bool HardwareCounter::setPerfEvents(folly::StringPiece sevents) {
bool HardwareCounter::setPerfEvents(std::string sevents) {
// Make a copy of the string for use with strtok.
auto const sevents_buf = static_cast<char*>(malloc(sevents.size() + 1));
SCOPE_EXIT { free(sevents_buf); };
memcpy(sevents_buf, sevents.data(), sevents.size());
sevents_buf[sevents.size()] = '\0';
char* strtok_buf = nullptr;
char* s = strtok_r(sevents_buf, ",", &strtok_buf);
bool success = true;
while (s) {
if (!eventExists(s) && !addPerfEvent(s)) {
return false;
success = false;
break;
}
s = strtok_r(nullptr, ",", &strtok_buf);
}
return true;
free(sevents_buf);
return success;
}
bool HardwareCounter::SetPerfEvents(folly::StringPiece events) {
bool HardwareCounter::SetPerfEvents(std::string events) {
return s_counter->setPerfEvents(events);
}

View File

@ -10,11 +10,10 @@
#ifndef incl_HPHP_UTIL_HARDWARE_COUNTER_H_
#define incl_HPHP_UTIL_HARDWARE_COUNTER_H_
#include "hphp/util/thread-local.h"
#include <folly/Range.h>
#include "thread-local.h"
#include <cstdint>
#include <memory>
#include <vector>
namespace HPHP {
@ -43,7 +42,7 @@ public:
static int64_t GetInstructionCount();
static int64_t GetLoadCount();
static int64_t GetStoreCount();
static bool SetPerfEvents(folly::StringPiece events);
static bool SetPerfEvents(std::string events);
static void IncInstructionCount(int64_t amount);
static void IncLoadCount(int64_t amount);
static void IncStoreCount(int64_t amount);
@ -61,7 +60,7 @@ private:
int64_t getStoreCount();
bool eventExists(const char* event);
bool addPerfEvent(const char* event);
bool setPerfEvents(folly::StringPiece events);
bool setPerfEvents(std::string events);
void getPerfEvents(PerfEventCallback f, void* data);
void clearPerfEvents();

View File

@ -10,9 +10,14 @@
#ifndef incl_HPHP_PORTABILITY_H_
#define incl_HPHP_PORTABILITY_H_
#include <folly/Likely.h> // defining LIKELY/UNLIKELY is part of this header
#include <folly/Portability.h>
#include <folly/CPortability.h> // defining FOLLY_DISABLE_ADDRESS_SANITIZER
// From folly/Likely.h
#if defined(__GNUC__) && __GNUC__ >= 4
#define LIKELY(x) (__builtin_expect((x), 1))
#define UNLIKELY(x) (__builtin_expect((x), 0))
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
//////////////////////////////////////////////////////////////////////

View File

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "hphp/util/thread-local.h"
#include "thread-local.h"
#ifdef __linux__
#include <link.h>

View File

@ -10,11 +10,16 @@
#ifndef incl_HPHP_THREAD_LOCAL_H_
#define incl_HPHP_THREAD_LOCAL_H_
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include "hphp/util/exception.h"
#include <errno.h>
#include <folly/String.h>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include "portability.h"
namespace HPHP {
@ -85,8 +90,7 @@ inline void ThreadLocalCheckReturn(int ret, const char *funcName) {
if (ret != 0) {
// This is used from global constructors so the safest thing to do is just
// print to stderr and exit().
fprintf(stderr, "%s returned %d: %s", funcName, ret,
folly::errnoStr(ret).c_str());
fprintf(stderr, "%s returned %d", funcName, ret);
exit(1);
}
}
@ -357,7 +361,7 @@ template<typename T, bool throwOnNull = true>
struct ThreadLocalProxy {
T *get() const {
if (m_p == nullptr && throwOnNull) {
throw Exception("ThreadLocalProxy::get() called before set()");
throw std::runtime_error("ThreadLocalProxy::get() called before set()");
}
return m_p;
}
@ -708,7 +712,7 @@ public:
T *get() const {
T *obj = (T*)pthread_getspecific(m_key);
if (obj == nullptr && throwOnNull) {
throw Exception("ThreadLocalProxy::get() called before set()");
throw std::runtime_error("ThreadLocalProxy::get() called before set()");
}
return obj;
}