diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f1d7b6a..8060fe0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -388,30 +388,7 @@ find_package(Threads) find_package(Eigen3 REQUIRED) -################################################################ -# -# Locate CUDD bdd package. -# -find_library(CUDD_LIB - NAME cudd - PATHS ${CUDD_DIR} - PATH_SUFFIXES lib lib/cudd cudd/.libs - ) -if (CUDD_LIB) - message(STATUS "CUDD library: ${CUDD_LIB}") - get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH) - get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH) - find_file(CUDD_HEADER cudd.h - PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd) - if (CUDD_HEADER) - get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH) - message(STATUS "CUDD header: ${CUDD_HEADER}") - else() - message(STATUS "CUDD header: not found") - endif() -else() - message(STATUS "CUDD library: not found") -endif() +include(cmake/FindCUDD.cmake) if("${SSTA}" STREQUAL "") set(SSTA 0) @@ -479,7 +456,7 @@ set_source_files_properties(${STA_SWIG_CXX_FILE} PROPERTIES # No simple way to modify the swig template that emits code full of warnings # so suppress them. - COMPILE_OPTIONS "-Wno-cast-qual;-Wno-missing-braces;-Wno-deprecated-declarations" + COMPILE_OPTIONS "-Wunused-variable;-Wno-cast-qual;-Wno-missing-braces;-Wno-deprecated-declarations" ) target_link_libraries(sta_swig diff --git a/cmake/FindCUDD.cmake b/cmake/FindCUDD.cmake new file mode 100644 index 00000000..170548d4 --- /dev/null +++ b/cmake/FindCUDD.cmake @@ -0,0 +1,25 @@ +################################################################ +# +# Locate CUDD bdd package. +# +################################################################ +find_library(CUDD_LIB + NAME cudd + PATHS ${CUDD_DIR} + PATH_SUFFIXES lib lib/cudd cudd/.libs + ) +if (CUDD_LIB) + message(STATUS "CUDD library: ${CUDD_LIB}") + get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH) + get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH) + find_file(CUDD_HEADER cudd.h + PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd) + if (CUDD_HEADER) + get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH) + message(STATUS "CUDD header: ${CUDD_HEADER}") + else() + message(STATUS "CUDD header: not found") + endif() +else() + message(STATUS "CUDD library: not found") +endif() diff --git a/doc/messages.txt b/doc/messages.txt index 95adafbe..ea0fb51a 100644 --- a/doc/messages.txt +++ b/doc/messages.txt @@ -75,7 +75,6 @@ 0245 CheckTiming.cc:428 unknown print flag 0246 Corner.cc:377 unknown parasitic analysis point count 0247 Corner.cc:421 unknown analysis point count -0248 Crpr.cc:73 missing prev paths 0249 GatedClk.cc:247 illegal gated clock active value 0250 NetworkEdit.tcl:107 unsupported object type $object_type. 0252 NetworkEdit.tcl:174 unsupported object type $object_type. @@ -422,72 +421,72 @@ 1240 LibertyReader.cc:3397 unknown port direction. 1241 LibertyReader.cc:3644 max_transition is 0.0. 1242 LibertyReader.cc:3750 pulse_latch unknown pulse type. -1243 LibertyReader.cc:4194 timing group missing related_pin/related_bus_pin. -1244 LibertyReader.cc:4293 unknown timing_type %s. -1245 LibertyReader.cc:4313 unknown timing_sense %s. -1246 LibertyReader.cc:4353 mode value is not a string. -1247 LibertyReader.cc:4356 missing mode value. -1248 LibertyReader.cc:4359 mode name is not a string. -1249 LibertyReader.cc:4362 mode missing values. -1250 LibertyReader.cc:4365 mode missing mode name and value. -1251 LibertyReader.cc:4441 unsupported model axis. -1252 LibertyReader.cc:4468 unsupported model axis. -1253 LibertyReader.cc:4497 unsupported model axis. -1254 LibertyReader.cc:4532 unsupported model axis. -1255 LibertyReader.cc:4548 %s group not in timing group. -1256 LibertyReader.cc:4587 table template %s not found. -1257 LibertyReader.cc:4671 %s is missing values. -1258 LibertyReader.cc:4694 %s is not a list of floats. -1259 LibertyReader.cc:4696 table row has %u columns but axis has %d. -1260 LibertyReader.cc:4706 table has %u rows but axis has %d. -1261 LibertyReader.cc:4757 lut output is not a string. -1262 LibertyReader.cc:4773 cell %s test_cell redefinition. -1263 LibertyReader.cc:4821 mode definition missing name. -1264 LibertyReader.cc:4838 mode value missing name. -1265 LibertyReader.cc:4852 when attribute inside table model. -1266 LibertyReader.cc:4901 %s attribute is not a string. -1267 LibertyReader.cc:4904 %s is not a simple attribute. -1268 LibertyReader.cc:4924 %s attribute is not an integer. -1269 LibertyReader.cc:4927 %s is not a simple attribute. -1270 LibertyReader.cc:4940 %s is not a simple attribute. -1271 LibertyReader.cc:4966 %s value %s is not a float. -1272 LibertyReader.cc:4995 %s missing values. -1273 LibertyReader.cc:4999 %s missing values. -1274 LibertyReader.cc:5002 %s is not a complex attribute. -1275 LibertyReader.cc:5028 %s is not a float. -1276 LibertyReader.cc:5051 %s is missing values. -1277 LibertyReader.cc:5054 %s has more than one string. -1278 LibertyReader.cc:5063 %s is missing values. -1279 LibertyReader.cc:5088 %s attribute is not boolean. -1280 LibertyReader.cc:5091 %s attribute is not boolean. -1281 LibertyReader.cc:5094 %s is not a simple attribute. -1282 LibertyReader.cc:5110 attribute %s value %s not recognized. -1283 LibertyReader.cc:5141 unknown early/late value. -1284 LibertyReader.cc:5361 OCV derate group named %s not found. -1285 LibertyReader.cc:5377 ocv_derate missing name. -1286 LibertyReader.cc:5430 unknown rise/fall. -1287 LibertyReader.cc:5450 unknown derate type. -1288 LibertyReader.cc:5482 unsupported model axis. -1289 LibertyReader.cc:5514 unsupported model axis. -1290 LibertyReader.cc:5546 unsupported model axis. -1291 LibertyReader.cc:5617 unknown pg_type. -1292 LibertyReader.cc:6031 port %s subscript out of range. -1293 LibertyReader.cc:6035 port range %s of non-bus port %s. -1294 LibertyReader.cc:6049 port %s not found. -1295 LibertyReader.cc:6119 port %s not found. +1243 LibertyReader.cc:4202 timing group missing related_pin/related_bus_pin. +1244 LibertyReader.cc:4301 unknown timing_type %s. +1245 LibertyReader.cc:4321 unknown timing_sense %s. +1246 LibertyReader.cc:4361 mode value is not a string. +1247 LibertyReader.cc:4364 missing mode value. +1248 LibertyReader.cc:4367 mode name is not a string. +1249 LibertyReader.cc:4370 mode missing values. +1250 LibertyReader.cc:4373 mode missing mode name and value. +1251 LibertyReader.cc:4449 unsupported model axis. +1252 LibertyReader.cc:4476 unsupported model axis. +1253 LibertyReader.cc:4505 unsupported model axis. +1254 LibertyReader.cc:4540 unsupported model axis. +1255 LibertyReader.cc:4556 %s group not in timing group. +1256 LibertyReader.cc:4595 table template %s not found. +1257 LibertyReader.cc:4679 %s is missing values. +1258 LibertyReader.cc:4702 %s is not a list of floats. +1259 LibertyReader.cc:4704 table row has %u columns but axis has %d. +1260 LibertyReader.cc:4714 table has %u rows but axis has %d. +1261 LibertyReader.cc:4765 lut output is not a string. +1262 LibertyReader.cc:4781 cell %s test_cell redefinition. +1263 LibertyReader.cc:4829 mode definition missing name. +1264 LibertyReader.cc:4846 mode value missing name. +1265 LibertyReader.cc:4860 when attribute inside table model. +1266 LibertyReader.cc:4909 %s attribute is not a string. +1267 LibertyReader.cc:4912 %s is not a simple attribute. +1268 LibertyReader.cc:4932 %s attribute is not an integer. +1269 LibertyReader.cc:4935 %s is not a simple attribute. +1270 LibertyReader.cc:4948 %s is not a simple attribute. +1271 LibertyReader.cc:4974 %s value %s is not a float. +1272 LibertyReader.cc:5003 %s missing values. +1273 LibertyReader.cc:5007 %s missing values. +1274 LibertyReader.cc:5010 %s is not a complex attribute. +1275 LibertyReader.cc:5036 %s is not a float. +1276 LibertyReader.cc:5059 %s is missing values. +1277 LibertyReader.cc:5062 %s has more than one string. +1278 LibertyReader.cc:5071 %s is missing values. +1279 LibertyReader.cc:5096 %s attribute is not boolean. +1280 LibertyReader.cc:5099 %s attribute is not boolean. +1281 LibertyReader.cc:5102 %s is not a simple attribute. +1282 LibertyReader.cc:5118 attribute %s value %s not recognized. +1283 LibertyReader.cc:5149 unknown early/late value. +1284 LibertyReader.cc:5369 OCV derate group named %s not found. +1285 LibertyReader.cc:5385 ocv_derate missing name. +1286 LibertyReader.cc:5438 unknown rise/fall. +1287 LibertyReader.cc:5458 unknown derate type. +1288 LibertyReader.cc:5490 unsupported model axis. +1289 LibertyReader.cc:5522 unsupported model axis. +1290 LibertyReader.cc:5554 unsupported model axis. +1291 LibertyReader.cc:5625 unknown pg_type. +1292 LibertyReader.cc:6039 port %s subscript out of range. +1293 LibertyReader.cc:6043 port range %s of non-bus port %s. +1294 LibertyReader.cc:6057 port %s not found. +1295 LibertyReader.cc:6127 port %s not found. 1297 LibertyReader.cc:1466 axis type %s not supported. 1298 LibertyReader.cc:2180 statetable input port %s not found. 1299 LibertyReader.cc:3809 unknown signal_type %s. -1300 LibertyReader.cc:4068 table row must have 3 groups separated by ':'. -1301 LibertyReader.cc:4073 table row has %zu input values but %zu are required. -1302 LibertyReader.cc:4080 table row has %zu current values but %zu are required. -1303 LibertyReader.cc:4087 table row has %zu next values but %zu are required. -1304 LibertyReader.cc:4133 table input value '%s' not recognized. -1305 LibertyReader.cc:4152 table internal value '%s' not recognized. -1340 LibertyWriter.cc:307 %s/%s bundled ports not supported. -1341 LibertyWriter.cc:455 %s/%s/%s timing model not supported. -1342 LibertyWriter.cc:475 3 axis table models not supported. -1343 LibertyWriter.cc:624 %s/%s/%s timing arc type %s not supported. +1300 LibertyReader.cc:4076 table row must have 3 groups separated by ':'. +1301 LibertyReader.cc:4081 table row has %zu input values but %zu are required. +1302 LibertyReader.cc:4088 table row has %zu current values but %zu are required. +1303 LibertyReader.cc:4095 table row has %zu next values but %zu are required. +1304 LibertyReader.cc:4141 table input value '%s' not recognized. +1305 LibertyReader.cc:4160 table internal value '%s' not recognized. +1340 LibertyWriter.cc:308 %s/%s bundled ports not supported. +1341 LibertyWriter.cc:456 %s/%s/%s timing model not supported. +1342 LibertyWriter.cc:476 3 axis table models not supported. +1343 LibertyWriter.cc:625 %s/%s/%s timing arc type %s not supported. 1350 LumpedCapDelayCalc.cc:138 gate delay input variable is NaN 1355 MakeTimingModel.cc:227 clock %s pin %s is inside model block. 1360 Vcd.cc:172 Unknown variable %s ID %s @@ -505,17 +504,15 @@ 1525 SpefParse.yy:805 %d is not positive. 1526 SpefParse.yy:814 %.4f is not positive. 1527 SpefParse.yy:820 %.4f is not positive. -1550 Sta.cc:1999 '%s' is not a valid start point. -1551 Sta.cc:2072 '%s' is not a valid endpoint. -1552 Sta.cc:2075 '%s' is not a valid endpoint. -1553 Sta.cc:2391 maximum corner count exceeded -1554 Sta.cc:1996 '%s' is not a valid start point. -1570 Search.i:54 no network has been linked. -1571 Search.i:68 network does not support edits. -1574 Search.i:1121 POCV support requires compilation with SSTA=1. -1575 Search.i:530 unknown report path field %s -1576 Search.i:542 unknown report path field %s -1600 WritePathSpice.cc:165 No liberty libraries found, +1550 Sta.cc:2000 '%s' is not a valid start point. +1551 Sta.cc:2073 '%s' is not a valid endpoint. +1552 Sta.cc:2076 '%s' is not a valid endpoint. +1553 Sta.cc:2393 maximum corner count exceeded +1554 Sta.cc:1997 '%s' is not a valid start point. +1570 Sta.cc:3413 No network has been linked. +1574 Search.i:1026 POCV support requires compilation with SSTA=1. +1575 Search.i:465 unknown report path field %s +1576 Search.i:477 unknown report path field %s 1602 WriteSpice.cc:458 Liberty pg_port %s/%s missing voltage_name attribute, 1603 WriteSpice.cc:428 %s pg_port %s not found, 1604 WriteSpice.cc:1019 no register/latch found for path from %s to %s, @@ -575,7 +572,10 @@ 2103 ArcDelayCalc.cc:97 %s not a valid rise/fall. 2104 ArcDelayCalc.cc:100 Pin %s/%s not found. 2105 ArcDelayCalc.cc:103 Instance %s not found. -2120 Network.i:252 unknown namespace -2121 Sdc.i:105 unknown analysis type -2122 Sdc.i:232 unknown wire load mode -2140 StaTclTypes.i:431 Delay calc arg requires 5 or 6 args. +2120 Network.i:255 unknown namespace +2121 Sdc.i:104 unknown analysis type +2122 Sdc.i:227 unknown wire load mode +2140 StaTclTypes.i:424 Delay calc arg requires 5 or 6 args. +2141 Sta.cc:3417 No liberty libraries found. +2200 Crpr.cc:62 missing prev paths +2201 Crpr.cc:73 missing prev paths diff --git a/graph/DelayNormal1.cc b/graph/DelayNormal1.cc index 294766c1..603c012d 100644 --- a/graph/DelayNormal1.cc +++ b/graph/DelayNormal1.cc @@ -63,6 +63,12 @@ Delay::Delay(const Delay &delay) : { } +Delay::Delay(const DelayDbl &delay) : + mean_(delay.mean_), + sigma2_(delay.sigma2_) +{ +} + Delay::Delay(float mean) : mean_(mean), sigma2_(0.0) @@ -173,6 +179,35 @@ Delay::operator==(const Delay &delay) const //////////////////////////////////////////////////////////////// +DelayDbl::DelayDbl() : + mean_(0.0), + sigma2_(0.0) +{ +} + +void +DelayDbl::operator=(float delay) +{ + mean_ = delay; + sigma2_ = 0.0; +} + +void +DelayDbl::operator+=(const Delay &delay) +{ + mean_ += delay.mean_; + sigma2_ += delay.sigma2_; +} + +void +DelayDbl::operator-=(const Delay &delay) +{ + mean_ -= delay.mean_; + sigma2_ += delay.sigma2_; +} + +//////////////////////////////////////////////////////////////// + Delay makeDelay(float delay, float sigma, diff --git a/graph/DelayNormal2.cc b/graph/DelayNormal2.cc index 4bdd482b..bd444e51 100644 --- a/graph/DelayNormal2.cc +++ b/graph/DelayNormal2.cc @@ -64,6 +64,13 @@ Delay::Delay(const Delay &delay) : sigma2_[EarlyLate::lateIndex()] = delay.sigma2_[EarlyLate::lateIndex()]; } +Delay::Delay(const DelayDbl &delay) : + mean_(delay.mean_) +{ + sigma2_[EarlyLate::earlyIndex()] = delay.sigma2_[EarlyLate::earlyIndex()]; + sigma2_[EarlyLate::lateIndex()] = delay.sigma2_[EarlyLate::lateIndex()]; +} + Delay::Delay(float mean) : mean_(mean), sigma2_{0.0, 0.0} @@ -196,6 +203,38 @@ Delay::operator==(const Delay &delay) const //////////////////////////////////////////////////////////////// +DelayDbl::DelayDbl() : + mean_(0.0), + sigma2_{0.0, 0.0} +{ +} + +void +DelayDbl::operator=(float delay) +{ + mean_ = delay; + sigma2_[early_index] = 0.0; + sigma2_[late_index] = 0.0; +} + +void +DelayDbl::operator+=(const Delay &delay) +{ + mean_ += delay.mean_; + sigma2_[early_index] += delay.sigma2_[early_index]; + sigma2_[late_index] += delay.sigma2_[late_index]; +} + +void +DelayDbl::operator-=(const Delay &delay) +{ + mean_ -= delay.mean_; + sigma2_[early_index] += delay.sigma2_[early_index]; + sigma2_[late_index] += delay.sigma2_[late_index]; +} + +//////////////////////////////////////////////////////////////// + Delay makeDelay(float delay, float sigma_early, diff --git a/include/sta/DelayFloat.hh b/include/sta/DelayFloat.hh index 68143025..800c7e03 100644 --- a/include/sta/DelayFloat.hh +++ b/include/sta/DelayFloat.hh @@ -25,6 +25,8 @@ namespace sta { class StaState; typedef float Delay; +// Delay double for accumulating Delays. +typedef double DelayDbl; const Delay delay_zero = 0.0; diff --git a/include/sta/DelayNormal1.hh b/include/sta/DelayNormal1.hh index a8bbacc8..103fe881 100644 --- a/include/sta/DelayNormal1.hh +++ b/include/sta/DelayNormal1.hh @@ -21,6 +21,7 @@ namespace sta { class Delay; +class DelayDbl; class StaState; // Normal distribution with std deviation. @@ -29,6 +30,7 @@ class Delay public: Delay(); Delay(const Delay &delay); + Delay(const DelayDbl &delay); Delay(float mean); Delay(float mean, float sigma2); @@ -53,6 +55,29 @@ private: float mean_; // Sigma^2 float sigma2_; + + friend class DelayDbl; +}; + +// Dwlay with doubles for accumulating delays. +class DelayDbl +{ +public: + DelayDbl(); + float mean() const { return mean_; } + float sigma() const; + // sigma^2 + float sigma2() const; + void operator=(float delay); + void operator+=(const Delay &delay); + void operator-=(const Delay &delay); + +private: + double mean_; + // Sigma^2 + double sigma2_; + + friend class Delay; }; const Delay delay_zero(0.0); diff --git a/include/sta/DelayNormal2.hh b/include/sta/DelayNormal2.hh index f7aac325..5f77eacd 100644 --- a/include/sta/DelayNormal2.hh +++ b/include/sta/DelayNormal2.hh @@ -21,6 +21,7 @@ namespace sta { class Delay; +class DelayDbl; class StaState; // Normal distribution with early(left)/late(right) std deviations. @@ -29,6 +30,7 @@ class Delay public: Delay(); Delay(const Delay &delay); + Delay(const DelayDbl &delay); Delay(float mean); Delay(float mean, float sigma2_early, @@ -60,6 +62,33 @@ private: float mean_; // Sigma^2 float sigma2_[EarlyLate::index_count]; + + friend class DelayDbl; +}; + +// Dwlay with doubles for accumulating delays. +class DelayDbl +{ +public: + DelayDbl(); + float mean() const { return mean_; } + float sigma() const; + // sigma^2 + float sigma2() const; + void operator=(float delay); + void operator+=(const Delay &delay); + void operator-=(const Delay &delay); + +protected: + static const int early_index = 0; + static const int late_index = 1; + +private: + double mean_; + // Sigma^2 + double sigma2_[EarlyLate::index_count]; + + friend class Delay; }; const Delay delay_zero(0.0); diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 5b3d6772..8dce6775 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -60,6 +60,7 @@ typedef UnorderedSet TagGroupSet; typedef Map VertexSlackMap; typedef Vector VertexSlackMapSeq; typedef Vector WorstSlacksSeq; +typedef vector DelayDblSeq; class Search : public StaState { @@ -570,7 +571,7 @@ protected: // Endpoint vertices with slacks that have changed since tns was found. VertexSet *invalid_tns_; // Indexed by path_ap->index(). - SlackSeq tns_; + DelayDblSeq tns_; // Indexed by path_ap->index(). VertexSlackMapSeq tns_slacks_; std::mutex tns_lock_; diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 2eba572e..7b331f99 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -168,7 +168,12 @@ SpefReader::findInstanceRelative(const char *name) Net * SpefReader::findNetRelative(const char *name) { - return network_->findNetRelative(instance_, name); + Net *net = network_->findNetRelative(instance_, name); + // Relax spef escaping requirement because some commercial tools + // don't follow the rules. + if (net == nullptr) + net = sdc_network_->findNetRelative(instance_, name); + return net; } Pin * diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index e994461f..8ac52a7f 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -98,7 +98,6 @@ MakeTimingModel::makeTimingModel() makePorts(); sta_->searchPreamble(); - graph_ = sta_->graph(); findTimingFromInputs(); findClkedOutputPaths(); @@ -143,12 +142,7 @@ MakeTimingModel::makeLibrary() { library_ = network_->makeLibertyLibrary(lib_name_, filename_); LibertyLibrary *default_lib = network_->defaultLibertyLibrary(); - *library_->units()->timeUnit() = *default_lib->units()->timeUnit(); - *library_->units()->capacitanceUnit() = *default_lib->units()->capacitanceUnit(); - *library_->units()->voltageUnit() = *default_lib->units()->voltageUnit(); - *library_->units()->resistanceUnit() = *default_lib->units()->resistanceUnit(); - *library_->units()->powerUnit() = *default_lib->units()->powerUnit(); - *library_->units()->distanceUnit() = *default_lib->units()->distanceUnit(); + *library_->units() = *default_lib->units(); for (RiseFall *rf : RiseFall::range()) { library_->setInputThreshold(rf, default_lib->inputThreshold(rf)); diff --git a/search/Sta.cc b/search/Sta.cc index 09287127..d26b6f1c 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -5651,6 +5651,7 @@ Sta::writeTimingModel(const char *lib_name, const bool scalar) { ensureLinked(); + ensureGraph(); LibertyLibrary *library = makeTimingModel(lib_name, cell_name, filename, corner, scalar, this); writeLiberty(library, filename, this); diff --git a/search/WorstSlack.cc b/search/WorstSlack.cc index a6dae0d5..2aacdc49 100644 --- a/search/WorstSlack.cc +++ b/search/WorstSlack.cc @@ -265,32 +265,34 @@ WorstSlack::updateWorstSlack(Vertex *vertex, SlackSeq &slacks, PathAPIndex path_ap_index) { - Slack slack = slacks[path_ap_index]; - - // Locking is required because ArrivalVisitor is called by multiple - // threads. - LockGuard lock(lock_); - if (worst_vertex_ - && delayLess(slack, worst_slack_, this)) - setWorstSlack(vertex, slack); - else if (vertex == worst_vertex_) - // Mark worst slack as unknown (updated by findWorstSlack(). - worst_vertex_ = nullptr; - - if (!delayEqual(slack, slack_init_) - && delayLessEqual(slack, slack_threshold_, this)) { - debugPrint(debug_, "wns", 3, "insert %s %s", - vertex->name(network_), - delayAsString(slack, this)); - queue_->insert(vertex); - } - else { - debugPrint(debug_, "wns", 3, "delete %s %s", - vertex->name(network_), - delayAsString(slack, this)); - queue_->erase(vertex); + // Do not touch the state unless queue has been initialized + if (!queue_->empty()) { + Slack slack = slacks[path_ap_index]; + // Locking is required because ArrivalVisitor is called by multiple + // threads. + LockGuard lock(lock_); + if (worst_vertex_ + && delayLess(slack, worst_slack_, this)) + setWorstSlack(vertex, slack); + else if (vertex == worst_vertex_) + // Mark worst slack as unknown (updated by findWorstSlack(). + worst_vertex_ = nullptr; + + if (!delayEqual(slack, slack_init_) + && delayLessEqual(slack, slack_threshold_, this)) { + debugPrint(debug_, "wns", 3, "insert %s %s", + vertex->name(network_), + delayAsString(slack, this)); + queue_->insert(vertex); + } + else { + debugPrint(debug_, "wns", 3, "delete %s %s", + vertex->name(network_), + delayAsString(slack, this)); + queue_->erase(vertex); + } + //checkQueue(path_ap_index); } - // checkQueue(); } void