diff options
author | Sergiusz Bazanski <q3k@q3k.org> | 2018-07-20 18:34:59 +0100 |
---|---|---|
committer | Sergiusz Bazanski <q3k@q3k.org> | 2018-07-20 18:34:59 +0100 |
commit | 0311a27a53922783363ab607ca8f3832980990c6 (patch) | |
tree | 9cb3555b233b6224d946a263dceb1ebff6569d80 | |
parent | 5d0dbe9db961f6dbd2494bd8ab730d8926d01626 (diff) | |
download | nextpnr-0311a27a53922783363ab607ca8f3832980990c6.tar.gz nextpnr-0311a27a53922783363ab607ca8f3832980990c6.tar.bz2 nextpnr-0311a27a53922783363ab607ca8f3832980990c6.zip |
Use UI lock for yielding
-rw-r--r-- | common/nextpnr.h | 32 | ||||
-rw-r--r-- | common/placer1.cc | 6 | ||||
-rw-r--r-- | common/router1.cc | 12 | ||||
-rw-r--r-- | gui/fpgaviewwidget.cc | 4 |
4 files changed, 40 insertions, 14 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index d42d3446..8b8299bc 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -318,6 +318,11 @@ struct BaseCtx std::mutex mutex; pthread_t mutex_owner; + // Lock to be taken by UI when wanting to access context - the yield() + // method will lock/unlock it when its' released the main mutex to make + // sure the UI is not starved. + std::mutex ui_mutex; + // ID String database. mutable std::unordered_map<std::string, int> *idstring_str_to_idx; mutable std::vector<const std::string *> *idstring_idx_to_str; @@ -353,12 +358,31 @@ struct BaseCtx mutex.unlock(); } - // TODO(q3k): get rid of this hack + // Must be called by the UI before rendering data. This lock will be + // prioritized when processing code calls yield(). + void lock_ui(void) + { + ui_mutex.lock(); + mutex.lock(); + } + + void unlock_ui(void) + { + mutex.unlock(); + ui_mutex.unlock(); + } + + // Yield to UI by unlocking the main mutex, flashing the UI mutex and + // relocking the main mutex. Call this when you're performing a + // long-standing action while holding a lock to let the UI show + // visualization updates. + // Must be called with the main lock taken. void yield(void) { - for (int i = 0; i < 10; i++) { - pthread_yield(); - } + unlock(); + ui_mutex.lock(); + ui_mutex.unlock(); + lock(); } IdString id(const std::string &s) const { return IdString(this, s); } diff --git a/common/placer1.cc b/common/placer1.cc index c8ba71a4..025c7c15 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -156,8 +156,6 @@ class SAPlacer // Main simulated annealing loop for (int iter = 1;; iter++) { - ctx->yield(); - ctx->lock(); n_move = n_accept = 0; improved = false; @@ -242,7 +240,9 @@ class SAPlacer metrics[net.first] = wl; curr_metric += wl; } - ctx->unlock(); + + // Let the UI show visualization updates. + ctx->yield(); } // Final post-pacement validitiy check ctx->lock(); diff --git a/common/router1.cc b/common/router1.cc index 3a0aa19b..3e4416df 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -495,8 +495,6 @@ bool router1(Context *ctx) #endif return false; } - ctx->yield(); - ctx->lock(); iterCnt++; if (ctx->verbose) @@ -533,9 +531,11 @@ bool router1(Context *ctx) ripupQueue.insert(net_name); } - if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) + if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) { log_info(" processed %d nets. (%d routed, %d failed)\n", netCnt, netCnt - int(ripupQueue.size()), int(ripupQueue.size())); + ctx->yield(); + } } int normalRouteCnt = netCnt - int(ripupQueue.size()); @@ -596,8 +596,10 @@ bool router1(Context *ctx) ripCnt += router.rippedNets.size(); - if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) + if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) { log_info(" routed %d nets, ripped %d nets.\n", netCnt, ripCnt); + ctx->yield(); + } } if ((ctx->verbose || iterCnt == 1) && (netCnt % 100 != 0)) @@ -626,7 +628,7 @@ bool router1(Context *ctx) if (iterCnt == 8 || iterCnt == 16 || iterCnt == 32 || iterCnt == 64 || iterCnt == 128) ripup_penalty += ctx->getRipupDelayPenalty(); - ctx->unlock(); + ctx->yield(); } log_info("routing complete after %d iterations.\n", iterCnt); diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index b990baca..86aae25d 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -426,7 +426,7 @@ void FPGAViewWidget::renderLines(void) if (ctx_ == nullptr) return; - ctx_->lock(); + ctx_->lock_ui(); // For now, collapse any decal changes into change of all decals. // TODO(q3k): fix this @@ -475,7 +475,7 @@ void FPGAViewWidget::renderLines(void) groupDecals.push_back(ctx_->getGroupDecal(group)); } } - ctx_->unlock(); + ctx_->unlock_ui(); rendererArgsLock_.lock(); auto selectedItems = rendererArgs_->selectedItems; |