Use UI lock for yielding
This commit is contained in:
parent
5d0dbe9db9
commit
0311a27a53
@ -318,6 +318,11 @@ struct BaseCtx
|
|||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
pthread_t mutex_owner;
|
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.
|
// ID String database.
|
||||||
mutable std::unordered_map<std::string, int> *idstring_str_to_idx;
|
mutable std::unordered_map<std::string, int> *idstring_str_to_idx;
|
||||||
mutable std::vector<const std::string *> *idstring_idx_to_str;
|
mutable std::vector<const std::string *> *idstring_idx_to_str;
|
||||||
@ -353,12 +358,31 @@ struct BaseCtx
|
|||||||
mutex.unlock();
|
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)
|
void yield(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 10; i++) {
|
unlock();
|
||||||
pthread_yield();
|
ui_mutex.lock();
|
||||||
}
|
ui_mutex.unlock();
|
||||||
|
lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString id(const std::string &s) const { return IdString(this, s); }
|
IdString id(const std::string &s) const { return IdString(this, s); }
|
||||||
|
@ -156,8 +156,6 @@ class SAPlacer
|
|||||||
|
|
||||||
// Main simulated annealing loop
|
// Main simulated annealing loop
|
||||||
for (int iter = 1;; iter++) {
|
for (int iter = 1;; iter++) {
|
||||||
ctx->yield();
|
|
||||||
ctx->lock();
|
|
||||||
n_move = n_accept = 0;
|
n_move = n_accept = 0;
|
||||||
improved = false;
|
improved = false;
|
||||||
|
|
||||||
@ -242,7 +240,9 @@ class SAPlacer
|
|||||||
metrics[net.first] = wl;
|
metrics[net.first] = wl;
|
||||||
curr_metric += wl;
|
curr_metric += wl;
|
||||||
}
|
}
|
||||||
ctx->unlock();
|
|
||||||
|
// Let the UI show visualization updates.
|
||||||
|
ctx->yield();
|
||||||
}
|
}
|
||||||
// Final post-pacement validitiy check
|
// Final post-pacement validitiy check
|
||||||
ctx->lock();
|
ctx->lock();
|
||||||
|
@ -495,8 +495,6 @@ bool router1(Context *ctx)
|
|||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ctx->yield();
|
|
||||||
ctx->lock();
|
|
||||||
|
|
||||||
iterCnt++;
|
iterCnt++;
|
||||||
if (ctx->verbose)
|
if (ctx->verbose)
|
||||||
@ -533,9 +531,11 @@ bool router1(Context *ctx)
|
|||||||
ripupQueue.insert(net_name);
|
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()),
|
log_info(" processed %d nets. (%d routed, %d failed)\n", netCnt, netCnt - int(ripupQueue.size()),
|
||||||
int(ripupQueue.size()));
|
int(ripupQueue.size()));
|
||||||
|
ctx->yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int normalRouteCnt = netCnt - int(ripupQueue.size());
|
int normalRouteCnt = netCnt - int(ripupQueue.size());
|
||||||
@ -596,8 +596,10 @@ bool router1(Context *ctx)
|
|||||||
|
|
||||||
ripCnt += router.rippedNets.size();
|
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);
|
log_info(" routed %d nets, ripped %d nets.\n", netCnt, ripCnt);
|
||||||
|
ctx->yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctx->verbose || iterCnt == 1) && (netCnt % 100 != 0))
|
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)
|
if (iterCnt == 8 || iterCnt == 16 || iterCnt == 32 || iterCnt == 64 || iterCnt == 128)
|
||||||
ripup_penalty += ctx->getRipupDelayPenalty();
|
ripup_penalty += ctx->getRipupDelayPenalty();
|
||||||
|
|
||||||
ctx->unlock();
|
ctx->yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("routing complete after %d iterations.\n", iterCnt);
|
log_info("routing complete after %d iterations.\n", iterCnt);
|
||||||
|
@ -426,7 +426,7 @@ void FPGAViewWidget::renderLines(void)
|
|||||||
if (ctx_ == nullptr)
|
if (ctx_ == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx_->lock();
|
ctx_->lock_ui();
|
||||||
|
|
||||||
// For now, collapse any decal changes into change of all decals.
|
// For now, collapse any decal changes into change of all decals.
|
||||||
// TODO(q3k): fix this
|
// TODO(q3k): fix this
|
||||||
@ -475,7 +475,7 @@ void FPGAViewWidget::renderLines(void)
|
|||||||
groupDecals.push_back(ctx_->getGroupDecal(group));
|
groupDecals.push_back(ctx_->getGroupDecal(group));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx_->unlock();
|
ctx_->unlock_ui();
|
||||||
|
|
||||||
rendererArgsLock_.lock();
|
rendererArgsLock_.lock();
|
||||||
auto selectedItems = rendererArgs_->selectedItems;
|
auto selectedItems = rendererArgs_->selectedItems;
|
||||||
|
Loading…
Reference in New Issue
Block a user