-
Notifications
You must be signed in to change notification settings - Fork 942
Fix access point cleanup on instance removal #10179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9feed74
013482b
dbae4c1
5e41e5f
20a850f
92e85f5
90d2355
ea37d99
46ac421
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1215,6 +1215,13 @@ bool dbInst::swapMaster(dbMaster* new_master_) | |
| return false; | ||
| } | ||
|
|
||
| // Clear preferred APs before the ITerms are remapped to the new master. | ||
| for (const uint32_t iterm_id : inst->iterms_) { | ||
| dbITerm* iterm = (dbITerm*) block->iterm_tbl_->getPtr(iterm_id); | ||
| iterm->clearPrefAccessPoints(); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change 1. Add preferred AP clean-up before swapping master.
|
||
| inst->pin_access_idx_ = -1; | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should also invalidate the dbInst's |
||
| // remove reference to inst_hdr | ||
| _dbInstHdr* old_inst_hdr | ||
| = block->inst_hdr_hash_.find(((_dbMaster*) old_master_)->id_); | ||
|
|
@@ -1501,16 +1508,7 @@ void dbInst::destroy(dbInst* inst_) | |
| _dbITerm* _iterm = block->iterm_tbl_->getPtr(id); | ||
| dbITerm* iterm = (dbITerm*) _iterm; | ||
| iterm->disconnect(); | ||
| if (inst_->getPinAccessIdx() >= 0) { | ||
| for (const auto& [pin, aps] : iterm->getAccessPoints()) { | ||
| for (auto ap : aps) { | ||
| _dbAccessPoint* _ap = (_dbAccessPoint*) ap; | ||
| auto [first, last] = std::ranges::remove_if( | ||
| _ap->iterms_, [id](const auto& id_in) { return id_in == id; }); | ||
| _ap->iterms_.erase(first, last); | ||
| } | ||
| } | ||
| } | ||
| iterm->clearPrefAccessPoints(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although this is a more efficient approach, the outcome theoretically should be exactly the same. The preferred access point of an iterm is always a subset of its total access points which is returned by getAccessPoints
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. It is a code reduction by using the existing API. Change 2: Less code. More intuitive to me.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's ok. Just wanted to confirm that this is not intended as a fix. |
||
|
|
||
| // Notify when pins are deleted (assumption: pins are destroyed only when | ||
| // the related instance is destroyed) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| #include "dbMPin.h" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| #include <cstddef> | ||||||||||||||||||||||||||||||||
| #include <cstdint> | ||||||||||||||||||||||||||||||||
| #include <vector> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -16,6 +17,7 @@ | |||||||||||||||||||||||||||||||
| #include "dbMaster.h" | ||||||||||||||||||||||||||||||||
| #include "dbPolygonItr.h" | ||||||||||||||||||||||||||||||||
| #include "dbTable.h" | ||||||||||||||||||||||||||||||||
| #include "dbVector.h" | ||||||||||||||||||||||||||||||||
| #include "odb/db.h" | ||||||||||||||||||||||||||||||||
| #include "odb/dbSet.h" | ||||||||||||||||||||||||||||||||
| #include "odb/geom.h" | ||||||||||||||||||||||||||||||||
|
|
@@ -150,11 +152,13 @@ void dbMPin::clearPinAccess(const int pin_access_idx) | |||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| _dbMPin* pin = (_dbMPin*) this; | ||||||||||||||||||||||||||||||||
| _dbBlock* block = (_dbBlock*) getDb()->getChip()->getBlock(); | ||||||||||||||||||||||||||||||||
| if (pin->aps_.size() <= pin_access_idx) { | ||||||||||||||||||||||||||||||||
| if (pin_access_idx < 0 | ||||||||||||||||||||||||||||||||
| || pin->aps_.size() <= static_cast<std::size_t>(pin_access_idx)) { | ||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+155
to
158
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder what made you do this change? It is correct, but I wonder if there is any call that uses a negative pin_access_idx which would be more concerning.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nvm, just found it's ai review triggered. |
||||||||||||||||||||||||||||||||
| const auto aps = pin->aps_[pin_access_idx]; | ||||||||||||||||||||||||||||||||
| for (const auto& ap : aps) { | ||||||||||||||||||||||||||||||||
| dbVector<dbId<_dbAccessPoint>> aps; | ||||||||||||||||||||||||||||||||
| aps.swap(pin->aps_[pin_access_idx]); | ||||||||||||||||||||||||||||||||
| for (const dbId<_dbAccessPoint>& ap : aps) { | ||||||||||||||||||||||||||||||||
| odb::dbAccessPoint::destroy( | ||||||||||||||||||||||||||||||||
| (odb::dbAccessPoint*) block->ap_tbl_->getPtr(ap)); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+159
to
164
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Theoretically, there shouldn't be duplicate aps. This looks a bit defensive. I would prefer if such a case exists a crash rather than passing unnoticed.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. The deduplication is too defensive, which should be removed. Regarding your suggested code, I think it has a vector iterator invalidation risk. To make it safe, a copy should be used: Or Change 3: Use
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dbInst::swapMaster()now unconditionally clears each ITerm’s preferred access points before completing the swap, but this mutation is not captured as a journal field update.dbDatabase::undoEco()reverts swaps by callingswapMaster()again, so both the forward and undo paths clear AP metadata and the original preferred AP/back-reference state is never restored. In ECO trial flows that swap then undo (e.g., rejected sizing moves), this leaves the database observably different after undo and can break subsequent pin-access dependent logic.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maliberty
It looks like ODB journal does not support many physical data structures including
dbAccessPoint.To support the journal, many changes are required (supporting journal just for
swapMasteris incomplete. All the network edit operations should be considered).Is it ok to proceed w/o the ODB journal support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. We have only supported journaling on operations we actually undo but adding to the list anything else we need makes sense.