blob: e983a51767ff3a1c94b91028b2c4b4ca6a089116 [file] [log] [blame]
#include "libhfuzz/performance.h"
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include "honggfuzz.h"
#include "libhfcommon/log.h"
#include "libhfcommon/util.h"
#include "libhfuzz/instrument.h"
#define HF_USEC_PER_SEC 1000000
#define HF_CHECK_INTERVAL_USECS (HF_USEC_PER_SEC * 20) /* Peform this check every 20 sec. */
#define HF_RESET_RATIO 5 /* Reset ourselves, if currently n times slower than in the beginning */
static uint64_t iterCnt = 0;
static time_t firstInputUSecs = 0;
static uint64_t initialUSecsPerExec = 0;
static uint64_t lastCheckUSecs = 0;
static uint64_t lastCheckIters = 0;
static bool performanceInit(void) {
if (iterCnt == 1) {
firstInputUSecs = util_timeNowUSecs();
}
uint64_t timeDiffUSecs = util_timeNowUSecs() - firstInputUSecs;
if (iterCnt == 5000 || timeDiffUSecs > HF_CHECK_INTERVAL_USECS) {
initialUSecsPerExec = timeDiffUSecs / iterCnt;
lastCheckUSecs = util_timeNowUSecs();
lastCheckIters = iterCnt;
LOG_I("Thread %u (pid=%d) initial speed set at %" PRIu64 " us/exec", instrumentThreadNo(),
(int)getpid(), initialUSecsPerExec);
return true;
}
return false;
}
bool performanceTooSlow(void) {
uint64_t timeDiffUSecs = util_timeNowUSecs() - lastCheckUSecs;
if (timeDiffUSecs > HF_CHECK_INTERVAL_USECS) {
uint64_t currentUSecsPerExec = timeDiffUSecs / (iterCnt - lastCheckIters);
if (currentUSecsPerExec > (initialUSecsPerExec * HF_RESET_RATIO)) {
LOG_W("Thread %u (pid=%d) became too slow to process fuzzing data, initial: %" PRIu64
" us/exec, current: %" PRIu64 " us/exec. Restaring myself!",
instrumentThreadNo(), (int)getpid(), initialUSecsPerExec, currentUSecsPerExec);
return true;
}
lastCheckIters = iterCnt;
lastCheckUSecs = util_timeNowUSecs();
}
return false;
}
void performanceCheck(void) {
iterCnt += 1;
static bool initialized = false;
if (!initialized) {
initialized = performanceInit();
return;
}
if (performanceTooSlow()) {
exit(0);
}
}