summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/drcbex64.cpp17
-rw-r--r--src/devices/cpu/drcbex86.cpp16
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp17
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp26
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp36
-rw-r--r--src/osd/osdcore.h11
6 files changed, 119 insertions, 4 deletions
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index 17b25bba958..891b8c69dd5 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -945,8 +945,21 @@ void drcbe_x64::generate(drcuml_block &block, const instruction *instlist, uint3
m_hash.block_begin(block, instlist, numinst);
m_map.block_begin(block);
- // compute the base by aligning the cache top to a cache line (assumed to be 64 bytes)
- x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63);
+ // compute the base by aligning the cache top to a cache line
+ auto [err, linesize] = osd_get_cache_line_size();
+ uintptr_t linemask = 63;
+ if (err)
+ {
+ osd_printf_verbose("Error getting cache line size (%s:%d %s), assuming 64 bytes\n", err.category().name(), err.value(), err.message());
+ }
+ else
+ {
+ assert(linesize);
+ linemask = linesize - 1;
+ for (unsigned shift = 1; linemask & (linemask + 1); ++shift)
+ linemask |= linemask >> shift;
+ }
+ x86code *dst = (x86code *)(uintptr_t(m_cache.top() + linemask) & ~linemask);
CodeHolder ch;
ch.init(Environment::host(), uint64_t(dst));
diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp
index 6e187e6846a..d9a6b79e137 100644
--- a/src/devices/cpu/drcbex86.cpp
+++ b/src/devices/cpu/drcbex86.cpp
@@ -840,8 +840,20 @@ void drcbe_x86::generate(drcuml_block &block, const instruction *instlist, uint3
m_hash.block_begin(block, instlist, numinst);
m_map.block_begin(block);
- // compute the base by aligning the cache top to a cache line (assumed to be 64 bytes)
- x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63);
+ // compute the base by aligning the cache top to a cache line
+ auto [err, linesize] = osd_get_cache_line_size();
+ uintptr_t linemask = 63;
+ if (err)
+ {
+ osd_printf_verbose("Error getting cache line size (%s:%d %s), assuming 64 bytes\n", err.category().name(), err.value(), err.message());
+ }
+ else
+ {
+ assert(linesize);
+ linemask = linesize - 1;
+ for (unsigned shift = 1; linemask & (linemask + 1); ++shift)
+ linemask |= linemask >> shift;
+ }
CodeHolder ch;
ch.init(Environment::host(), uint64_t(dst));
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 9d13f118ff2..54836f9ec69 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -56,6 +56,7 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}
+
//============================================================
// osd_break_into_debugger
//============================================================
@@ -82,6 +83,22 @@ void osd_break_into_debugger(const char *message)
//============================================================
+// osd_get_cache_line_size
+//============================================================
+
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
+{
+ size_t result = 0;
+ size_t resultsize = sizeof(result);
+ int const err = sysctlbyname("hw.cachelinesize", &result, &resultsize, 0, 0);
+ if (!err)
+ return std::make_pair(std::error_condition(), unsigned(result));
+ else
+ return std::make_pair(std::error_condition(err, std::generic_category()), 0U);
+}
+
+
+//============================================================
// osd_get_clipboard_text
//============================================================
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 20f6a9ab40c..36004580222 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -53,6 +53,7 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}
+
//============================================================
// osd_break_into_debugger
//============================================================
@@ -68,6 +69,31 @@ void osd_break_into_debugger(const char *message)
#endif
}
+
+//============================================================
+// osd_get_cache_line_size
+//============================================================
+
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
+{
+#if defined(__linux__)
+ FILE *const f = std::fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
+ if (!f)
+ return std::make_pair(std::error_condition(errno, std::generic_category()), 0U);
+
+ unsigned result = 0;
+ auto const cnt = std::fscanf(f, "%u", &result);
+ std::fclose(f);
+ if (1 == cnt)
+ return std::make_pair(std::error_condition(), result);
+ else
+ return std::make_pair(std::errc::io_error, 0U);
+#else // defined(__linux__)
+ return std::make_pair(std::errc::not_supported, 0U);
+#endif
+}
+
+
#ifdef SDLMAME_ANDROID
std::string osd_get_clipboard_text() noexcept
{
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index d42ad14d3df..cf3fd7c9320 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -106,6 +106,42 @@ void osd_break_into_debugger(const char *message)
#endif
}
+
+//============================================================
+// osd_get_cache_line_size
+//============================================================
+
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
+{
+ DWORD resultsize = 0;
+ if (GetLogicalProcessorInformation(nullptr, &resultsize) || (ERROR_INSUFFICIENT_BUFFER != GetLastError()) || !resultsize)
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+
+ auto const result = reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION *>(std::malloc(resultsize));
+ if (!result)
+ return std::make_pair(std::errc::not_enough_memory, 0U);
+
+ if (!GetLogicalProcessorInformation(result, &resultsize))
+ {
+ std::free(result);
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+ }
+
+ for (unsigned i = 0; i < (resultsize / sizeof(result[0])); ++i)
+ {
+ if ((RelationCache == result[i].Relationship) && (1 == result[i].Cache.Level))
+ {
+ unsigned const linesize = result[i].Cache.LineSize;
+ std::free(result);
+ return std::make_pair(std::error_condition(), linesize);
+ }
+ }
+
+ std::free(result);
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+}
+
+
//============================================================
// get_clipboard_text_by_format
//============================================================
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index f3f5fc2e9b3..b3dc2099913 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -19,6 +19,7 @@
#include <iosfwd>
#include <string>
#include <string_view>
+#include <system_error>
#include <utility>
#include <vector>
@@ -128,6 +129,8 @@ osd_ticks_t osd_ticks_per_second() noexcept;
-----------------------------------------------------------------------------*/
void osd_sleep(osd_ticks_t duration) noexcept;
+
+
/***************************************************************************
WORK ITEM INTERFACES
***************************************************************************/
@@ -350,6 +353,14 @@ void osd_work_item_release(osd_work_item *item);
void osd_break_into_debugger(const char *message);
+/// \brief Get cache line size in bytes
+///
+/// This function gets the host CPU's level 1 cache line size in bytes.
+/// \return A pair consisting of an error condition and the cache line
+/// size in bytes if successful.
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept;
+
+
/***************************************************************************
UNCATEGORIZED INTERFACES