developer
dongloong 3 months ago
parent 6705d8e243
commit 3b45ac2f0a

@ -1,35 +1,29 @@
/*
Copyright 2015 Google LLC All rights reserved.
/*
2015 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
Apache License, 2.0
使
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
american fuzzy lop - free CPU gizmo
/*
- CPU
-----------------------------------
Written and maintained by Michal Zalewski <lcamtuf@google.com>
Michal Zalewski <lcamtuf@google.com>
This tool provides a fairly accurate measurement of CPU preemption rate.
It is meant to complement the quick-and-dirty load average widget shown
in the afl-fuzz UI. See docs/parallel_fuzzing.txt for more info.
CPU
afl-fuzz UIdocs/parallel_fuzzing.txt
For some work loads, the tool may actually suggest running more instances
than you have CPU cores. This can happen if the tested program is spending
a portion of its run time waiting for I/O, rather than being 100%
CPU-bound.
CPUI/O100% CPU
The idea for the getrusage()-based approach comes from Jakub Wilk.
getrusage()Jakub Wilk
*/
#define AFL_MAIN
@ -55,119 +49,151 @@
#endif /* __linux__ */
/* Get unix time in microseconds. */
/*
Unix
*/
static u64 get_cur_time_us(void) {
// 定义一个timeval结构体变量tv用于存储当前时间
struct timeval tv;
// 定义一个timezone结构体变量tz用于存储时区信息
struct timezone tz;
// 使用gettimeofday函数获取当前时间并存储到tv和tz中
gettimeofday(&tv, &tz);
// 将秒转换为微秒,并加上微秒部分,返回当前时间的微秒值
return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
}
/* Get CPU usage in microseconds. */
/*
CPU使
*/
static u64 get_cpu_usage_us(void) {
// 定义一个rusage结构体变量u用于存储资源使用情况
struct rusage u;
// 使用getrusage函数获取当前进程的资源使用情况并存储到u中
getrusage(RUSAGE_SELF, &u);
// 计算用户态和核心态的总使用时间(微秒),并返回
return (u.ru_utime.tv_sec * 1000000ULL) + u.ru_utime.tv_usec +
(u.ru_stime.tv_sec * 1000000ULL) + u.ru_stime.tv_usec;
}
/* Measure preemption rate. */
/*
*/
static u32 measure_preemption(u32 target_ms) {
// 定义两个易失性变量,用于循环测试
static volatile u32 v1, v2;
// 定义变量用于存储开始和结束的时间微秒以及CPU使用时间
u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;
// 定义循环重复次数
s32 loop_repeats = 0;
// 获取当前时间(微秒)
st_t = get_cur_time_us();
// 获取当前CPU使用时间微秒
st_c = get_cpu_usage_us();
repeat_loop:
// 设置v1为一个忙循环的计数
v1 = CTEST_BUSY_CYCLES;
// 执行忙循环同时v2自增
while (v1--) v2++;
// 调用sched_yield()让出CPU
sched_yield();
// 再次获取当前时间(微秒)
en_t = get_cur_time_us();
// 如果当前时间与开始时间的差小于目标时间(毫秒转换为微秒),则增加循环次数并继续循环
if (en_t - st_t < target_ms * 1000) {
loop_repeats++;
goto repeat_loop;
}
/* Let's see what percentage of this time we actually had a chance to
run, and how much time was spent in the penalty box. */
/* 让我们看看这段时间里我们实际上有多少百分比的机会运行,
*/
// 获取当前CPU使用时间微秒
en_c = get_cpu_usage_us();
// 计算实际时间差毫秒和CPU使用时间差毫秒
real_delta = (en_t - st_t) / 1000;
slice_delta = (en_c - st_c) / 1000;
// 返回实际时间差占CPU使用时间差的百分比即抢占率
return real_delta * 100 / slice_delta;
}
/* Do the benchmark thing. */
/*
*/
int main(int argc, char** argv) {
#ifdef HAVE_AFFINITY
// 获取在线的CPU核心数
u32 cpu_cnt = sysconf(_SC_NPROCESSORS_ONLN),
// 初始化空闲CPU和可能可用CPU的计数器
idle_cpus = 0, maybe_cpus = 0, i;
// 打印欢迎信息和版本号
SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
// 打印测量每个核心抢占率所需的时间
ACTF("Measuring per-core preemption rate (this will take %0.02f sec)...",
((double)CTEST_CORE_TRG_MS) / 1000);
// 遍历每个CPU核心
for (i = 0; i < cpu_cnt; i++) {
// 创建子进程
s32 fr = fork();
// 如果fork失败则打印错误信息并退出
if (fr < 0) PFATAL("fork failed");
// 如果是子进程,则执行以下操作
if (!fr) {
// 定义CPU集合
cpu_set_t c;
// 定义CPU使用率百分比
u32 util_perc;
// 初始化CPU集合
CPU_ZERO(&c);
// 将当前核心加入CPU集合
CPU_SET(i, &c);
// 如果设置CPU亲和性失败则打印错误信息并退出
if (sched_setaffinity(0, sizeof(c), &c))
PFATAL("sched_setaffinity failed for cpu %d", i);
// 测量抢占率
util_perc = measure_preemption(CTEST_CORE_TRG_MS);
// 如果使用率低于110%,则标记为核心可用,并退出
if (util_perc < 110) {
SAYF(" Core #%u: " cLGN "AVAILABLE " cRST "(%u%%)\n", i, util_perc);
SAYF(" Core #%u: " cLGN "AVAILABLE" cRST "(%u%%)\n", i, util_perc);
exit(0);
} else if (util_perc < 250) {
SAYF(" Core #%u: " cYEL "CAUTION " cRST "(%u%%)\n", i, util_perc);
// 如果使用率低于250%,则标记为核心需要谨慎,并退出
SAYF(" Core #%u: " cYEL "CAUTION" cRST "(%u%%)\n", i, util_perc);
exit(1);
}
SAYF(" Core #%u: " cLRD "OVERBOOKED " cRST "(%u%%)\n" cRST, i,
// 如果使用率高于250%,则标记为核心过载,并退出
SAYF(" Core #%u: " cLRD "OVERBOOKED" cRST "(%u%%)\n" cRST, i,
util_perc);
exit(2);
@ -175,44 +201,35 @@ int main(int argc, char** argv) {
}
// 等待子进程结束,并统计空闲和可能可用的核心数
for (i = 0; i < cpu_cnt; i++) {
int ret;
if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed");
if (WEXITSTATUS(ret) == 0) idle_cpus++;
if (WEXITSTATUS(ret) <= 1) maybe_cpus++;
}
// 根据空闲和可能可用的核心数打印结果
SAYF(cGRA "\n>>> ");
if (idle_cpus) {
if (maybe_cpus == idle_cpus) {
SAYF(cLGN "PASS: " cRST "You can run more processes on %u core%s.",
idle_cpus, idle_cpus > 1 ? "s" : "");
} else {
SAYF(cLGN "PASS: " cRST "You can run more processes on %u to %u core%s.",
idle_cpus, maybe_cpus, maybe_cpus > 1 ? "s" : "");
}
SAYF(cGRA " <<<" cRST "\n\n");
return 0;
}
if (maybe_cpus) {
SAYF(cYEL "CAUTION: " cRST "You may still have %u core%s available.",
maybe_cpus, maybe_cpus > 1 ? "s" : "");
SAYF(cGRA " <<<" cRST "\n\n");
return 1;
}
SAYF(cLRD "FAIL: " cRST "All cores are overbooked.");
@ -221,38 +238,35 @@ int main(int argc, char** argv) {
#else
// 如果没有CPU亲和性支持则执行总体抢占率的测量
u32 util_perc;
SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
/* Run a busy loop for CTEST_TARGET_MS. */
/* 运行一个忙循环持续CTEST_TARGET_MS毫秒。 */
ACTF("Measuring gross preemption rate (this will take %0.02f sec)...",
((double)CTEST_TARGET_MS) / 1000);
// 测量抢占率
util_perc = measure_preemption(CTEST_TARGET_MS);
/* Deliver the final verdict. */
/* 输出最终结果。 */
SAYF(cGRA "\n>>> ");
if (util_perc < 105) {
SAYF(cLGN "PASS: " cRST "You can probably run additional processes.");
} else if (util_perc < 130) {
SAYF(cYEL "CAUTION: " cRST "Your CPU may be somewhat overbooked (%u%%).",
util_perc);
} else {
SAYF(cLRD "FAIL: " cRST "Your CPU is overbooked (%u%%).", util_perc);
}
SAYF(cGRA " <<<" cRST "\n\n");
// 返回结果代码
return (util_perc > 105) + (util_perc > 130);
#endif /* ^HAVE_AFFINITY */

Loading…
Cancel
Save