mirror of https://github.com/KLayout/klayout.git
Also provide layout locking for recursive instance iterator
This commit is contained in:
parent
57e98d17ac
commit
1407ae13a7
|
|
@ -61,6 +61,7 @@ RecursiveInstanceIterator &RecursiveInstanceIterator::operator= (const Recursive
|
|||
|
||||
m_box_convert = d.m_box_convert;
|
||||
|
||||
m_locker = d.m_locker;
|
||||
m_inst = d.m_inst;
|
||||
m_inst_array = d.m_inst_array;
|
||||
m_empty_cells_cache = d.m_empty_cells_cache;
|
||||
|
|
@ -175,7 +176,7 @@ RecursiveInstanceIterator::set_region (const box_type ®ion)
|
|||
{
|
||||
if (m_region != region || mp_complex_region.get () != 0) {
|
||||
init_region (region);
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +184,7 @@ void
|
|||
RecursiveInstanceIterator::set_region (const region_type ®ion)
|
||||
{
|
||||
init_region (region);
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -196,7 +197,7 @@ RecursiveInstanceIterator::confine_region (const box_type ®ion)
|
|||
} else {
|
||||
init_region (m_region & region);
|
||||
}
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -209,7 +210,7 @@ RecursiveInstanceIterator::confine_region (const region_type ®ion)
|
|||
} else {
|
||||
init_region (region & region_type (m_region));
|
||||
}
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -218,7 +219,7 @@ RecursiveInstanceIterator::enable_all_targets ()
|
|||
if (! m_all_targets) {
|
||||
m_all_targets = true;
|
||||
m_targets.clear ();
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +229,7 @@ RecursiveInstanceIterator::set_targets (const std::set<db::cell_index_type> &tgt
|
|||
if (m_all_targets || m_targets != tgt) {
|
||||
m_targets = tgt;
|
||||
m_all_targets = false;
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,6 +265,8 @@ RecursiveInstanceIterator::validate (RecursiveInstanceReceiver *receiver) const
|
|||
m_needs_reinit = false;
|
||||
|
||||
// re-initialize
|
||||
m_locker = db::LayoutLocker ();
|
||||
|
||||
mp_cell = mp_top_cell;
|
||||
m_trans_stack.clear ();
|
||||
m_inst_iterators.clear ();
|
||||
|
|
@ -310,6 +313,17 @@ RecursiveInstanceIterator::validate (RecursiveInstanceReceiver *receiver) const
|
|||
next_instance (receiver);
|
||||
|
||||
}
|
||||
|
||||
if (mp_layout && ! at_end ()) {
|
||||
m_locker = db::LayoutLocker (const_cast <db::Layout *> (mp_layout.get ()), true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveInstanceIterator::reset ()
|
||||
{
|
||||
m_needs_reinit = true;
|
||||
m_locker = db::LayoutLocker ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -320,7 +334,7 @@ RecursiveInstanceIterator::reset_selection ()
|
|||
m_start.clear ();
|
||||
m_stop.clear ();
|
||||
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -335,7 +349,7 @@ RecursiveInstanceIterator::unselect_cells (const std::set<db::cell_index_type> &
|
|||
m_start.erase (*c);
|
||||
}
|
||||
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -350,7 +364,7 @@ RecursiveInstanceIterator::unselect_all_cells ()
|
|||
m_stop.insert (c->cell_index ());
|
||||
}
|
||||
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -365,7 +379,7 @@ RecursiveInstanceIterator::select_cells (const std::set<db::cell_index_type> &ce
|
|||
m_stop.erase (*c);
|
||||
}
|
||||
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -380,7 +394,7 @@ RecursiveInstanceIterator::select_all_cells ()
|
|||
m_start.insert (c->cell_index ());
|
||||
}
|
||||
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -441,6 +455,7 @@ void
|
|||
RecursiveInstanceIterator::next (RecursiveInstanceReceiver *receiver)
|
||||
{
|
||||
if (! at_end ()) {
|
||||
|
||||
++m_inst_array;
|
||||
if (! m_inst_array.at_end ()) {
|
||||
new_inst_member (receiver);
|
||||
|
|
@ -449,6 +464,12 @@ RecursiveInstanceIterator::next (RecursiveInstanceReceiver *receiver)
|
|||
new_inst (receiver);
|
||||
}
|
||||
next_instance (receiver);
|
||||
|
||||
if (at_end ()) {
|
||||
// Take this opportunity the release the layout lock.
|
||||
// This way, the shape iterator can be held further, without blocking the layout.
|
||||
m_locker = db::LayoutLocker ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ public:
|
|||
{
|
||||
if (m_max_depth != depth) {
|
||||
m_max_depth = depth;
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ public:
|
|||
{
|
||||
if (m_min_depth != depth) {
|
||||
m_min_depth = depth;
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,17 +262,14 @@ public:
|
|||
{
|
||||
if (m_overlapping != f) {
|
||||
m_overlapping = f;
|
||||
m_needs_reinit = true;
|
||||
reset ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the iterator
|
||||
*/
|
||||
void reset ()
|
||||
{
|
||||
m_needs_reinit = true;
|
||||
}
|
||||
void reset ();
|
||||
|
||||
/**
|
||||
* @brief Gets the selected target cells
|
||||
|
|
@ -552,6 +549,7 @@ private:
|
|||
std::unique_ptr<region_type> mp_complex_region;
|
||||
db::box_convert<db::CellInst> m_box_convert;
|
||||
|
||||
mutable db::LayoutLocker m_locker;
|
||||
mutable inst_iterator m_inst;
|
||||
mutable inst_array_iterator m_inst_array;
|
||||
mutable instance_element_type m_combined_instance;
|
||||
|
|
|
|||
|
|
@ -511,7 +511,14 @@ RecursiveShapeIterator::validate (RecursiveShapeReceiver *receiver) const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
RecursiveShapeIterator::reset ()
|
||||
{
|
||||
m_needs_reinit = true;
|
||||
m_locker = db::LayoutLocker ();
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveShapeIterator::reset_selection ()
|
||||
{
|
||||
if (mp_layout) {
|
||||
|
|
@ -554,13 +561,6 @@ RecursiveShapeIterator::unselect_all_cells ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveShapeIterator::reset ()
|
||||
{
|
||||
m_needs_reinit = true;
|
||||
m_locker = db::LayoutLocker ();
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveShapeIterator::select_cells (const std::set<db::cell_index_type> &cells)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -790,3 +790,69 @@ TEST(6)
|
|||
);
|
||||
}
|
||||
|
||||
// layout locking
|
||||
TEST(7_LayoutLocking)
|
||||
{
|
||||
db::Layout layout;
|
||||
|
||||
layout.insert_layer (0);
|
||||
|
||||
db::Cell &c0 (layout.cell (layout.add_cell ()));
|
||||
db::Cell &c1 (layout.cell (layout.add_cell ()));
|
||||
|
||||
db::Box b (0, 100, 1000, 1200);
|
||||
c1.shapes (0).insert (b);
|
||||
|
||||
db::Trans tt;
|
||||
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), tt));
|
||||
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (2000, -2000))));
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
|
||||
db::RecursiveInstanceIterator iter (layout, c0);
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
|
||||
EXPECT_EQ (iter.at_end (), false);
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
|
||||
EXPECT_EQ (iter.instance ().to_string (), "cell_index=1 r0 *1 0,0");
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
++iter;
|
||||
|
||||
EXPECT_EQ (iter.at_end (), false);
|
||||
|
||||
EXPECT_EQ (iter.instance ().to_string (), "cell_index=1 r0 *1 2000,-2000");
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
++iter;
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
EXPECT_EQ (iter.at_end (), true);
|
||||
|
||||
// reset will restart
|
||||
iter.reset ();
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
|
||||
EXPECT_EQ (iter.at_end (), false);
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
|
||||
// a copy will hold the lock
|
||||
iter.reset ();
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
EXPECT_EQ (iter.at_end (), false);
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
db::RecursiveInstanceIterator iter_copy = iter;
|
||||
|
||||
while (! iter.at_end ()) {
|
||||
++iter;
|
||||
}
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), true);
|
||||
iter_copy = db::RecursiveInstanceIterator ();
|
||||
|
||||
EXPECT_EQ (layout.under_construction (), false);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue