97 lines
3.3 KiB
C++
97 lines
3.3 KiB
C++
/*
|
|
* yosys -- Yosys Open SYnthesis Suite
|
|
*
|
|
* Copyright (C) 2014 Claire Xenia Wolf <claire@yosyshq.com>
|
|
* Copyright (C) 2014 Johann Glaser <Johann.Glaser@gmx.at>
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#include "kernel/yosys.h"
|
|
#include "kernel/log_help.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
|
|
USING_YOSYS_NAMESPACE
|
|
PRIVATE_NAMESPACE_BEGIN
|
|
|
|
#ifdef __linux__
|
|
struct LinuxPerf : public Pass {
|
|
LinuxPerf() : Pass("linux_perf", "turn linux perf recording off or on") { }
|
|
void help() override
|
|
{
|
|
log("This pass turns Linux 'perf' profiling on or off, when it has been configured to use control FIFOs.\n");
|
|
log("\n");
|
|
log("Example shell command line:\n");
|
|
log("mkfifo /tmp/perf.fifo /tmp/perf-ack.fifo\n");
|
|
log("YOSYS_PERF_CTL=/tmp/perf.fifo YOSYS_PERF_ACK=/tmp/perf-ack.fifo \\\n");
|
|
log(" perf record --latency --delay=-1 \\\n");
|
|
log(" --control=fifo:/tmp/perf.fifo,/tmp/perf-ack.fifo --call-graph=dwarf ./yosys -dt -p \\\n");
|
|
log(" \"read_rtlil design.rtlil; linux_perf on; opt_clean; linux_perf off\"\n");
|
|
log("\n");
|
|
log(" linux_perf on\n");
|
|
log("\n");
|
|
log("Start perf recording. YOSYS_PERF_CTL and YOSYS_PERF_ACK must point to Linux perf control FIFOs.\n");
|
|
log("\n");
|
|
log(" linux_perf off\n");
|
|
log("\n");
|
|
log("Stop perf recording.\n");
|
|
log("\n");
|
|
}
|
|
void execute(std::vector<std::string> args, RTLIL::Design *) override
|
|
{
|
|
if (args.size() > 2)
|
|
cmd_error(args, 2, "Unexpected argument.");
|
|
|
|
std::string_view ctl_msg;
|
|
if (args.size() == 2) {
|
|
if (args[1] == "on")
|
|
ctl_msg = "enable\n";
|
|
else if (args[1] == "off")
|
|
ctl_msg = "disable\n";
|
|
else
|
|
cmd_error(args, 1, "Unexpected argument.");
|
|
}
|
|
|
|
const char *ctl_fifo = std::getenv("YOSYS_PERF_CTL");
|
|
if (!ctl_fifo)
|
|
log_error("YOSYS_PERF_CTL environment variable not set.");
|
|
const char *ack_fifo = std::getenv("YOSYS_PERF_ACK");
|
|
if (!ack_fifo)
|
|
log_error("YOSYS_PERF_ACK environment variable not set.");
|
|
|
|
int ctl_fd = open(ctl_fifo, O_WRONLY);
|
|
if (ctl_fd < 0)
|
|
log_error("Failed to open YOSYS_PERF_CTL.");
|
|
int ack_fd = open(ack_fifo, O_RDONLY);
|
|
if (ack_fd < 0)
|
|
log_error("Failed to open YOSYS_PERF_ACK.");
|
|
int result = write(ctl_fd, ctl_msg.data(), ctl_msg.size());
|
|
if (result != static_cast<int>(ctl_msg.size()))
|
|
log_error("Failed to write to YOSYS_PERF_CTL.");
|
|
char buffer[64];
|
|
result = read(ack_fd, buffer, sizeof(buffer));
|
|
close(ctl_fd);
|
|
close(ack_fd);
|
|
if (result <= 0)
|
|
log_error("Failed to read from YOSYS_PERF_ACK.");
|
|
if (strcmp(buffer, "ack\n") != 0)
|
|
log_error("YOSYS_PERF_ACK did not return 'ack'.");
|
|
}
|
|
} LinuxPerf;
|
|
#endif
|
|
|
|
PRIVATE_NAMESPACE_END
|