diff options
27 files changed, 358 insertions, 139 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 1eccdd3f291..7beb745cbf2 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -218,7 +218,7 @@ public: { } - virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override; + virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: device_t &m_dev; pstring m_name; @@ -229,7 +229,7 @@ class netlist_data_memregions_t : public netlist::source_t public: netlist_data_memregions_t(device_t &dev); - virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override; + virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: device_t &m_dev; @@ -240,7 +240,7 @@ private: // memregion source support // ---------------------------------------------------------------------------------------- -std::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name) { //memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().setup().exec()).machine().root_device().memregion(m_name.c_str()); memory_region *mem = m_dev.machine().root_device().memregion(m_name.c_str()); @@ -252,7 +252,7 @@ netlist_data_memregions_t::netlist_data_memregions_t(device_t &dev) { } -std::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring &name) { //memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().setup().exec()).parent().memregion(name.c_str()); memory_region *mem = m_dev.memregion(name.c_str()); @@ -264,7 +264,7 @@ std::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring { // This should be the last data provider being called - last resort fatalerror("data named %s not found in device rom regions\n", name.c_str()); - return std::unique_ptr<plib::pistream>(nullptr); + return plib::unique_ptr<plib::pistream>(nullptr); } } diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index b37fd31abf6..cadbdf0b7bb 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -464,9 +464,9 @@ netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstri ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \ ENTRYY(n, 7, s); ENTRYY(n, 8, s) -std::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile) +plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile) { - std::unique_ptr<netlist_base_factory_truthtable_t> ret; + plib::unique_ptr<netlist_base_factory_truthtable_t> ret; switch (desc.ni * 100 + desc.no) { diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index abc6b108ce5..a4b9e1e238e 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -225,7 +225,7 @@ namespace devices }; /* the returned element is still missing a pointer to the family ... */ - std::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile); + plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile); } //namespace devices } // namespace netlist diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index bb2e2daafdd..3d6a8cf04b0 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -236,7 +236,7 @@ detail::terminal_type detail::core_terminal_t::type() const // netlist_t // ---------------------------------------------------------------------------------------- -netlist_t::netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks) +netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks) : m_state(plib::make_unique<netlist_state_t>(aname, std::move(callbacks), plib::make_unique<setup_t>(*this))) // FIXME, ugly but needed to have netlist_state_t constructed first @@ -256,8 +256,8 @@ netlist_t::netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callback // ---------------------------------------------------------------------------------------- netlist_state_t::netlist_state_t(const pstring &aname, - std::unique_ptr<callbacks_t> &&callbacks, - std::unique_ptr<setup_t> &&setup) + plib::unique_ptr<callbacks_t> &&callbacks, + plib::unique_ptr<setup_t> &&setup) : m_name(aname) , m_state() , m_callbacks(std::move(callbacks)) // Order is important here @@ -1035,7 +1035,7 @@ nl_double param_model_t::model_value(const pstring &entity) } -std::unique_ptr<plib::pistream> param_data_t::stream() +plib::unique_ptr<plib::pistream> param_data_t::stream() { return device().setup().get_data_stream(Value()); } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 5975eaa4011..7f65a33e6bf 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -30,7 +30,7 @@ #include "nl_time.h" //============================================================ -// MACROS / New Syntax999 +// MACROS / New Syntax //============================================================ /*! Construct a netlist device name */ @@ -1070,7 +1070,7 @@ namespace netlist { } - std::unique_ptr<plib::pistream> stream(); + plib::unique_ptr<plib::pistream> stream(); protected: void changed() override { } }; @@ -1276,8 +1276,8 @@ namespace netlist /* need to preserve order of device creation ... */ using devices_collection_type = std::vector<std::pair<pstring, poolptr<core_device_t>>>; netlist_state_t(const pstring &aname, - std::unique_ptr<callbacks_t> &&callbacks, - std::unique_ptr<setup_t> &&setup); + plib::unique_ptr<callbacks_t> &&callbacks, + plib::unique_ptr<setup_t> &&setup); COPYASSIGNMOVE(netlist_state_t, delete) @@ -1371,7 +1371,7 @@ namespace netlist } /* sole use is to manage lifetime of family objects */ - std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache; + std::vector<std::pair<pstring, plib::unique_ptr<logic_family_desc_t>>> m_family_cache; setup_t &setup() NL_NOEXCEPT { return *m_setup; } const setup_t &setup() const NL_NOEXCEPT { return *m_setup; } @@ -1387,11 +1387,11 @@ namespace netlist void reset(); pstring m_name; - std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists + plib::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists plib::state_manager_t m_state; - std::unique_ptr<callbacks_t> m_callbacks; + plib::unique_ptr<callbacks_t> m_callbacks; log_type m_log; - std::unique_ptr<setup_t> m_setup; + plib::unique_ptr<setup_t> m_setup; nets_collection_type m_nets; /* sole use is to manage lifetime of net objects */ @@ -1409,7 +1409,7 @@ namespace netlist { public: - explicit netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks); + explicit netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks); COPYASSIGNMOVE(netlist_t, delete) @@ -1454,7 +1454,7 @@ namespace netlist void print_stats() const; private: - std::unique_ptr<netlist_state_t> m_state; + plib::unique_ptr<netlist_state_t> m_state; devices::NETLIB_NAME(solver) * m_solver; /* mostly rw */ diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index 793a0b4d1bc..c9d5ea7e29f 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -52,7 +52,7 @@ namespace netlist { namespace factory { } - void list_t::register_device(std::unique_ptr<element_t> &&factory) + void list_t::register_device(plib::unique_ptr<element_t> &&factory) { for (auto & e : *this) if (e->name() == factory->name()) diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index 3ed98b19152..cd7e74944eb 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -25,7 +25,7 @@ NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param) \ #define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \ - static std::unique_ptr<factory::element_t> NETLIB_NAME(p_alias ## _c) \ + static plib::unique_ptr<factory::element_t> NETLIB_NAME(p_alias ## _c) \ (const pstring &classname) \ { \ return plib::make_unique<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(p_name, classname, p_def_param, pstring(__FILE__)); \ @@ -91,7 +91,7 @@ namespace factory { } }; - class list_t : public std::vector<std::unique_ptr<element_t>> + class list_t : public std::vector<plib::unique_ptr<element_t>> { public: explicit list_t(log_type &alog); @@ -106,7 +106,7 @@ namespace factory { register_device(plib::make_unique<device_element_t<device_class>>(name, classname, def_param)); } - void register_device(std::unique_ptr<element_t> &&factory); + void register_device(plib::unique_ptr<element_t> &&factory); element_t * factory_by_name(const pstring &devname); @@ -124,10 +124,10 @@ namespace factory { // factory_creator_ptr_t // ----------------------------------------------------------------------------- - using constructor_ptr_t = std::unique_ptr<element_t> (*)(const pstring &classname); + using constructor_ptr_t = plib::unique_ptr<element_t> (*)(const pstring &classname); template <typename T> - std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname, + plib::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname, const pstring &def_param) { return plib::make_unique<device_element_t<T>>(name, classname, def_param); diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index b9196852878..b892fb4571c 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -219,7 +219,7 @@ namespace netlist return false; } - bool nlparse_t::parse_stream(std::unique_ptr<plib::pistream> &&istrm, const pstring &name) + bool nlparse_t::parse_stream(plib::unique_ptr<plib::pistream> &&istrm, const pstring &name) { return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name); } @@ -986,7 +986,7 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model) // Sources // ---------------------------------------------------------------------------------------- -std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name) +plib::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name) { for (auto &source : m_sources) { @@ -998,7 +998,7 @@ std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name) } } log().warning(MW_1_DATA_1_NOT_FOUND, name); - return std::unique_ptr<plib::pistream>(nullptr); + return plib::unique_ptr<plib::pistream>(nullptr); } @@ -1146,19 +1146,19 @@ bool source_t::parse(nlparse_t &setup, const pstring &name) } } -std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name) { plib::unused_var(name); return plib::make_unique<plib::pimemstream>(m_str.c_str(), std::strlen(m_str.c_str())); } -std::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name) { plib::unused_var(name); return plib::make_unique<plib::pimemstream>(m_str.c_str(), std::strlen(m_str.c_str())); } -std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name) { plib::unused_var(name); return plib::make_unique<plib::pifilestream>(m_filename); @@ -1175,10 +1175,10 @@ bool source_proc_t::parse(nlparse_t &setup, const pstring &name) return false; } -std::unique_ptr<plib::pistream> source_proc_t::stream(const pstring &name) +plib::unique_ptr<plib::pistream> source_proc_t::stream(const pstring &name) { plib::unused_var(name); - std::unique_ptr<plib::pistream> p(nullptr); + plib::unique_ptr<plib::pistream> p(nullptr); return p; } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 448df3490da..5e445fc6a32 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -180,7 +180,7 @@ namespace netlist DATA }; - using list_t = std::vector<std::unique_ptr<source_t>>; + using list_t = std::vector<plib::unique_ptr<source_t>>; source_t(const type_t type = SOURCE) : m_type(type) @@ -195,7 +195,7 @@ namespace netlist type_t type() const { return m_type; } protected: - virtual std::unique_ptr<plib::pistream> stream(const pstring &name) = 0; + virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) = 0; private: const type_t m_type; @@ -224,7 +224,7 @@ namespace netlist void register_frontier(const pstring &attach, const double r_IN, const double r_OUT); /* register a source */ - void register_source(std::unique_ptr<source_t> &&src) + void register_source(plib::unique_ptr<source_t> &&src) { m_sources.push_back(std::move(src)); } @@ -251,7 +251,7 @@ namespace netlist bool device_exists(const pstring &name) const; /* FIXME: used by source_t - need a different approach at some time */ - bool parse_stream(std::unique_ptr<plib::pistream> &&istrm, const pstring &name); + bool parse_stream(plib::unique_ptr<plib::pistream> &&istrm, const pstring &name); void add_define(pstring def, pstring val) { @@ -328,7 +328,7 @@ namespace netlist void register_dynamic_log_devices(); void resolve_inputs(); - std::unique_ptr<plib::pistream> get_data_stream(const pstring &name); + plib::unique_ptr<plib::pistream> get_data_stream(const pstring &name); factory::list_t &factory() { return m_factory; } @@ -404,7 +404,7 @@ namespace netlist } protected: - std::unique_ptr<plib::pistream> stream(const pstring &name) override; + plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_str; @@ -420,7 +420,7 @@ namespace netlist } protected: - std::unique_ptr<plib::pistream> stream(const pstring &name) override; + plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_filename; @@ -435,7 +435,7 @@ namespace netlist } protected: - std::unique_ptr<plib::pistream> stream(const pstring &name) override; + plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_str; @@ -454,7 +454,7 @@ namespace netlist bool parse(nlparse_t &setup, const pstring &name) override; protected: - std::unique_ptr<plib::pistream> stream(const pstring &name) override; + plib::unique_ptr<plib::pistream> stream(const pstring &name) override; private: void (*m_setup_func)(nlparse_t &); diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index c70aaa392d7..45c19ef7b3a 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -8,45 +8,124 @@ #ifndef PALLOC_H_ #define PALLOC_H_ +#include "pconfig.h" #include "pstring.h" #include "ptypes.h" #include <cstddef> +#include <cstdlib> #include <memory> #include <utility> #include <vector> +#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) +#include <malloc.h> +#endif + namespace plib { //============================================================ // Memory allocation //============================================================ +#if (USE_ALIGNED_OPTIMIZATIONS) + static inline void *paligned_alloc( size_t alignment, size_t size ) + { +#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) + return _aligned_malloc(size, alignment); +#elif defined(__APPLE__) + void* p; + if (::posix_memalign(&p, alignment, size) != 0) { + p = nullptr; + } + return p; +#else + return aligned_alloc(alignment, size); +#endif + } + + static inline void pfree( void *ptr ) + { + free(ptr); + } + + template <typename T, std::size_t ALIGN> + inline C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept + { + return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN)); + } + + template <typename T, std::size_t ALIGN> + inline C14CONSTEXPR const T *assume_aligned_ptr(const T *p) noexcept + { + return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN)); + } +#else + static inline void *paligned_alloc( size_t alignment, size_t size ) + { + unused_var(alignment); + return ::operator new(size); + } + + static inline void pfree( void *ptr ) + { + ::operator delete(ptr); + } + + template <typename T, std::size_t ALIGN> + inline C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept + { + return p; + } + + template <typename T, std::size_t ALIGN> + inline C14CONSTEXPR const T *assume_aligned_ptr(const T *p) noexcept + { + return p; + } +#endif template<typename T, typename... Args> - T *palloc(Args&&... args) + inline T *pnew(Args&&... args) { - return new T(std::forward<Args>(args)...); + auto *p = paligned_alloc(alignof(T), sizeof(T)); + return new(p) T(std::forward<Args>(args)...); } template<typename T> - void pfree(T *ptr) + inline void pdelete(T *ptr) { - delete ptr; + ptr->~T(); + pfree(ptr); } template<typename T> - T* palloc_array(const std::size_t num) + inline T* pnew_array(const std::size_t num) { return new T[num](); } template<typename T> - void pfree_array(T *ptr) + inline void pdelete_array(T *ptr) { delete [] ptr; } - template <typename SC, typename D = std::default_delete<SC>> + template <typename T> + struct pdefault_deleter + { + constexpr pdefault_deleter() noexcept = default; + + template<typename U, typename = typename + std::enable_if<std::is_convertible< U*, T*>::value>::type> + pdefault_deleter(const pdefault_deleter<U>&) noexcept { } + + void operator()(T *p) const + { + pdelete(p); + } + }; + + template <typename SC, typename D = pdefault_deleter<SC>> class owned_ptr { public: @@ -142,19 +221,113 @@ namespace plib { bool m_is_owned; }; + template <typename T> + using unique_ptr = std::unique_ptr<T, pdefault_deleter<T>>; + template<typename T, typename... Args> - std::unique_ptr<T> make_unique(Args&&... args) + plib::unique_ptr<T> make_unique(Args&&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + return plib::unique_ptr<T>(pnew<T>(std::forward<Args>(args)...)); } template<typename T, typename... Args> static owned_ptr<T> make_owned(Args&&... args) { - owned_ptr<T> a(new T(std::forward<Args>(args)...), true); + owned_ptr<T> a(pnew<T>(std::forward<Args>(args)...), true); return std::move(a); } + template <class T, std::size_t ALIGN = alignof(T)> + class aligned_allocator + { + public: + using value_type = T; + + static_assert(ALIGN >= alignof(T) && (ALIGN % alignof(T)) == 0, + "ALIGN must be greater than alignof(T) and a multiple"); + + aligned_allocator() = default; + + aligned_allocator(const aligned_allocator&) = default; + aligned_allocator& operator=(const aligned_allocator&) = delete; + + template <class U> + aligned_allocator(const aligned_allocator<U, ALIGN>& rhs) noexcept + { + unused_var(rhs); + } + + template <class U> struct rebind + { + using other = aligned_allocator<U, ALIGN>; + }; + + T* allocate(std::size_t n) + { + return reinterpret_cast<T *>(paligned_alloc(ALIGN, sizeof(T) * n)); + } + + void deallocate(T* p, std::size_t n) noexcept + { + unused_var(n); + pfree(p); + } + + template <class T1, std::size_t A1, class U, std::size_t A2> + friend bool operator==(const aligned_allocator<T1, A1>& lhs, + const aligned_allocator<U, A2>& rhs) noexcept; + + template <class U, std::size_t A> friend class aligned_allocator; + }; + + template <class T1, std::size_t A1, class U, std::size_t A2> + /*friend*/ inline bool operator==(const aligned_allocator<T1, A1>& lhs, + const aligned_allocator<U, A2>& rhs) noexcept + { + unused_var(lhs, rhs); + return A1 == A2; + } + template <class T1, std::size_t A1, class U, std::size_t A2> + /*friend*/ inline bool operator!=(const aligned_allocator<T1, A1>& lhs, + const aligned_allocator<U, A2>& rhs) noexcept + { + return !(lhs == rhs); + } + + // FIXME: needs to be somewhere else +#if 0 + template <class T, std::size_t ALIGN = alignof(T)> + using aligned_vector = std::vector<T, aligned_allocator<T, alignof(T)>>; + //using aligned_vector = std::vector<T, aligned_allocator<T, ALIGN>>; +#else + template <class T, std::size_t ALIGN = alignof(T)> + class aligned_vector : public std::vector<T, aligned_allocator<T, ALIGN>> + { + public: + using base = std::vector<T, aligned_allocator<T, ALIGN>>; + + using reference = typename base::reference; + using const_reference = typename base::const_reference; + using size_type = typename base::size_type; + + using base::base; + + reference operator[](size_type i) noexcept + { + return assume_aligned_ptr<T, ALIGN>(this->data())[i]; + } + constexpr const_reference operator[](size_type i) const noexcept + { + return assume_aligned_ptr<T, ALIGN>(this->data())[i]; + } + + }; + + +#endif + + + } // namespace plib #endif /* PALLOC_H_ */ diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index 662c2e9550e..e09639163f0 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -10,6 +10,7 @@ #include "pconfig.h" #include "pexception.h" +#include "palloc.h" #include <array> #include <memory> @@ -30,7 +31,7 @@ namespace plib { struct sizeabs<FT, 0> { static constexpr const std::size_t ABS = 0; - using container = typename std::vector<FT> ; + using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>; }; /** @@ -102,11 +103,17 @@ namespace plib { return m_a[i]; } #else - reference operator[](size_type i) noexcept { return m_a[i]; } - constexpr const_reference operator[](size_type i) const noexcept { return m_a[i]; } + reference operator[](size_type i) noexcept + { + return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i]; + } + constexpr const_reference operator[](size_type i) const noexcept + { + return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i]; + } #endif - FT * data() noexcept { return m_a.data(); } - const FT * data() const noexcept { return m_a.data(); } + FT * data() noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); } + const FT * data() const noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); } private: PALIGNAS_VECTOROPT() diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index cc92a42c827..9f61fc0b01f 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -34,11 +34,22 @@ #endif /* + * Set this to one if you want to use aligned storage optimizations. + */ + +#ifndef USE_ALIGNED_OPTIMIZATIONS +#define USE_ALIGNED_OPTIMIZATIONS (0) +#endif + +/* * Standard alignment macros */ -#define PALIGNAS_CACHELINE() PALIGNAS(64) -#define PALIGNAS_VECTOROPT() PALIGNAS(64) +#define PALIGN_CACHELINE (64) +#define PALIGN_VECTOROPT (16) + +#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE) +#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT) /* Breaks mame build on windows due to -Wattribute */ #if defined(_WIN32) && defined(__GNUC__) diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp index f30ddc5d59a..c0c89de208d 100644 --- a/src/lib/netlist/plib/pdynlib.cpp +++ b/src/lib/netlist/plib/pdynlib.cpp @@ -25,7 +25,7 @@ CHAR *astring_from_utf8(const char *utf8string) // convert UTF-16 to "ANSI code page" string char_count = WideCharToMultiByte(CP_ACP, 0, wstring, -1, nullptr, 0, nullptr, nullptr); - result = palloc_array<CHAR>(char_count); + result = pnew_array<CHAR>(char_count); if (result != nullptr) WideCharToMultiByte(CP_ACP, 0, wstring, -1, result, char_count, nullptr, nullptr); @@ -39,7 +39,7 @@ WCHAR *wstring_from_utf8(const char *utf8string) // convert MAME string (UTF-8) to UTF-16 char_count = MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, nullptr, 0); - result = palloc_array<WCHAR>(char_count); + result = pnew_array<WCHAR>(char_count); if (result != nullptr) MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, result, char_count); @@ -72,7 +72,7 @@ dynlib::dynlib(const pstring libname) m_isLoaded = true; //else // fprintf(stderr, "win: library <%s> not found!\n", libname.c_str()); - pfree_array(buffer); + pdelete_array(buffer); #elif defined(EMSCRIPTEN) //no-op #else @@ -106,7 +106,7 @@ dynlib::dynlib(const pstring path, const pstring libname) { //printf("win: library <%s> not found!\n", libname.c_str()); } - pfree_array(buffer); + pdelete_array(buffer); #elif defined(EMSCRIPTEN) //no-op #else diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h index 80e30ada324..c55d66d8847 100644 --- a/src/lib/netlist/plib/pmempool.h +++ b/src/lib/netlist/plib/pmempool.h @@ -34,7 +34,6 @@ namespace plib { void operator()(T *p) const { - p->~T(); P::free(p); } }; @@ -83,7 +82,7 @@ namespace plib { block * new_block(std::size_t min_bytes) { - auto *b = new block(this, min_bytes); + auto *b = plib::pnew<block>(this, min_bytes); m_blocks.push_back(b); return b; } @@ -123,22 +122,27 @@ namespace plib { } } - void *alloc(size_t size, size_t align) + template <std::size_t ALIGN> + void *alloc(size_t size) { + size_t align = ALIGN; if (align < m_min_align) align = m_min_align; - size_t rs = (size + align - 1) & ~(align - 1); + size_t rs = size + align; for (auto &b : m_blocks) { if (b->m_free > rs) { b->m_free -= rs; b->m_num_alloc++; - auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur); + auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur); auto capacity(rs); - std::align(align, size, ret, capacity); + ret = std::align(align, size, ret, capacity); + if (ret == nullptr) + printf("Oh no\n"); sinfo().insert({ ret, info(b, b->m_cur)}); + rs -= (capacity - size); b->m_cur += rs; return ret; @@ -148,17 +152,24 @@ namespace plib { block *b = new_block(rs); b->m_num_alloc = 1; b->m_free = m_min_alloc - rs; - auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur); + auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur); auto capacity(rs); - std::align(align, size, ret, capacity); + ret = std::align(align, size, ret, capacity); + if (ret == nullptr) + printf("Oh no\n"); sinfo().insert({ ret, info(b, b->m_cur)}); + rs -= (capacity - size); b->m_cur += rs; return ret; } } - static void free(void *ptr) + template <typename T> + static void free(T *ptr) { + /* call destructor */ + ptr->~T(); + auto it = sinfo().find(ptr); if (it == sinfo().end()) plib::terminate("mempool::free - pointer not found\n"); @@ -182,7 +193,7 @@ namespace plib { template<typename T, typename... Args> poolptr<T> make_poolptr(Args&&... args) { - auto mem = this->alloc(sizeof(T), alignof(T)); + auto *mem = this->alloc<alignof(T)>(sizeof(T)); auto *obj = new (mem) T(std::forward<Args>(args)...); poolptr<T> a(obj, true); return std::move(a); @@ -208,6 +219,7 @@ namespace plib { ~mempool_default() = default; +#if 0 void *alloc(size_t size) { plib::unused_var(m_min_alloc); // -Wunused-private-field fires without @@ -216,9 +228,11 @@ namespace plib { return ::operator new(size); } - static void free(void *ptr) +#endif + template <typename T> + static void free(T *ptr) { - ::operator delete(ptr); + plib::pdelete(ptr); } template <typename T> @@ -227,12 +241,13 @@ namespace plib { template<typename T, typename... Args> poolptr<T> make_poolptr(Args&&... args) { - auto mem(alloc(sizeof(T))); - auto *obj = new (mem) T(std::forward<Args>(args)...); + plib::unused_var(m_min_alloc); // -Wunused-private-field fires without + plib::unused_var(m_min_align); + + auto *obj = plib::pnew<T>(std::forward<Args>(args)...); poolptr<T> a(obj, true); return std::move(a); } - }; diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index cdb6ea94dc8..d837a6d2931 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -10,6 +10,7 @@ #include "pstring.h" #include "ptypes.h" +#include "palloc.h" #include <array> #include <memory> @@ -63,7 +64,7 @@ public: struct entry_t { - using list_t = std::vector<std::unique_ptr<entry_t>>; + using list_t = std::vector<plib::unique_ptr<entry_t>>; entry_t(const pstring &stname, const datatype_t &dt, const void *owner, const std::size_t count, void *ptr) diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp index f9dd224e92f..8f80f317f98 100644 --- a/src/lib/netlist/plib/pstream.cpp +++ b/src/lib/netlist/plib/pstream.cpp @@ -270,13 +270,13 @@ pimemstream::pos_type pimemstream::vtell() const pomemstream::pomemstream() : postream(FLAG_SEEKABLE), m_pos(0), m_capacity(1024), m_size(0) { - m_mem = palloc_array<char>(m_capacity); + m_mem = pnew_array<char>(m_capacity); } pomemstream::~pomemstream() { if (m_mem != nullptr) - pfree_array(m_mem); + pdelete_array(m_mem); } void pomemstream::vwrite(const value_type *buf, const pos_type n) @@ -286,13 +286,13 @@ void pomemstream::vwrite(const value_type *buf, const pos_type n) while (m_pos + n >= m_capacity) m_capacity *= 2; char *o = m_mem; - m_mem = palloc_array<char>(m_capacity); + m_mem = pnew_array<char>(m_capacity); if (m_mem == nullptr) { throw out_of_mem_e("pomemstream::vwrite"); } std::copy(o, o + m_pos, m_mem); - pfree_array(o); + pdelete_array(o); } std::copy(buf, buf + n, m_mem + m_pos); @@ -309,13 +309,13 @@ void pomemstream::vseek(const pos_type n) while (m_size >= m_capacity) m_capacity *= 2; char *o = m_mem; - m_mem = palloc_array<char>(m_capacity); + m_mem = pnew_array<char>(m_capacity); if (m_mem == nullptr) { throw out_of_mem_e("pomemstream::vseek"); } std::copy(o, o + m_pos, m_mem); - pfree_array(o); + pdelete_array(o); } } diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index 80619137c51..d5b2bfa4809 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -447,7 +447,7 @@ private: template <typename T> struct constructor_helper { - std::unique_ptr<pistream> operator()(T &&s) { return std::move(plib::make_unique<T>(std::move(s))); } + plib::unique_ptr<pistream> operator()(T &&s) { return std::move(plib::make_unique<T>(std::move(s))); } }; // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) @@ -489,20 +489,20 @@ public: } private: - std::unique_ptr<pistream> m_strm; + plib::unique_ptr<pistream> m_strm; putf8string m_linebuf; }; template <> struct constructor_helper<putf8_reader> { - std::unique_ptr<pistream> operator()(putf8_reader &&s) { return std::move(s.m_strm); } + plib::unique_ptr<pistream> operator()(putf8_reader &&s) { return std::move(s.m_strm); } }; template <> -struct constructor_helper<std::unique_ptr<pistream>> +struct constructor_helper<plib::unique_ptr<pistream>> { - std::unique_ptr<pistream> operator()(std::unique_ptr<pistream> &&s) { return std::move(s); } + plib::unique_ptr<pistream> operator()(plib::unique_ptr<pistream> &&s) { return std::move(s); } }; @@ -626,11 +626,11 @@ public: { std::size_t sz = 0; read(sz); - auto buf = plib::palloc_array<plib::string_info<pstring>::mem_t>(sz+1); + auto buf = plib::pnew_array<plib::string_info<pstring>::mem_t>(sz+1); m_strm.read(reinterpret_cast<pistream::value_type *>(buf), sz); buf[sz] = 0; s = pstring(buf); - plib::pfree_array(buf); + plib::pdelete_array(buf); } template <typename T> diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index ea7e1426626..076d004528c 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -126,13 +126,13 @@ public: { } - std::unique_ptr<plib::pistream> stream(const pstring &file) override; + plib::unique_ptr<plib::pistream> stream(const pstring &file) override; private: pstring m_folder; }; -std::unique_ptr<plib::pistream> netlist_data_folder_t::stream(const pstring &file) +plib::unique_ptr<plib::pistream> netlist_data_folder_t::stream(const pstring &file) { pstring name = m_folder + "/" + file; try @@ -145,7 +145,7 @@ std::unique_ptr<plib::pistream> netlist_data_folder_t::stream(const pstring &fil if (dynamic_cast<const plib::file_open_e *>(&e) == nullptr ) throw; } - return std::unique_ptr<plib::pistream>(nullptr); + return plib::unique_ptr<plib::pistream>(nullptr); } class netlist_tool_callbacks_t : public netlist::callbacks_t diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 96cf9342058..24c84c73739 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -166,7 +166,7 @@ public: return success; } - void process(std::vector<std::unique_ptr<plib::pistream>> &is) + void process(std::vector<plib::unique_ptr<plib::pistream>> &is) { std::vector<plib::putf8_reader> readers; for (auto &i : is) @@ -431,7 +431,7 @@ public: private: void convert_wav(); void convert_vcd(vcdwriter::format_e format); - std::vector<std::unique_ptr<plib::pistream>> m_instrms; + std::vector<plib::unique_ptr<plib::pistream>> m_instrms; plib::postream *m_outstrm; }; @@ -440,8 +440,8 @@ void nlwav_app::convert_wav() double dt = 1.0 / static_cast<double>(opt_rate()); - std::unique_ptr<wavwriter> wo = plib::make_unique<wavwriter>(*m_outstrm, m_instrms.size(), opt_rate(), opt_amp()); - std::unique_ptr<aggregator> ago = plib::make_unique<aggregator>(m_instrms.size(), dt, aggregator::callback_type(&wavwriter::process, wo.get())); + plib::unique_ptr<wavwriter> wo = plib::make_unique<wavwriter>(*m_outstrm, m_instrms.size(), opt_rate(), opt_amp()); + plib::unique_ptr<aggregator> ago = plib::make_unique<aggregator>(m_instrms.size(), dt, aggregator::callback_type(&wavwriter::process, wo.get())); aggregator::callback_type agcb = log_processor::callback_type(&aggregator::process, ago.get()); log_processor lp(m_instrms.size(), agcb); @@ -462,7 +462,7 @@ void nlwav_app::convert_wav() void nlwav_app::convert_vcd(vcdwriter::format_e format) { - std::unique_ptr<vcdwriter> wo = plib::make_unique<vcdwriter>(*m_outstrm, opt_args(), + plib::unique_ptr<vcdwriter> wo = plib::make_unique<vcdwriter>(*m_outstrm, opt_args(), format, opt_high(), opt_low()); log_processor::callback_type agcb = log_processor::callback_type(&vcdwriter::process, wo.get()); @@ -510,11 +510,11 @@ int nlwav_app::execute() return 0; } - m_outstrm = (opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opt_out())); + m_outstrm = (opt_out() == "-" ? &pout_strm : plib::pnew<plib::pofilestream>(opt_out())); for (auto &oi: opt_args()) { - std::unique_ptr<plib::pistream> fin = (oi == "-" ? + plib::unique_ptr<plib::pistream> fin = (oi == "-" ? plib::make_unique<plib::pstdin>() : plib::make_unique<plib::pifilestream>(oi)); m_instrms.push_back(std::move(fin)); @@ -534,7 +534,7 @@ int nlwav_app::execute() } if (opt_out() != "-") - plib::pfree(m_outstrm); + plib::pdelete(m_outstrm); return 0; } diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 36c8f2fb551..951733874fd 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -336,9 +336,9 @@ void matrix_solver_t::setup_matrix() * This should reduce cache misses ... */ - auto **touched = plib::palloc_array<bool *>(iN); + auto **touched = plib::pnew_array<bool *>(iN); for (std::size_t k=0; k<iN; k++) - touched[k] = plib::palloc_array<bool>(iN); + touched[k] = plib::pnew_array<bool>(iN); for (std::size_t k = 0; k < iN; k++) { @@ -397,8 +397,8 @@ void matrix_solver_t::setup_matrix() } for (std::size_t k=0; k<iN; k++) - plib::pfree_array(touched[k]); - plib::pfree_array(touched); + plib::pdelete_array(touched[k]); + plib::pdelete_array(touched); } void matrix_solver_t::update_inputs() diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 803437d76e2..e5404290de0 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -10,6 +10,7 @@ #include "netlist/nl_base.h" #include "netlist/nl_errstr.h" +#include "netlist/plib/palloc.h" #include "netlist/plib/putil.h" #include "netlist/plib/vector_ops.h" @@ -103,9 +104,6 @@ public: std::vector<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */ std::vector<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */ - - - /* state */ nl_double m_last_V; nl_double m_DD_n_m_1; @@ -113,10 +111,10 @@ public: private: std::vector<int> m_connected_net_idx; - std::vector<nl_double> m_go; - std::vector<nl_double> m_gt; - std::vector<nl_double> m_Idr; - std::vector<nl_double *> m_connected_net_V; + plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_go; + plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_gt; + plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_Idr; + plib::aligned_vector<nl_double *, PALIGN_VECTOROPT> m_connected_net_V; std::vector<terminal_t *> m_terms; }; @@ -218,11 +216,11 @@ protected: template <typename T> void build_LE_RHS(T &child); - std::vector<std::unique_ptr<terms_for_net_t>> m_terms; + std::vector<plib::unique_ptr<terms_for_net_t>> m_terms; std::vector<analog_net_t *> m_nets; std::vector<poolptr<proxied_analog_output_t>> m_inps; - std::vector<std::unique_ptr<terms_for_net_t>> m_rails_temp; + std::vector<plib::unique_ptr<terms_for_net_t>> m_rails_temp; const solver_parameters_t &m_params; diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 8d1351435c8..d2caa944434 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -65,7 +65,8 @@ private: plib::parray<FT, SIZE> RHS; plib::parray<FT, SIZE> new_V; - std::array<std::vector<FT *>, storage_N> m_term_cr; + std::array<plib::aligned_vector<FT *, PALIGN_VECTOROPT>, storage_N> m_term_cr; +// std::array<std::vector<FT *>, storage_N> m_term_cr; mat_type mat; diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 3cd88dea429..dcb3726f5f2 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -51,7 +51,7 @@ namespace devices using mattype = typename plib::matrix_compressed_rows_t<FT, SIZE>::index_type; - plib::parray<std::vector<FT *>, SIZE> m_term_cr; + plib::parray<plib::aligned_vector<FT *, PALIGN_VECTOROPT>, SIZE> m_term_cr; plib::mat_precondition_ILU<FT, SIZE> m_ops; //plib::mat_precondition_diag<FT, SIZE> m_ops; plib::gmres_t<FT, SIZE> m_gmres; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 6ce9a093c84..44d51793690 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -175,6 +175,25 @@ poolptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(std::size_t size, co } } +template <typename FT, int SIZE> +poolptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver_x(std::size_t size, const pstring &solvername) +{ + if (SIZE > 0) + { + if (size == SIZE) + return create_solver<FT, SIZE>(size, solvername); + else + return this->create_solver_x<FT, SIZE-1>(size, solvername); + } + else + { + if (size * 2 > -SIZE ) + return create_solver<FT, SIZE>(size, solvername); + else + return this->create_solver_x<FT, SIZE / 2>(size, solvername); + } +}; + struct net_splitter { @@ -230,9 +249,6 @@ struct net_splitter void NETLIB_NAME(solver)::post_start() { - const bool use_specific = true; - plib::unused_var(use_specific); - m_params.m_pivot = m_pivot(); m_params.m_accuracy = m_accuracy(); /* FIXME: Throw when negative */ @@ -283,18 +299,11 @@ void NETLIB_NAME(solver)::post_start() { #if 1 case 1: - if (use_specific) - ms = pool().make_poolptr<matrix_solver_direct1_t<double>>(state(), sname, &m_params); - else - ms = create_solver<double, 1>(1, sname); + ms = pool().make_poolptr<matrix_solver_direct1_t<double>>(state(), sname, &m_params); break; case 2: - if (use_specific) - ms = pool().make_poolptr<matrix_solver_direct2_t<double>>(state(), sname, &m_params); - else - ms = create_solver<double, 2>(2, sname); + ms = pool().make_poolptr<matrix_solver_direct2_t<double>>(state(), sname, &m_params); break; -#if 1 case 3: ms = create_solver<double, 3>(3, sname); break; @@ -319,6 +328,7 @@ void NETLIB_NAME(solver)::post_start() case 10: ms = create_solver<double, 10>(10, sname); break; +#if 0 case 11: ms = create_solver<double, 11>(11, sname); break; @@ -341,7 +351,7 @@ void NETLIB_NAME(solver)::post_start() ms = create_solver<double, 49>(49, sname); break; #endif -#if 0 +#if 1 case 86: ms = create_solver<double,86>(86, sname); break; diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 247abc9097b..c4a9eba6971 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -105,6 +105,9 @@ private: template <typename FT, int SIZE> poolptr<matrix_solver_t> create_solver(std::size_t size, const pstring &solvername); + + template <typename FT, int SIZE> + poolptr<matrix_solver_t> create_solver_x(std::size_t size, const pstring &solvername); }; } //namespace devices diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index 95e05d27857..f4616cb7774 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -81,7 +81,7 @@ void nl_convert_base_t::add_ext_alias(const pstring &alias) m_ext_alias.push_back(alias); } -void nl_convert_base_t::add_device(std::unique_ptr<dev_t> dev) +void nl_convert_base_t::add_device(plib::unique_ptr<dev_t> dev) { for (auto & d : m_devs) if (d->name() == dev->name()) diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h index 7dd0e56c5ee..73c98301af5 100644 --- a/src/lib/netlist/tools/nl_convert.h +++ b/src/lib/netlist/tools/nl_convert.h @@ -124,14 +124,14 @@ private: private: - void add_device(std::unique_ptr<dev_t> dev); + void add_device(plib::unique_ptr<dev_t> dev); plib::postringstream m_buf; - std::vector<std::unique_ptr<dev_t>> m_devs; - std::unordered_map<pstring, std::unique_ptr<net_t> > m_nets; + std::vector<plib::unique_ptr<dev_t>> m_devs; + std::unordered_map<pstring, plib::unique_ptr<net_t> > m_nets; std::vector<pstring> m_ext_alias; - std::unordered_map<pstring, std::unique_ptr<pin_alias_t>> m_pins; + std::unordered_map<pstring, plib::unique_ptr<pin_alias_t>> m_pins; static unit_t m_units[]; pstring m_numberchars; |