Skip to content
Open
4 changes: 2 additions & 2 deletions src/OpenRoad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,8 @@ void OpenRoad::readDb(const char* filename, bool hierarchy)
void OpenRoad::readDb(std::istream& stream)
{
if (db_->getChip() && db_->getChip()->getBlock()) {
logger_->error(
ORD, 47, "You can't load a new db file as the db is already populated");
db_->triggerPreDbClear();
db_->clear();
}

stream.exceptions(std::ifstream::failbit | std::ifstream::badbit
Expand Down
1 change: 1 addition & 0 deletions src/dbSta/include/db_sta/dbSta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class dbSta : public Sta, public odb::dbDatabaseObserver
void postReadDef(odb::dbBlock* block) override;
void postReadDb(odb::dbDatabase* db) override;
void postRead3Dbx(odb::dbChip* chip) override;
void preDbClear(odb::dbDatabase* db) override;

// Find clock nets connected by combinational gates from the clock roots.
std::set<odb::dbNet*> findClkNets();
Expand Down
2 changes: 2 additions & 0 deletions src/dbSta/src/dbNetwork.cc
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,8 @@ void dbNetwork::clear()
{
ConcreteNetwork::clear();
db_ = nullptr;
block_ = nullptr;
top_cell_ = nullptr;
}

Instance* dbNetwork::topInstance() const
Expand Down
21 changes: 21 additions & 0 deletions src/dbSta/src/dbSta.cc
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,27 @@ void dbSta::postReadDb(odb::dbDatabase* db)
}
}

void dbSta::preDbClear(odb::dbDatabase* db)
{
db_cbk_->removeOwner();
// Clear staCell pointers on all masters before freeing the network.
// The GUI render thread may still be accessing these concurrently.
for (odb::dbLib* lib : db->getLibs()) {
for (odb::dbMaster* master : lib->getMasters()) {
master->staSetCell(nullptr);
}
}
// Delete scenes before clearing the network, since scenes hold
// LibertyLibrary pointers that ConcreteNetwork::clear() will free.
// Recreate the default scene so cmd_scene_ remains valid.
deleteScenes();
makeDefaultScene();
clear();
db_network_->clear();
// Restore db_ since dbNetwork::clear() nulls it, but we need it for reload
db_network_->init(db_, logger_);
}

float dbSta::slack(const odb::dbNet* db_net, const MinMax* min_max)
{
const Net* net = db_network_->dbToSta(db_net);
Expand Down
1 change: 1 addition & 0 deletions src/grt/include/grt/GlobalRouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ class GlobalRouter
odb::dbDatabase* db() const { return db_; }
FastRouteCore* fastroute() const { return fastroute_; }
Rudy* getRudy();
void clearRudy();

void writePinLocations(const char* file_name);

Expand Down
6 changes: 6 additions & 0 deletions src/grt/src/GlobalRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,12 @@ Rudy* GlobalRouter::getRudy()
return rudy_;
}

void GlobalRouter::clearRudy()
{
delete rudy_;
rudy_ = nullptr;
}

bool GlobalRouter::findPinAccessPointPositions(
const Pin& pin,
std::map<int, std::vector<PointPair>>& ap_positions,
Expand Down
6 changes: 6 additions & 0 deletions src/grt/src/heatMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class RoutingCongestionDataSource : public gui::GlobalRoutingDataSource
public:
RoutingCongestionDataSource(utl::Logger* logger, odb::dbDatabase* db);

void setChip(odb::dbChip* chip) override
{
layer_ = nullptr;
HeatMapDataSource::setChip(chip);
}

protected:
bool populateMap() override;
void combineMapData(bool base_has_value,
Expand Down
11 changes: 11 additions & 0 deletions src/grt/src/heatMapRudy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,17 @@ bool RUDYDataSource::populateMap()
return true;
}

void RUDYDataSource::setChip(odb::dbChip* chip)
{
grouter_->clearRudy();
rudy_ = nullptr;
removeOwner();
HeatMapDataSource::setChip(chip);
if (chip && chip->getBlock()) {
addOwner(chip->getBlock());
}
}

void RUDYDataSource::onShow()
{
HeatMapDataSource::onShow();
Expand Down
1 change: 1 addition & 0 deletions src/grt/src/heatMapRudy.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class RUDYDataSource : public gui::GlobalRoutingDataSource,
grt::GlobalRouter* grouter,
odb::dbDatabase* db);

void setChip(odb::dbChip* chip) override;
void onShow() override;
void onHide() override;

Expand Down
10 changes: 8 additions & 2 deletions src/gui/include/gui/heatMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class HeatMapDataSource
std::string name;
std::string label;
std::function<std::vector<std::string>()> choices;
std::function<const std::string()> getter;
std::function<std::string()> getter;
std::function<void(const std::string&)> setter;
};

