mirror of https://github.com/KLayout/klayout.git
[consider merging] Enabling Shapes-based RecursiveShapeIterators for MT-use
This fixes a crash when using DRC fill in tiled mode with multiple threads.
This commit is contained in:
parent
54a4564a52
commit
76f7c620f6
|
|
@ -280,7 +280,8 @@ fill_polygon_impl (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type f
|
||||||
|
|
||||||
{
|
{
|
||||||
// In case we run this from a tiling processor we need to lock against multithread races
|
// In case we run this from a tiling processor we need to lock against multithread races
|
||||||
tl::MutexLocker locker (&db::TilingProcessor::output_lock ());
|
tl_assert (cell->layout () != 0);
|
||||||
|
tl::MutexLocker locker (&cell->layout ()->lock ());
|
||||||
cell->insert (array);
|
cell->insert (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -500,15 +500,21 @@ RecursiveShapeIterator::validate (RecursiveShapeReceiver *receiver) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_shapes) {
|
if (mp_shapes) {
|
||||||
|
|
||||||
// Ensures the trees are built properly - this is important in MT contexts (i.e. TilingProcessor)
|
// Ensures the trees are built properly - this is important in MT contexts (i.e. TilingProcessor)
|
||||||
// TODO: get rid of that const cast
|
// TODO: get rid of that const cast
|
||||||
(const_cast <db::Shapes *> (mp_shapes))->update ();
|
(const_cast <db::Shapes *> (mp_shapes))->update ();
|
||||||
|
|
||||||
start_shapes ();
|
start_shapes ();
|
||||||
|
|
||||||
} else if (mp_layout && (! m_has_layers || m_current_layer < m_layers.size ())) {
|
} else if (mp_layout && (! m_has_layers || m_current_layer < m_layers.size ())) {
|
||||||
|
|
||||||
// Ensures the trees are built properly - this is important in MT contexts (i.e. TilingProcessor)
|
// Ensures the trees are built properly - this is important in MT contexts (i.e. TilingProcessor)
|
||||||
mp_layout->update ();
|
mp_layout->update ();
|
||||||
|
|
||||||
new_cell (receiver);
|
new_cell (receiver);
|
||||||
next_shape (receiver);
|
next_shape (receiver);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_layout && ! at_end ()) {
|
if (mp_layout && ! at_end ()) {
|
||||||
|
|
|
||||||
|
|
@ -1127,10 +1127,20 @@ void Shapes::reset_bbox_dirty ()
|
||||||
|
|
||||||
void Shapes::update ()
|
void Shapes::update ()
|
||||||
{
|
{
|
||||||
|
std::unique_ptr<tl::MutexLocker> locker;
|
||||||
|
|
||||||
|
// If not in a layout context, we should lock here against multiple calls from different threads.
|
||||||
|
// In a layout context, the Layout object will do that for us.
|
||||||
|
if (layout () == 0) {
|
||||||
|
static tl::Mutex lock;
|
||||||
|
locker.reset (new tl::MutexLocker (&lock));
|
||||||
|
}
|
||||||
|
|
||||||
for (tl::vector<LayerBase *>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
|
for (tl::vector<LayerBase *>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
|
||||||
(*l)->sort ();
|
(*l)->sort ();
|
||||||
(*l)->update_bbox ();
|
(*l)->update_bbox ();
|
||||||
}
|
}
|
||||||
|
|
||||||
set_dirty (false);
|
set_dirty (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue