Use UI lock for yielding

This commit is contained in:
Sergiusz Bazanski 2018-07-20 18:34:59 +01:00
parent 5d0dbe9db9
commit 0311a27a53
4 changed files with 40 additions and 14 deletions

View File

@ -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); }

View File

@ -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();

View File

@ -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);

View File

@ -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;