Expand Down Expand Up @@ -92,7 +92,13 @@ class HeatMapDataSource

void registerHeatMap();

virtual void setChip(odb::dbChip* chip) { chip_ = chip; }
virtual void setChip(odb::dbChip* chip)
{
if (chip_ != chip) {
destroyMap();
}
chip_ = chip;
}
void setUseDBU(bool use_dbu) { use_dbu_ = use_dbu; }
bool getUseDBU() const { return use_dbu_; }

Expand Down
30 changes: 30 additions & 0 deletions src/gui/src/displayControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,36 @@ void DisplayControls::techInit(odb::dbTech* tech)
techs_.insert(tech);
}

void DisplayControls::clearTechData()
{
// Remove layer leaf rows but preserve sub-group items (implant, other)
// by clearing children of each sub-group first, then removing only
// direct layer rows from the layers group.
layers_.implant.name->removeRows(0, layers_.implant.name->rowCount());
layers_.other.name->removeRows(0, layers_.other.name->rowCount());

// Remove direct children (routing/cut layers) from layers_group_, but
// keep the implant and other sub-group rows. Walk in reverse to avoid
// index shifting.
for (int i = layers_group_.name->rowCount() - 1; i >= 0; --i) {
QStandardItem* child = layers_group_.name->child(i);
if (child != layers_.implant.name && child != layers_.other.name) {
layers_group_.name->removeRow(i);
}
}

site_group_.name->removeRows(0, site_group_.name->rowCount());

// Clear ODB-keyed maps
layer_controls_.clear();
site_controls_.clear();
layer_color_.clear();
layer_pattern_.clear();
site_color_.clear();
techs_.clear();
layers_menu_layer_ = nullptr;
}

void DisplayControls::blockLoaded(odb::dbBlock* block)
{
addTech(block->getTech());
Expand Down
3 changes: 3 additions & 0 deletions src/gui/src/displayControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ class DisplayControls : public QDockWidget,
// options displayed need to match
void blockLoaded(odb::dbBlock* block);

// Clears all ODB-derived display state (layers, sites) for DB reload
void clearTechData();

void setCurrentChip(odb::dbChip* chip);

// This is called by the check boxes to update the state
Expand Down
1 change: 0 additions & 1 deletion src/gui/src/heatMapCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ Renderer::Settings HeatMapDataSource::getSettings() const
settings[set.name] = set.getter();
}
}

return settings;
}

Expand Down
22 changes: 22 additions & 0 deletions src/gui/src/layoutTabs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,30 @@ void LayoutTabs::chipLoaded(odb::dbChip* chip)
emit newViewer(viewer);
}

void LayoutTabs::clearViewers()
{
// Stop render threads before destroying viewers to avoid
// deleting a running QThread.
for (LayoutViewer* viewer : viewers_) {
viewer->exit();
}
// QTabWidget::clear() removes all tabs and deletes the page widgets
// (LayoutScroll), which are parents of the LayoutViewer widgets.
QTabWidget::clear();
viewers_.clear();
current_viewer_ = nullptr;
modules_.clear();
focus_nets_.clear();
route_guides_.clear();
net_tracks_.clear();
}

