diff options
-rw-r--r-- | scripts/src/netlist.lua | 2 | ||||
-rw-r--r-- | src/lib/netlist/build/makefile | 24 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_9316_base.hxx | 3 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_truthtable.cpp | 3 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 13 | ||||
-rw-r--r-- | src/lib/netlist/nl_factory.h | 3 | ||||
-rwxr-xr-x | src/lib/netlist/nl_setup.cpp | 6 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pconfig.h | 35 | ||||
-rw-r--r-- | src/lib/netlist/plib/plists.h | 336 | ||||
-rw-r--r-- | src/lib/netlist/plib/pmulti_threading.h | 44 | ||||
-rwxr-xr-x | src/lib/netlist/plib/poptions.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/ppreprocessor.cpp | 12 | ||||
-rw-r--r-- | src/lib/netlist/plib/ppreprocessor.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstring.cpp | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptimed_queue.h | 343 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptokenizer.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/putil.cpp | 1 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 2 | ||||
-rwxr-xr-x | src/lib/netlist/prg/nlwav.cpp | 7 | ||||
-rwxr-xr-x | src/lib/netlist/tools/nl_convert.h | 1 |
21 files changed, 453 insertions, 388 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua index e3e79c55817..49d8371a1c4 100644 --- a/scripts/src/netlist.lua +++ b/scripts/src/netlist.lua @@ -66,6 +66,7 @@ project "netlist" MAME_DIR .. "src/lib/netlist/plib/pmain.h", MAME_DIR .. "src/lib/netlist/plib/pmath.h", MAME_DIR .. "src/lib/netlist/plib/pmempool.h", + MAME_DIR .. "src/lib/netlist/plib/pmulti_threading.h", MAME_DIR .. "src/lib/netlist/plib/pomp.h", MAME_DIR .. "src/lib/netlist/plib/poptions.cpp", MAME_DIR .. "src/lib/netlist/plib/poptions.h", @@ -80,6 +81,7 @@ project "netlist" MAME_DIR .. "src/lib/netlist/plib/pstrutil.h", MAME_DIR .. "src/lib/netlist/plib/pstream.h", MAME_DIR .. "src/lib/netlist/plib/ptime.h", + MAME_DIR .. "src/lib/netlist/plib/ptimed_queue.h", MAME_DIR .. "src/lib/netlist/plib/ptokenizer.cpp", MAME_DIR .. "src/lib/netlist/plib/ptokenizer.h", MAME_DIR .. "src/lib/netlist/plib/ptypes.h", diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 924bba5609d..3762d14d2e1 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -232,7 +232,7 @@ ALL_TIDY_FILES = $(ALL_OBJS:.o=.json) SOURCES = $(patsubst $(OBJ)%, $(SRC)%, $(ALL_OBJS:.o=.cpp)) ALLFILES = $(SOURCES) $(VSBUILDS) $(DOCS) -MAKEFILE_TARGETS_WITHOUT_INCLUDE := clean doc clang mingw nvcc +MAKEFILE_TARGETS_WITHOUT_INCLUDE := clean doc clang mingw nvcc clang-libc # git archive HEAD --prefix=project-name-version/ \ @@ -242,7 +242,7 @@ MAKEFILE_TARGETS_WITHOUT_INCLUDE := clean doc clang mingw nvcc # PHONY #------------------------------------------------- -.PHONY: clang clang-5 mingw doc native maketree depend $(DEPEND) +.PHONY: clang clang-5 mingw doc native maketree $(DEPEND) depend #------------------------------------------------- # all @@ -287,7 +287,7 @@ native: $(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra " gcc9: - $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -finline-limit=100 -fext-numeric-literals -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra " EXTRALIBS="-lquadmath" + $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -finline-limit=100 -fpermissive -fext-numeric-literals -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra " EXTRALIBS="-lquadmath" clang: #$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors" @@ -299,13 +299,25 @@ clang: -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral \ -Wno-exit-time-destructors -Winconsistent-missing-destructor-override" +clang-libc: + #$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors" + $(MAKE) CC=clang++-libc++ LD=clang++-libc++ OBJ=obj/clang-libc CEXTRAFLAGS="-march=native \ + -mllvm -inline-threshold=2000 \ + -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field \ + -Werror -Wno-padded -Wno-weak-vtables -Wno-weak-template-vtables -Wno-unused-template \ + -Wno-missing-variable-declarations -Wno-float-equal -Wconversion \ + -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral \ + -Wno-exit-time-destructors -Winconsistent-missing-destructor-override" + clang-5: $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" nvcc: - $(MAKE) CC=/usr/local/cuda-9.0/bin/nvcc LD=/usr/local/cuda-9.2/bin/nvcc \ - OBJ=obj/nvcc CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda \ - --expt-relaxed-constexpr --default-stream per-thread --restrict" \ + $(MAKE) CC=/usr/local/cuda-10.2/bin/nvcc LD=/usr/local/cuda-10.2/bin/nvcc \ + OBJ=obj/nvcc CEXTRAFLAGS="--std c++14 -x cu -DNVCCBUILD=102 --expt-extended-lambda \ + --expt-relaxed-constexpr --default-stream per-thread --restrict \ + --ftemplate-depth 1024 \ + -Xcompiler -O6 -Xcompiler -march=native -ccbin g++-8 " \ DEPENDCC=g++ tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix diff --git a/src/lib/netlist/devices/nld_9316_base.hxx b/src/lib/netlist/devices/nld_9316_base.hxx index 8f0b0b9ee99..0f6d22dd79b 100644 --- a/src/lib/netlist/devices/nld_9316_base.hxx +++ b/src/lib/netlist/devices/nld_9316_base.hxx @@ -63,7 +63,7 @@ namespace netlist if (D::ASYNC::value && !CLRQ && (m_cnt>0)) { m_cnt = 0; - m_Q.push(m_cnt, D::tCLR::value(0)); + m_Q.push(0, D::tCLR::value(0)); } } m_RC.push(m_ent && (m_cnt == D::MAXCNT::value), D::tRC::value(0)); @@ -78,7 +78,6 @@ namespace netlist } else { - //const auto cnt = (m_loadq ? (m_cnt + 1) & D::MAXCNT::value : m_abcd); const auto cnt = (m_loadq ? rollover<D::MAXCNT::value>(m_cnt + 1) : m_abcd); m_RC.push(m_ent && (cnt == D::MAXCNT::value), D::tRC::value(0)); m_Q.push(cnt, D::tLDCNT::value(0)); diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 094517d2c73..ea29be363ce 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -52,6 +52,7 @@ namespace devices init(desc); } + private: void init(const std::vector<pstring> &desc); NETLIB_RESETI() @@ -109,8 +110,6 @@ namespace devices m_ign = (1<<m_NI)-1; } - protected: - private: template<bool doOUT> diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index f61c7007941..857f1be10e3 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -24,6 +24,7 @@ #include "plib/pstonum.h" #include "plib/pstream.h" #include "plib/ptime.h" +#include "plib/ptimed_queue.h" #include "plib/ptypes.h" #include "nl_errstr.h" @@ -748,15 +749,15 @@ namespace netlist } void push_to_queue(const netlist_time &delay) noexcept; - constexpr bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; } + NVCC_CONSTEXPR bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; } template <bool KEEP_STATS> - void update_devs() noexcept; + inline void update_devs() noexcept; netlist_time_ext next_scheduled_time() const noexcept { return m_next_scheduled_time; } void set_next_scheduled_time(netlist_time_ext ntime) noexcept { m_next_scheduled_time = ntime; } - constexpr bool is_rail_net() const noexcept { return !(m_railterminal == nullptr); } + NVCC_CONSTEXPR bool is_rail_net() const noexcept { return !(m_railterminal == nullptr); } core_terminal_t & railterminal() const noexcept { return *m_railterminal; } bool has_connections() const noexcept { return !m_core_terms.empty(); } @@ -785,7 +786,7 @@ namespace netlist protected: // only used for logic nets - constexpr netlist_sig_t Q() const noexcept { return m_cur_Q; } + NVCC_CONSTEXPR netlist_sig_t Q() const noexcept { return m_cur_Q; } // only used for logic nets void initial(netlist_sig_t val) noexcept @@ -1368,7 +1369,7 @@ namespace netlist param_rom_t(core_device_t &device, const pstring &name); - ST operator[] (std::size_t n) const noexcept { return m_data[n]; } + const ST & operator[] (std::size_t n) const noexcept { return m_data[n]; } protected: void changed() noexcept override { @@ -2372,7 +2373,7 @@ namespace netlist for (auto &p : m_list_active) { p.set_copied_input(sig); - if ((p.terminal_state() & mask)) + if ((p.terminal_state() & mask) != 0) p.run_delegate(); } } diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index 32c80b55ed0..15b15470180 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -12,7 +12,6 @@ #include "plib/palloc.h" #include "plib/ptypes.h" #include "plib/putil.h" -#include "plib/penum.h" #include <vector> @@ -30,7 +29,7 @@ () \ { \ using devtype = factory::device_element_t<ns :: NETLIB_NAME(chip)>; \ - auto sl(factory::properties(p_def_param, PSOURCELOC())); \ + factory::properties sl(p_def_param, PSOURCELOC()); \ return devtype::create(p_name, std::move(sl)); \ } \ \ diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index fc34942e734..9b0bc5f4340 100755 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -105,7 +105,7 @@ namespace netlist { if (ptok == ptok_end) { - auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size())); + auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()); log().fatal(err); throw nl_exception(err); //break; @@ -127,7 +127,7 @@ namespace netlist { if (ptok == params_and_connections.end()) { - auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size())); + auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()); log().fatal(err); throw nl_exception(err); } @@ -142,7 +142,7 @@ namespace netlist } if (ptok != params_and_connections.end()) { - auto err(MF_PARAM_COUNT_EXCEEDED_2(name, params_and_connections.size())); + MF_PARAM_COUNT_EXCEEDED_2 err(name, params_and_connections.size()); log().fatal(err); throw nl_exception(err); } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index f1a79be5f30..5ca6233e8fa 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -116,7 +116,7 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \ desc.ni = in; \ desc.no = out; \ desc.family = ""; \ - auto props(netlist::factory::properties(def_params, PSOURCELOC())); + netlist::factory::properties props(def_params, PSOURCELOC()); #define TT_HEAD(x) \ desc.desc.emplace_back(x); diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index a40120cc7f5..06e48ef9930 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -113,20 +113,29 @@ //============================================================ -#if NVCCBUILD -#define C14CONSTEXPR +#ifdef NVCCBUILD + #define C14CONSTEXPR constexpr + #if NVCCBUILD == 101 + #define NVCC_CONSTEXPR constexpr + #else + #define NVCC_CONSTEXPR constexpr + #endif + #if __cplusplus != 201402L + #error nvcc - something is wrong + #endif #else -#if __cplusplus == 201103L -#define C14CONSTEXPR -#elif __cplusplus == 201402L -#define C14CONSTEXPR constexpr -#elif __cplusplus == 201703L -#define C14CONSTEXPR constexpr -#elif defined(_MSC_VER) -#define C14CONSTEXPR -#else -#error "C++ version not supported" -#endif + #define NVCC_CONSTEXPR constexpr + #if __cplusplus == 201103L + #define C14CONSTEXPR + #elif __cplusplus == 201402L + #define C14CONSTEXPR constexpr + #elif __cplusplus == 201703L + #define C14CONSTEXPR constexpr + #elif defined(_MSC_VER) + #define C14CONSTEXPR + #else + #error "C++ version not supported" + #endif #endif #if (PHAS_INT128) diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 515ea6aae5a..c570f61e954 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -14,11 +14,8 @@ #include <algorithm> #include <array> -#include <atomic> -#include <mutex> #include <type_traits> #include <utility> -#include <vector> namespace plib { @@ -221,339 +218,6 @@ namespace plib { LC *m_head; }; - // ---------------------------------------------------------------------------------------- - // FIXME: Move elsewhere - // ---------------------------------------------------------------------------------------- - - template<bool enabled_ = true> - class pspin_mutex - { - public: - pspin_mutex() noexcept = default; - void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } } - void unlock() noexcept { m_lock.clear(std::memory_order_release); } - private: - PALIGNAS_CACHELINE() - std::atomic_flag m_lock = ATOMIC_FLAG_INIT; - }; - - template<> - class pspin_mutex<false> - { - public: - void lock() const noexcept { } - void unlock() const noexcept { } - }; - - // ---------------------------------------------------------------------------------------- - // timed queue - // ---------------------------------------------------------------------------------------- - - - // Note: Don't even try the following approach for element: - // - // template <typename Time, typename Element> - // struct pqentry_t : public std::pair<Time, Element> - // - // This degrades performance significantly. - - template <typename Time, typename Element> - struct pqentry_t final - { - constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { } - constexpr pqentry_t(Time t, Element o) noexcept : m_exec_time(t), m_object(o) { } - - PCOPYASSIGNMOVE(pqentry_t, default) - - ~pqentry_t() = default; - - constexpr bool operator ==(const pqentry_t &rhs) const noexcept - { - return m_object == rhs.m_object; - } - - constexpr bool operator ==(const Element &rhs) const noexcept - { - return m_object == rhs; - } - - constexpr bool operator <=(const pqentry_t &rhs) const noexcept - { - return (m_exec_time <= rhs.m_exec_time); - } - - constexpr bool operator <(const pqentry_t &rhs) const noexcept - { - return (m_exec_time < rhs.m_exec_time); - } - - static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); } - - constexpr Time exec_time() const noexcept { return m_exec_time; } - constexpr Element object() const noexcept { return m_object; } - private: - Time m_exec_time; - Element m_object; - }; - - // Use TS = true for a threadsafe queue - template <class T, bool TS> - class timed_queue_linear - { - public: - - explicit timed_queue_linear(const std::size_t list_size) - : m_list(list_size) - { - clear(); - } - ~timed_queue_linear() = default; - - PCOPYASSIGNMOVE(timed_queue_linear, delete) - - std::size_t capacity() const noexcept { return m_list.capacity() - 1; } - bool empty() const noexcept { return (m_end == &m_list[1]); } - - template<bool KEEPSTAT, typename... Args> - void emplace(Args&&... args) noexcept - { - // Lock - lock_guard_type lck(m_lock); - T * i(m_end++); - *i = T(std::forward<Args>(args)...); - for (; *(i-1) < *i; --i) - { - std::swap(*(i-1), *(i)); - if (KEEPSTAT) - m_prof_sortmove.inc(); - } - if (KEEPSTAT) - m_prof_call.inc(); - } - - template<bool KEEPSTAT> - void push(T && e) noexcept - { -#if 0 - // Lock - lock_guard_type lck(m_lock); - T * i(m_end-1); - for (; *i < e; --i) - { - *(i+1) = *(i); - if (KEEPSTAT) - m_prof_sortmove.inc(); - } - *(i+1) = std::move(e); - ++m_end; -#else - // Lock - lock_guard_type lck(m_lock); - T * i(m_end++); - *i = std::move(e); - for (; *(i-1) < *i; --i) - { - std::swap(*(i-1), *(i)); - if (KEEPSTAT) - m_prof_sortmove.inc(); - } -#endif - if (KEEPSTAT) - m_prof_call.inc(); - } - - void pop() noexcept { --m_end; } - const T &top() const noexcept { return *(m_end-1); } - - template <bool KEEPSTAT, class R> - void remove(const R &elem) noexcept - { - // Lock - lock_guard_type lck(m_lock); - if (KEEPSTAT) - m_prof_remove.inc(); - for (T * i = m_end - 1; i > &m_list[0]; --i) - { - // == operator ignores time! - if (*i == elem) - { - std::copy(i+1, m_end--, i); - return; - } - } - } - - template <bool KEEPSTAT, class R> - void retime(R && elem) noexcept - { - // Lock - lock_guard_type lck(m_lock); - if (KEEPSTAT) - m_prof_retime.inc(); - - for (R * i = m_end - 1; i > &m_list[0]; --i) - { - if (*i == elem) // partial equal! - { - *i = std::forward<R>(elem); - while (*(i-1) < *i) - { - std::swap(*(i-1), *i); - --i; - } - while (i < m_end && *i < *(i+1)) - { - std::swap(*(i+1), *i); - ++i; - } - return; - } - } - } - - void clear() noexcept - { - lock_guard_type lck(m_lock); - m_end = &m_list[0]; - // put an empty element with maximum time into the queue. - // the insert algo above will run into this element and doesn't - // need a comparison with queue start. - // - m_list[0] = T::never(); - m_end++; - } - - // save state support & mame disasm - - const T *listptr() const noexcept { return &m_list[1]; } - std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); } - const T & operator[](std::size_t index) const noexcept { return m_list[ 1 + index]; } - private: - using mutex_type = pspin_mutex<TS>; - using lock_guard_type = std::lock_guard<mutex_type>; - - mutex_type m_lock; - PALIGNAS_CACHELINE() - T * m_end; - aligned_vector<T> m_list; - - public: - // profiling - // FIXME: Make those private - pperfcount_t<true> m_prof_sortmove; // NOLINT - pperfcount_t<true> m_prof_call; // NOLINT - pperfcount_t<true> m_prof_remove; // NOLINT - pperfcount_t<true> m_prof_retime; // NOLINT - }; - - template <class T, bool TS> - class timed_queue_heap - { - public: - - struct compare - { - constexpr bool operator()(const T &a, const T &b) const { return b <= a; } - }; - - explicit timed_queue_heap(const std::size_t list_size) - : m_list(list_size) - { - clear(); - } - ~timed_queue_heap() = default; - - PCOPYASSIGNMOVE(timed_queue_heap, delete) - - std::size_t capacity() const noexcept { return m_list.capacity(); } - bool empty() const noexcept { return &m_list[0] == m_end; } - - template <bool KEEPSTAT> - void push(T &&e) noexcept - { - // Lock - lock_guard_type lck(m_lock); - *m_end++ = e; - std::push_heap(&m_list[0], m_end, compare()); - if (KEEPSTAT) - m_prof_call.inc(); - } - - T pop() noexcept - { - T ret(m_list[0]); - std::pop_heap(&m_list[0], m_end, compare()); - m_end--; - return ret; - } - - const T &top() const noexcept { return m_list[0]; } - - template <bool KEEPSTAT, class R> - void remove(const R &elem) noexcept - { - // Lock - lock_guard_type lck(m_lock); - if (KEEPSTAT) - m_prof_remove.inc(); - for (T * i = m_end - 1; i >= &m_list[0]; i--) - { - if (*i == elem) - { - m_end--; - *i = *m_end; - std::make_heap(&m_list[0], m_end, compare()); - return; - } - } - } - - template <bool KEEPSTAT> - void retime(const T &elem) noexcept - { - // Lock - lock_guard_type lck(m_lock); - if (KEEPSTAT) - m_prof_retime.inc(); - for (T * i = m_end - 1; i >= &m_list[0]; i--) - { - if (*i == elem) // partial equal! - { - *i = elem; - std::make_heap(&m_list[0], m_end, compare()); - return; - } - } - } - - void clear() - { - lock_guard_type lck(m_lock); - m_list.clear(); - m_end = &m_list[0]; - } - - // save state support & mame disasm - - constexpr const T *listptr() const { return &m_list[0]; } - constexpr std::size_t size() const noexcept { return m_list.size(); } - constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; } - private: - using mutex_type = pspin_mutex<TS>; - using lock_guard_type = std::lock_guard<mutex_type>; - - mutex_type m_lock; - std::vector<T> m_list; - T *m_end; - - public: - // profiling - pperfcount_t<true> m_prof_sortmove; // NOLINT - pperfcount_t<true> m_prof_call; // NOLINT - pperfcount_t<true> m_prof_remove; // NOLINT - pperfcount_t<true> m_prof_retime; // NOLINT - }; - } // namespace plib #endif // PLISTS_H_ diff --git a/src/lib/netlist/plib/pmulti_threading.h b/src/lib/netlist/plib/pmulti_threading.h new file mode 100644 index 00000000000..a7dbdd33f13 --- /dev/null +++ b/src/lib/netlist/plib/pmulti_threading.h @@ -0,0 +1,44 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +#ifndef PMULTI_THREADING_H_ +#define PMULTI_THREADING_H_ + +/// +/// \file pmulti_threading.h +/// + +#include "pconfig.h" + +#include <algorithm> +#include <atomic> +#include <mutex> +#include <type_traits> +#include <utility> + +namespace plib { + + template<bool enabled_ = true> + struct pspin_mutex + { + public: + pspin_mutex() noexcept = default; + void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } } + void unlock() noexcept { m_lock.clear(std::memory_order_release); } + private: + PALIGNAS_CACHELINE() + std::atomic_flag m_lock = ATOMIC_FLAG_INIT; + }; + + template<> + struct pspin_mutex<false> + { + public: + void lock() const noexcept { } + void unlock() const noexcept { } + }; + + +} // namespace plib + +#endif // PMULTI_THREADING_H_ diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 2db0e7e9585..b960b45acb9 100755 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -8,7 +8,6 @@ /// \file poptions.h /// -#include "plists.h" #include "pstonum.h" #include "pstring.h" #include "putil.h" diff --git a/src/lib/netlist/plib/ppreprocessor.cpp b/src/lib/netlist/plib/ppreprocessor.cpp index 177599da924..61baadbb608 100644 --- a/src/lib/netlist/plib/ppreprocessor.cpp +++ b/src/lib/netlist/plib/ppreprocessor.cpp @@ -298,7 +298,7 @@ namespace plib { do { repeat = false; - auto elems(simple_iter<ppreprocessor>(this, tokenize(tmpret, m_expr_sep, false, true))); + simple_iter<ppreprocessor> elems(this, tokenize(tmpret, m_expr_sep, false, true)); tmpret = ""; while (!elems.eod()) { @@ -342,7 +342,7 @@ namespace plib { repeat = true; if (def->m_params.size() != rep.size()) error(pfmt("Expected {1} parameters, got {2}")(def->m_params.size(), rep.size())); - auto r(simple_iter<ppreprocessor>(this, tokenize(def->m_replace, m_expr_sep, false, false))); + simple_iter<ppreprocessor> r(this, tokenize(def->m_replace, m_expr_sep, false, false)); bool stringify_next = false; while (!r.eod()) { @@ -460,7 +460,7 @@ namespace plib { { m_if_level++; lt = replace_macros(lt); - auto t(simple_iter<ppreprocessor>(this, tokenize(lt.substr(3), m_expr_sep, true, true))); + simple_iter<ppreprocessor> t(this, tokenize(lt.substr(3), m_expr_sep, true, true)); auto val = static_cast<int>(prepro_expr(t, 255)); t.skip_ws(); if (!t.eod()) @@ -488,7 +488,7 @@ namespace plib { { m_if_flag ^= (1 << m_if_level); lt = replace_macros(lt); - auto t(simple_iter<ppreprocessor>(this, tokenize(lt.substr(5), m_expr_sep, true, true))); + simple_iter<ppreprocessor> t(this, tokenize(lt.substr(5), m_expr_sep, true, true)); auto val = static_cast<int>(prepro_expr(t, 255)); t.skip_ws(); if (!t.eod()) @@ -552,7 +552,7 @@ namespace plib { { if (lti.size() < 2) error("define needs at least one argument"); - auto args(simple_iter<ppreprocessor>(this, tokenize(lt.substr(8), m_expr_sep, false, false))); + simple_iter<ppreprocessor> args(this, tokenize(lt.substr(8), m_expr_sep, false, false)); pstring n = args.next(); if (!is_valid_token(n)) error("define expected identifier"); @@ -604,7 +604,7 @@ namespace plib { { if (lti.size() < 2) error("undef needs at least one argument"); - auto args(simple_iter<ppreprocessor>(this, tokenize(lt.substr(7), m_expr_sep, false, false))); + simple_iter<ppreprocessor> args(this, tokenize(lt.substr(7), m_expr_sep, false, false)); pstring n = args.next(); if (!is_valid_token(n)) error("undef expected identifier"); diff --git a/src/lib/netlist/plib/ppreprocessor.h b/src/lib/netlist/plib/ppreprocessor.h index af0a304bc00..e88fff0c13a 100644 --- a/src/lib/netlist/plib/ppreprocessor.h +++ b/src/lib/netlist/plib/ppreprocessor.h @@ -8,7 +8,6 @@ /// \file ppreprocessor.h /// -#include "plists.h" #include "pstream.h" #include "pstring.h" diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp index a7b18cd7e17..04c2adf4351 100644 --- a/src/lib/netlist/plib/pstring.cpp +++ b/src/lib/netlist/plib/pstring.cpp @@ -3,7 +3,6 @@ #include "pstring.h" #include "palloc.h" -#include "plists.h" #include <algorithm> #include <atomic> diff --git a/src/lib/netlist/plib/ptimed_queue.h b/src/lib/netlist/plib/ptimed_queue.h new file mode 100644 index 00000000000..a3fb6df6d82 --- /dev/null +++ b/src/lib/netlist/plib/ptimed_queue.h @@ -0,0 +1,343 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +#ifndef PTIMED_QUEUE_H_ +#define PTIMED_QUEUE_H_ + +/// +/// \file ptimed_queue.h +/// + +#include "palloc.h" +#include "pchrono.h" +#include "pstring.h" +#include "pmulti_threading.h" + +#include <algorithm> +#include <mutex> +#include <type_traits> +#include <utility> +#include <vector> + +namespace plib { + + // ---------------------------------------------------------------------------------------- + // timed queue + // ---------------------------------------------------------------------------------------- + + // Note: Don't even try the following approach for element: + // + // template <typename Time, typename Element> + // struct pqentry_t : public std::pair<Time, Element> + // + // This degrades performance significantly. + + template <typename Time, typename Element> + struct pqentry_t final + { + constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { } + constexpr pqentry_t(Time t, Element o) noexcept : m_exec_time(t), m_object(o) { } + + PCOPYASSIGNMOVE(pqentry_t, default) + + ~pqentry_t() = default; + + constexpr bool operator ==(const pqentry_t &rhs) const noexcept + { + return m_object == rhs.m_object; + } + + constexpr bool operator ==(const Element &rhs) const noexcept + { + return m_object == rhs; + } + + constexpr bool operator <=(const pqentry_t &rhs) const noexcept + { + return (m_exec_time <= rhs.m_exec_time); + } + + constexpr bool operator <(const pqentry_t &rhs) const noexcept + { + return (m_exec_time < rhs.m_exec_time); + } + + static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); } + + constexpr Time exec_time() const noexcept { return m_exec_time; } + constexpr Element object() const noexcept { return m_object; } + private: + Time m_exec_time; + Element m_object; + }; + + // Use TS = true for a threadsafe queue + template <class T, bool TS> + class timed_queue_linear + { + public: + + explicit timed_queue_linear(const std::size_t list_size) + : m_list(list_size) + { + clear(); + } + ~timed_queue_linear() = default; + + PCOPYASSIGNMOVE(timed_queue_linear, delete) + + std::size_t capacity() const noexcept { return m_list.capacity() - 1; } + bool empty() const noexcept { return (m_end == &m_list[1]); } + + template<bool KEEPSTAT, typename... Args> + void emplace(Args&&... args) noexcept + { + // Lock + lock_guard_type lck(m_lock); + T * i(m_end++); + *i = T(std::forward<Args>(args)...); + + if (!KEEPSTAT) + { + for (; *(i-1) < *i; --i) + { + std::swap(*(i-1), *(i)); + } + } + else + { + for (; *(i-1) < *i; --i) + { + std::swap(*(i-1), *(i)); + m_prof_sortmove.inc(); + } + m_prof_call.inc(); + } + } + + template<bool KEEPSTAT> + void push(T && e) noexcept + { +#if 0 + // Lock + lock_guard_type lck(m_lock); + T * i(m_end-1); + for (; *i < e; --i) + { + *(i+1) = *(i); + if (KEEPSTAT) + m_prof_sortmove.inc(); + } + *(i+1) = std::move(e); + ++m_end; +#else + // Lock + lock_guard_type lck(m_lock); + T * i(m_end++); + *i = std::move(e); + for (; *(i-1) < *i; --i) + { + std::swap(*(i-1), *(i)); + if (KEEPSTAT) + m_prof_sortmove.inc(); + } +#endif + if (KEEPSTAT) + m_prof_call.inc(); + } + + void pop() noexcept { --m_end; } + const T &top() const noexcept { return *(m_end-1); } + + template <bool KEEPSTAT, class R> + void remove(const R &elem) noexcept + { + // Lock + lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_remove.inc(); + for (T * i = m_end - 1; i > &m_list[0]; --i) + { + // == operator ignores time! + if (*i == elem) + { + std::copy(i+1, m_end--, i); + return; + } + } + } + + template <bool KEEPSTAT, class R> + void retime(R && elem) noexcept + { + // Lock + lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_retime.inc(); + + for (R * i = m_end - 1; i > &m_list[0]; --i) + { + if (*i == elem) // partial equal! + { + *i = std::forward<R>(elem); + while (*(i-1) < *i) + { + std::swap(*(i-1), *i); + --i; + } + while (i < m_end && *i < *(i+1)) + { + std::swap(*(i+1), *i); + ++i; + } + return; + } + } + } + + void clear() noexcept + { + lock_guard_type lck(m_lock); + m_end = &m_list[0]; + // put an empty element with maximum time into the queue. + // the insert algo above will run into this element and doesn't + // need a comparison with queue start. + // + m_list[0] = T::never(); + m_end++; + } + + // save state support & mame disasm + + const T *listptr() const noexcept { return &m_list[1]; } + std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); } + const T & operator[](std::size_t index) const noexcept { return m_list[ 1 + index]; } + private: + using mutex_type = pspin_mutex<TS>; + using lock_guard_type = std::lock_guard<mutex_type>; + + mutex_type m_lock; + PALIGNAS_CACHELINE() + T * m_end; + aligned_vector<T> m_list; + + public: + // profiling + // FIXME: Make those private + pperfcount_t<true> m_prof_sortmove; // NOLINT + pperfcount_t<true> m_prof_call; // NOLINT + pperfcount_t<true> m_prof_remove; // NOLINT + pperfcount_t<true> m_prof_retime; // NOLINT + }; + + template <class T, bool TS> + class timed_queue_heap + { + public: + + struct compare + { + constexpr bool operator()(const T &a, const T &b) const { return b <= a; } + }; + + explicit timed_queue_heap(const std::size_t list_size) + : m_list(list_size) + { + clear(); + } + ~timed_queue_heap() = default; + + PCOPYASSIGNMOVE(timed_queue_heap, delete) + + std::size_t capacity() const noexcept { return m_list.capacity(); } + bool empty() const noexcept { return &m_list[0] == m_end; } + + template <bool KEEPSTAT> + void push(T &&e) noexcept + { + // Lock + lock_guard_type lck(m_lock); + *m_end++ = e; + std::push_heap(&m_list[0], m_end, compare()); + if (KEEPSTAT) + m_prof_call.inc(); + } + + T pop() noexcept + { + T ret(m_list[0]); + std::pop_heap(&m_list[0], m_end, compare()); + m_end--; + return ret; + } + + const T &top() const noexcept { return m_list[0]; } + + template <bool KEEPSTAT, class R> + void remove(const R &elem) noexcept + { + // Lock + lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_remove.inc(); + for (T * i = m_end - 1; i >= &m_list[0]; i--) + { + if (*i == elem) + { + m_end--; + *i = *m_end; + std::make_heap(&m_list[0], m_end, compare()); + return; + } + } + } + + template <bool KEEPSTAT> + void retime(const T &elem) noexcept + { + // Lock + lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_retime.inc(); + for (T * i = m_end - 1; i >= &m_list[0]; i--) + { + if (*i == elem) // partial equal! + { + *i = elem; + std::make_heap(&m_list[0], m_end, compare()); + return; + } + } + } + + void clear() + { + lock_guard_type lck(m_lock); + m_list.clear(); + m_end = &m_list[0]; + } + + // save state support & mame disasm + + constexpr const T *listptr() const { return &m_list[0]; } + constexpr std::size_t size() const noexcept { return m_list.size(); } + constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; } + private: + using mutex_type = pspin_mutex<TS>; + using lock_guard_type = std::lock_guard<mutex_type>; + + mutex_type m_lock; + std::vector<T> m_list; + T *m_end; + + public: + // profiling + pperfcount_t<true> m_prof_sortmove; // NOLINT + pperfcount_t<true> m_prof_call; // NOLINT + pperfcount_t<true> m_prof_remove; // NOLINT + pperfcount_t<true> m_prof_retime; // NOLINT + }; + +} // namespace plib + +#endif // PTIMED_QUEUE_H_ diff --git a/src/lib/netlist/plib/ptokenizer.h b/src/lib/netlist/plib/ptokenizer.h index d5c4e13632c..ce73d4a3512 100644 --- a/src/lib/netlist/plib/ptokenizer.h +++ b/src/lib/netlist/plib/ptokenizer.h @@ -8,7 +8,6 @@ /// \file ptokenizer.h /// -#include "plists.h" #include "pstream.h" #include "pstring.h" diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp index 180f2079ebc..f1459c1b00e 100644 --- a/src/lib/netlist/plib/putil.cpp +++ b/src/lib/netlist/plib/putil.cpp @@ -2,7 +2,6 @@ // copyright-holders:Couriersud #include "putil.h" -#include "plists.h" #include "pstrutil.h" #include "ptypes.h" #include "penum.h" diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index b8e1c25a927..02231c1b8b5 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -608,7 +608,7 @@ void tool_app_t::static_compile() for (auto &e : mp) { - auto sout(std::ofstream(opt_dir() + "/" + e.first + ".c" )); + std::ofstream sout(opt_dir() + "/" + e.first + ".c" ); sout << e.second.m_code; } } diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 6e8bce036d1..7c2847eb38d 100755 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -1,8 +1,7 @@ // license:GPL-2.0+ // copyright-holders:Couriersud #include "netlist/plib/pstring.h" -#include "netlist/nl_setup.h" -#include "netlist/plib/plists.h" +//#include "netlist/nl_setup.h" #include "netlist/plib/pmain.h" #include "netlist/plib/ppmf.h" #include "netlist/plib/pstream.h" @@ -724,8 +723,8 @@ static void open_ostream_and_exec(pstring fname, bool binary, F func) if (fname != "-") { // FIXME: binary depends on format! - auto outstrm(std::ofstream(plib::filesystem::u8path(fname), - binary ? (std::ios::out | std::ios::binary) : std::ios::out)); + std::ofstream outstrm(plib::filesystem::u8path(fname), + binary ? (std::ios::out | std::ios::binary) : std::ios::out); if (outstrm.fail()) throw plib::file_open_e(fname); outstrm.imbue(std::locale::classic()); diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h index 30daa5c4556..fec745b5c5e 100755 --- a/src/lib/netlist/tools/nl_convert.h +++ b/src/lib/netlist/tools/nl_convert.h @@ -8,7 +8,6 @@ /// \file nl_convert.h /// -#include "plib/plists.h" #include "plib/pstring.h" #include "plib/ptokenizer.h" #include "plib/ptypes.h" |