#include "libhfuzz/performance.h" #include #include #include #include #include #include #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); } }