25 #include <gtest/gtest.h>
29 std::string
env(
const char* n) {
const char* v = getenv(n);
return v ? v :
""; }
30 std::string
cctlib_root() { std::string r =
env(
"CCTLIB_ROOT");
return r.empty() ?
"../.." : r; }
33 int run_pin(
const std::string& tool,
const std::vector<std::string>& args) {
34 std::string pin =
pin_root() +
"/pin";
35 std::vector<char*> argv;
36 argv.push_back(
const_cast<char*
>(pin.c_str()));
37 argv.push_back(
const_cast<char*
>(
"-t"));
38 argv.push_back(
const_cast<char*
>(tool.c_str()));
39 argv.push_back(
const_cast<char*
>(
"--"));
40 for (
auto&
a : args) argv.push_back(
const_cast<char*
>(
a.c_str()));
41 argv.push_back(
nullptr);
43 if (pid < 0)
return -1;
45 if (!
env(
"CCTLIB_TEST_VERBOSE").size()) {
46 int devnull = open(
"/dev/null", O_WRONLY);
47 if (devnull >= 0) { dup2(devnull, 1); dup2(devnull, 2); close(devnull); }
49 execv(pin.c_str(), argv.data());
53 if (waitpid(pid, &
status, 0) < 0)
return -1;
58 std::string
find_newest(
const std::string& dir,
const std::string& prefix) {
59 std::string cmd =
"ls -t " + dir +
"/" + prefix +
"* 2>/dev/null | head -1";
60 FILE* p = popen(cmd.c_str(),
"r");
62 char buf[4096]; std::string out;
63 if (fgets(
buf,
sizeof(
buf), p)) out =
buf;
65 if (!out.empty() && out.back() ==
'\n') out.pop_back();
69 std::ifstream in(path); std::stringstream ss; ss << in.rdbuf();
return ss.str();
71 void cleanup(
const std::string& dir,
const std::string& prefix) {
72 std::string cmd =
"rm -f " + dir +
"/" + prefix +
"*"; (void)system(cmd.c_str());
78 std::regex re(R
"(Footprint is (\d+))");
80 if (!std::regex_search(content, m, re))
return -1;
81 return std::stol(m[1]);
90 tool_ = root_ +
"/clients/obj-intel64/footprint_client.so";
91 ASSERT_EQ(0, access(tool_.c_str(), F_OK)) << tool_ <<
" missing";
92 ASSERT_EQ(0, chdir(root_.c_str())) <<
"chdir failed";
96 int rc =
run_pin(tool_, {victim});
97 EXPECT_EQ(0, rc) <<
"footprint on " << victim <<
" returned " << rc;
98 std::string out =
find_newest(root_,
"client.out.");
99 EXPECT_FALSE(out.empty()) <<
"no client.out.* file";
105 long fp = run_and_parse_footprint(
"/bin/ls");
115 long large = run_and_parse_footprint(root_ +
"/tests/gtest/obj/apps/footprint_large");
116 long small = run_and_parse_footprint(root_ +
"/tests/gtest/obj/apps/footprint_small");
122 EXPECT_GT(large - small, 50000)
123 <<
"large=" << large <<
" small=" << small;
132 long avx = run_and_parse_footprint(root_ +
"/tests/gtest/obj/apps/isa/footprint_avx32_sweep");
133 long small = run_and_parse_footprint(root_ +
"/tests/gtest/obj/apps/footprint_small");
138 EXPECT_GT(avx - small, 1000000)
139 <<
"avx=" << avx <<
" small=" << small;
static uint64_t buf[ITERS]