mirror of
https://github.com/holub/mame
synced 2025-07-01 08:18:59 +03:00
osd: Added helper for getting CPU cache line size.
This commit is contained in:
parent
43c5edd139
commit
ff92d10a04
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -56,6 +56,7 @@ void osd_process_kill()
|
||||
kill(getpid(), SIGKILL);
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// osd_break_into_debugger
|
||||
//============================================================
|
||||
@ -81,6 +82,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
|
||||
//============================================================
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
//============================================================
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user