From b0c05c7f751cf68165849a8f28d389541456f956 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:37 +0100 Subject: Revert "Refactor proxies to nextpnr." This reverts commit 9b17fe385cf7e8d3025747b5f7c7822ac2d99920. --- ice40/arch.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 103 insertions(+), 27 deletions(-) (limited to 'ice40/arch.h') diff --git a/ice40/arch.h b/ice40/arch.h index 5d4eaedf..4311f4a5 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -22,6 +22,9 @@ #error Include "arch.h" via "nextpnr.h" only. #endif +#include +#include + NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -327,8 +330,11 @@ struct ArchArgs /// Forward declare proxy classes for Arch. -class ArchMutateMethods; -class ArchReadMethods; +class ArchRWProxyMethods; +class ArchRProxyMethods; +class ArchRWProxy; +class ArchRProxy; + /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped @@ -341,8 +347,11 @@ class ArchReadMethods; class Arch : public BaseCtx { // We let proxy methods access our state. - friend class ArchMutateMethods; - friend class ArchReadMethods; + friend class ArchRWProxyMethods; + friend class ArchRProxyMethods; + // We let proxy objects access our mutex. + friend class ArchRWProxy; + friend class ArchRProxy; private: // All of the following... std::vector bel_to_cell; @@ -353,6 +362,9 @@ private: mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; + // ... are guarded by the following lock: + mutable boost::shared_mutex mtx_; + public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -360,6 +372,15 @@ public: ArchArgs args; Arch(ArchArgs args); + // Get a readwrite proxy to arch - this will keep a readwrite lock on the + // entire architecture until the proxy object goes out of scope. + ArchRWProxy rwproxy(void); + // Get a read-only proxy to arch - this will keep a read lock on the + // entire architecture until the proxy object goes out of scope. Other read + // locks can be taken while this one still exists. Ie., the UI can draw + // elements while the PnR is going a RO operation. + ArchRProxy rproxy(void) const; + std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -611,9 +632,22 @@ public: }; // Read-only methods on Arch that require state access. -class ArchReadMethods : public BaseReadCtx { +class ArchRProxyMethods { + // We let proxy objects access our private constructors. + friend class ArchRProxy; + friend class ArchRWProxy; private: const Arch *parent_; + ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} + ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} + + // Let methods access hot members directly without having to go through + // parent_. const ChipInfoPOD *chip_info; const std::vector &bel_to_cell; const std::vector &wire_to_net; @@ -622,17 +656,8 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ~ArchReadMethods() noexcept { } - ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} - ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} + ~ArchRProxyMethods() noexcept { } /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) @@ -668,11 +693,44 @@ public: std::vector getDecalGraphics(DecalId decal) const; }; +// A proxy object that keeps an Arch shared/readonly lock until it goes out +// of scope. All const/read-only ArchRProxyMethods are available on it. +class ArchRProxy : public ArchRProxyMethods { + friend class Arch; + friend class ArchRWProxy; +private: + boost::shared_mutex *lock_; + ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) + { + lock_->lock_shared(); + } + +public: + ~ArchRProxy() { + if (lock_ != nullptr) { + lock_->unlock_shared(); + } + } + ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } +}; + // State mutating methods on Arch. -class ArchMutateMethods : public BaseMutateCtx { - friend class MutateContext; +class ArchRWProxyMethods { + // We let proxy objects access our private constructors. + friend class ArchRWProxy; private: Arch *parent_; + ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} + ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} + const ChipInfoPOD *chip_info; std::vector &bel_to_cell; std::vector &wire_to_net; @@ -681,17 +739,8 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} - ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} - ~ArchMutateMethods() {} + ~ArchRWProxyMethods() {} void unbindWire(WireId wire); void unbindPip(PipId pip); @@ -701,6 +750,33 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); + + + // Methods to be used by UI for detecting whether we need to redraw. + UIUpdatesRequired getUIUpdatesRequired(void); +}; + +// A proxy object that keeps an Arch readwrite lock until it goes out of scope. +// All ArchRProxyMethods and ArchRWProxyMethods are available on it. +class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { + friend class Arch; +private: + boost::shared_mutex *lock_; + ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { + lock_->lock(); + } + +public: + ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } + ~ArchRWProxy() + { + if (lock_ != nullptr) { + lock_->unlock(); + } + } }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3