Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ cc_binary(
"//src/sta:opensta_lib",
"//src/utl",
"//src/web",
"@abseil-cpp//absl/base:no_destructor",
"@boost.stacktrace",
"@rules_cc//cc/runfiles", # sets BAZEL_CURRENT_REPOSITORY
"@tcl_lang//:tcl",
Expand Down
35 changes: 19 additions & 16 deletions src/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#include <string>
#include <system_error>

#include "absl/base/no_destructor.h"
#include "boost/stacktrace/stacktrace.hpp"
#include "tcl.h"
#include "tclDecls.h"
#ifdef ENABLE_PYTHON3
#define PY_SSIZE_T_CLEAN
#include "Python.h"
Expand Down Expand Up @@ -182,16 +184,16 @@ static volatile sig_atomic_t fatal_error_in_progress = 0;
// When we enter through main() we have a single tech and design.
// Custom applications using OR as a library might define multiple.
// Such applications won't allocate or use these objects.
//
// Use a wrapper struct to ensure destruction ordering - design
// then tech (members are destroyed in reverse order).
// Use a wrapper struct to hold the objects. They are wrapped in
// absl::NoDestructor below to intentionally leak them and avoid
// static destruction order issues.
struct TechAndDesign
{
std::unique_ptr<ord::Tech> tech;
std::unique_ptr<ord::Design> design;
};

static TechAndDesign the_tech_and_design;
static absl::NoDestructor<TechAndDesign> the_tech_and_design;
Comment thread
calewis marked this conversation as resolved.

static void handler(int sig)
{
Expand Down Expand Up @@ -265,10 +267,10 @@ int main(int argc, char* argv[])
// Setup the app with tcl
auto* interp = Tcl_CreateInterp();
Tcl_Init(interp);
the_tech_and_design.tech = std::make_unique<ord::Tech>(interp);
the_tech_and_design.design
= std::make_unique<ord::Design>(the_tech_and_design.tech.get());
ord::OpenRoad::setOpenRoad(the_tech_and_design.design->getOpenRoad());
the_tech_and_design->tech = std::make_unique<ord::Tech>(interp);
the_tech_and_design->design
= std::make_unique<ord::Design>(the_tech_and_design->tech.get());
ord::OpenRoad::setOpenRoad(the_tech_and_design->design->getOpenRoad());
const bool exit = findCmdLineFlag(cmd_argc, cmd_argv, "-exit");
ord::initOpenRoad(interp, log_filename, metrics_filename, exit);
if (!findCmdLineFlag(cmd_argc, cmd_argv, "-no_splash")) {
Expand Down Expand Up @@ -452,7 +454,7 @@ static int tclAppInit(int& argc,

if (argc > 2 || (argc > 1 && argv[1][0] == '-')) {
showUsage(argv[0], init_filename);
exit(1);
Tcl_Exit(1);
} else {
if (argc == 2) {
char* cmd_file = argv[1];
Expand All @@ -461,7 +463,7 @@ static int tclAppInit(int& argc,
int result = sourceTclFile(cmd_file, false, false, interp);
if (exit_after_cmd_file) {
int exit_code = (result == TCL_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
exit(exit_code);
Tcl_Exit(exit_code);
}
} else {
// need to delay loading of file until after GUI is completed
Expand All @@ -485,7 +487,7 @@ static int tclAppInit(int& argc,
// real process exit now from the main thread (worker threads are
// already joined by stop()).
if (server->exitRequested()) {
exit(EXIT_SUCCESS);
Tcl_Exit(EXIT_SUCCESS);
}
}
}
Expand All @@ -502,16 +504,17 @@ static int tclAppInit(int& argc,

int ord::tclAppInit(Tcl_Interp* interp)
{
the_tech_and_design.tech = std::make_unique<ord::Tech>(interp);
the_tech_and_design.design
= std::make_unique<ord::Design>(the_tech_and_design.tech.get());
ord::OpenRoad::setOpenRoad(the_tech_and_design.design->getOpenRoad());
the_tech_and_design->tech = std::make_unique<ord::Tech>(interp);
the_tech_and_design->design
= std::make_unique<ord::Design>(the_tech_and_design->tech.get());
ord::OpenRoad::setOpenRoad(the_tech_and_design->design->getOpenRoad());

// This is to enable Design.i where a design arg can be
// retrieved from the interpreter. This is necessary for
// cases with more than one interpreter (ie more than one Design).
// This should replace the use of the singleton OpenRoad::openRoad().
Tcl_SetAssocData(interp, "design", nullptr, the_tech_and_design.design.get());
Tcl_SetAssocData(
Comment thread
calewis marked this conversation as resolved.
interp, "design", nullptr, the_tech_and_design->design.get());

return ord::tclInit(interp);
}
Expand Down
10 changes: 10 additions & 0 deletions src/OpenRoad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "ord/Version.hh"
#include "tcl.h"
#include "tclDecls.h"
#ifdef ENABLE_PYTHON3
#define PY_SSIZE_T_CLEAN
#include "Python.h"
Expand Down Expand Up @@ -178,6 +179,12 @@ void OpenRoad::setOpenRoad(OpenRoad* app, bool reinit_ok)

////////////////////////////////////////////////////////////////

static void finalizeLoggerMetrics(ClientData clientData)
{
auto* logger = static_cast<utl::Logger*>(clientData);
logger->finalizeMetrics();
}

void initOpenRoad(Tcl_Interp* interp,
const char* log_filename,
const char* metrics_filename,
Expand All @@ -197,6 +204,9 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
// Make components.
utl::Progress::setBatchMode(batch_mode);
logger_ = new utl::Logger(log_filename, metrics_filename);
if (metrics_filename) {
Tcl_CreateExitHandler(finalizeLoggerMetrics, logger_);
Comment thread
calewis marked this conversation as resolved.
}
service_registry_ = new utl::ServiceRegistry(logger_);
db_->setLogger(logger_);
sta_ = new sta::dbSta(tcl_interp, db_, logger_);
Expand Down
4 changes: 3 additions & 1 deletion src/utl/include/utl/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ class Logger
Progress* progress() const { return progress_.get(); }
std::unique_ptr<Progress> swapProgress(Progress* progress);

void finalizeMetrics();

private:
std::vector<std::string> metrics_sinks_;
std::list<MetricsEntry> metrics_entries_;
Expand Down Expand Up @@ -322,7 +324,6 @@ class Logger
}

void flushMetrics();
void finalizeMetrics();
// Add new metrics for non-zero warnings. It also counts the number of
// unique warning types.
void addWarningMetrics();
Expand Down Expand Up @@ -371,6 +372,7 @@ class Logger
std::array<MessageLevel, ToolId::SIZE> message_levels_;
std::array<DebugGroups, ToolId::SIZE> debug_group_level_;
bool debug_on_{false};
bool metrics_finalized_{false};
std::atomic_int warning_count_{0};
std::atomic_int error_count_{0};
static constexpr const char* level_names[]
Expand Down
5 changes: 5 additions & 0 deletions src/utl/src/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ void Logger::addWarningMetrics()

void Logger::finalizeMetrics()
{
if (metrics_finalized_) {
return;
}
metrics_finalized_ = true;

log_metric("flow__warnings__count", std::to_string(warning_count_));
log_metric("flow__errors__count", std::to_string(error_count_));

Expand Down
Loading