void LayoutTabs::tabChange(int index)
{
if (index < 0 || index >= static_cast<int>(viewers_.size())) {
current_viewer_ = nullptr;
return;
}
current_viewer_ = viewers_[index];

emit setCurrentChip(current_viewer_->getChip());
Expand Down
1 change: 1 addition & 0 deletions src/gui/src/layoutTabs.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class LayoutTabs : public QTabWidget
void tabChange(int index);
void updateBackgroundColors();
void updateBackgroundColor(LayoutViewer* viewer);
void clearViewers();

// These are just forwarding to the current LayoutViewer
void zoomIn();
Expand Down
15 changes: 15 additions & 0 deletions src/gui/src/mainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,10 @@ void MainWindow::selectHighlightConnectedBufferTrees(bool select_flag,

void MainWindow::saveSettings()
{
// Stop render threads before saving settings to avoid races
// between the render thread and the main thread.
viewers_->exit();

QSettings settings("OpenRoad Project", "openroad");
settings.beginGroup("main");
settings.setValue("geometry", saveGeometry());
Expand Down Expand Up @@ -1662,6 +1666,17 @@ void MainWindow::postRead3Dbx(odb::dbChip* chip)
emit chipLoaded(chip);
}

void MainWindow::preDbClear(odb::dbDatabase* db)
{
selected_.clear();
for (auto& highlighted_set : highlighted_) {
highlighted_set.clear();
}
viewers_->clearViewers();
controls_->clearTechData();
setBlock(nullptr);
}

void MainWindow::postReadDb(odb::dbDatabase* db)
{
auto chip = db->getChip();
Expand Down
1 change: 1 addition & 0 deletions src/gui/src/mainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class MainWindow : public QMainWindow, public odb::dbDatabaseObserver
void postReadDef(odb::dbBlock* block) override;
void postReadDb(odb::dbDatabase* db) override;
void postRead3Dbx(odb::dbChip* chip) override;
void preDbClear(odb::dbDatabase* db) override;

// Capture logger messages into the script widget output
void setLogger(utl::Logger* logger);
Expand Down
1 change: 1 addition & 0 deletions src/odb/include/odb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -7716,6 +7716,7 @@ class dbDatabase : public dbObject
void triggerPostReadDef(dbBlock* block, bool floorplan);
void triggerPostReadDb();
void triggerPostRead3Dbx(dbChip* chip);
void triggerPreDbClear();

///
/// Create an instance of a database
Expand Down
3 changes: 3 additions & 0 deletions src/odb/include/odb/dbDatabaseObserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class dbDatabaseObserver
virtual void postReadDb(odb::dbDatabase* db) = 0;
virtual void postRead3Dbx(odb::dbChip* chip) = 0;

// Called before the database is cleared for a reload
virtual void preDbClear(odb::dbDatabase* /*db*/) {}

void setUnregisterObserver(std::function<void()> unregister_observer)
{
unregister_observer_ = std::move(unregister_observer);
Expand Down
33 changes: 33 additions & 0 deletions src/odb/src/db/dbDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <ostream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

#include "absl/synchronization/mutex.h"
Expand Down Expand Up @@ -478,6 +479,24 @@ _dbDatabase::_dbDatabase(_dbDatabase* /* unused: db */, int id)

chip_tbl_ = new dbTable<_dbChip, 2>(
this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipObj);
chip_hash_.setTable(chip_tbl_);

chip_inst_tbl_ = new dbTable<_dbChipInst>(
this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipInstObj);
chip_region_inst_tbl_ = new dbTable<_dbChipRegionInst>(
this,
this,
(GetObjTbl_t) &_dbDatabase::getObjectTable,
dbChipRegionInstObj);
chip_conn_tbl_ = new dbTable<_dbChipConn>(
this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipConnObj);
chip_bump_inst_tbl_
= new dbTable<_dbChipBumpInst>(this,
this,
(GetObjTbl_t) &_dbDatabase::getObjectTable,
dbChipBumpInstObj);
chip_net_tbl_ = new dbTable<_dbChipNet>(
this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipNetObj);

gds_lib_tbl_ = new dbTable<_dbGDSLib, 2>(
this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbGdsLibObj);
Expand Down Expand Up @@ -925,8 +944,14 @@ void dbDatabase::clear()
{
_dbDatabase* db = (_dbDatabase*) this;
int id = db->unique_id_;
// Save session-level state that was set up during init and is not
// part of the database content being cleared.
auto observers = std::move(db->observers_);
utl::Logger* logger = db->logger_;
db->~_dbDatabase();
new (db) _dbDatabase(db, id);
db->observers_ = std::move(observers);
db->logger_ = logger;
}

void dbDatabase::destroy(dbDatabase* db_)
Expand Down Expand Up @@ -1029,6 +1054,14 @@ void dbDatabase::triggerPostReadDb()
}
}

void dbDatabase::triggerPreDbClear()
{
_dbDatabase* db = (_dbDatabase*) this;
for (dbDatabaseObserver* observer : db->observers_) {
observer->preDbClear(this);
}
}

// User Code End dbDatabasePublicMethods
} // namespace odb
// Generator Code End Cpp
3 changes: 3 additions & 0 deletions src/psm/src/heatMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ IRDropDataSource::IRDropDataSource(PDNSim* psm,

void IRDropDataSource::setChip(odb::dbChip* chip)
{
layer_ = nullptr;
net_ = nullptr;
corner_ = nullptr;
gui::HeatMapDataSource::setChip(chip);
if (chip != nullptr) {
odb::dbBlock* block = chip->getBlock();
Expand Down
7 changes: 5 additions & 2 deletions src/web/src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,13 @@ void Search::setTopChip(odb::dbChip* chip)
return;
}
odb::dbBlock* block = chip->getBlock();
if (top_chip_ != chip) {
// Re-initialize when the chip changed or when the previous block was
// destroyed (e.g. after a database reload via read_db). The block
// destructor calls removeOwner() which clears hasOwner().
if (top_chip_ != chip || !hasOwner()) {
clear();

if (top_chip_ != nullptr) {
if (hasOwner()) {
removeOwner();
}

Expand Down
Loading