aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Rothman <537074+litghost@users.noreply.github.com>2021-02-26 11:37:27 -0800
committerKeith Rothman <537074+litghost@users.noreply.github.com>2021-02-26 11:40:58 -0800
commit77a5a60a66b0cfc1602edb61aadf392dc651bf46 (patch)
tree9ebd1ff8d35cc6d008d66b159709709747c4d6cd
parent7878561970d27ff2fed73fe0909fa64320e34bc8 (diff)
downloadnextpnr-77a5a60a66b0cfc1602edb61aadf392dc651bf46.tar.gz
nextpnr-77a5a60a66b0cfc1602edb61aadf392dc651bf46.tar.bz2
nextpnr-77a5a60a66b0cfc1602edb61aadf392dc651bf46.zip
Fix latent bug with context locking in placer HeAP.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
-rw-r--r--common/placer_heap.cc22
-rw-r--r--common/scope_lock.h56
2 files changed, 68 insertions, 10 deletions
diff --git a/common/placer_heap.cc b/common/placer_heap.cc
index df1454e8..cea862af 100644
--- a/common/placer_heap.cc
+++ b/common/placer_heap.cc
@@ -49,6 +49,7 @@
#include "nextpnr.h"
#include "place_common.h"
#include "placer1.h"
+#include "scope_lock.h"
#include "timing.h"
#include "util.h"
@@ -147,7 +148,7 @@ class HeAPPlacer
{
auto startt = std::chrono::high_resolution_clock::now();
- ctx->lock();
+ nextpnr::ScopeLock<Context> lock(ctx);
place_constraints();
build_fast_bels();
seed_placement();
@@ -312,15 +313,6 @@ class HeAPPlacer
log_info("AP soln: %s -> %s\n", cell.first.c_str(ctx), ctx->nameOfBel(cell.second->bel));
}
- ctx->unlock();
- auto endtt = std::chrono::high_resolution_clock::now();
- log_info("HeAP Placer Time: %.02fs\n", std::chrono::duration<double>(endtt - startt).count());
- log_info(" of which solving equations: %.02fs\n", solve_time);
- log_info(" of which spreading cells: %.02fs\n", cl_time);
- log_info(" of which strict legalisation: %.02fs\n", sl_time);
-
- ctx->check();
-
bool any_bad_placements = false;
for (auto bel : ctx->getBels()) {
CellInfo *cell = ctx->getBoundBelCell(bel);
@@ -339,6 +331,16 @@ class HeAPPlacer
return false;
}
+ lock.unlock_early();
+
+ auto endtt = std::chrono::high_resolution_clock::now();
+ log_info("HeAP Placer Time: %.02fs\n", std::chrono::duration<double>(endtt - startt).count());
+ log_info(" of which solving equations: %.02fs\n", solve_time);
+ log_info(" of which spreading cells: %.02fs\n", cl_time);
+ log_info(" of which strict legalisation: %.02fs\n", sl_time);
+
+ ctx->check();
+
if (!placer1_refine(ctx, Placer1Cfg(ctx))) {
return false;
}
diff --git a/common/scope_lock.h b/common/scope_lock.h
new file mode 100644
index 00000000..35de6bc9
--- /dev/null
+++ b/common/scope_lock.h
@@ -0,0 +1,56 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021 Symbiflow Authors.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef SCOPE_LOCK_H
+#define SCOPE_LOCK_H
+
+namespace nextpnr {
+
+// Provides a simple RIAA locking object. ScopeLock takes a lock when
+// constructed, and releases the lock on destruction or if "unlock_early" is
+// called.
+//
+// LockingObject must have a method "void lock(void)" and "void unlock(void)".
+template<typename LockingObject>
+class ScopeLock {
+public:
+ ScopeLock(LockingObject * obj) : obj_(obj), locked_(false) {
+ obj_->lock();
+ locked_ = true;
+ }
+ ScopeLock(const ScopeLock &other) = delete;
+ ScopeLock(const ScopeLock &&other) = delete;
+
+ ~ScopeLock() {
+ if(locked_) {
+ obj_->unlock();
+ }
+ }
+ void unlock_early() {
+ locked_ = false;
+ obj_->unlock();
+ }
+private:
+ LockingObject *obj_;
+ bool locked_;
+};
+
+};
+
+#endif /* SCOPE_LOCK_H */