mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +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_hash.block_begin(block, instlist, numinst);
|
||||||
m_map.block_begin(block);
|
m_map.block_begin(block);
|
||||||
|
|
||||||
// compute the base by aligning the cache top to a cache line (assumed to be 64 bytes)
|
// compute the base by aligning the cache top to a cache line
|
||||||
x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63);
|
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;
|
CodeHolder ch;
|
||||||
ch.init(Environment::host(), uint64_t(dst));
|
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_hash.block_begin(block, instlist, numinst);
|
||||||
m_map.block_begin(block);
|
m_map.block_begin(block);
|
||||||
|
|
||||||
// compute the base by aligning the cache top to a cache line (assumed to be 64 bytes)
|
// compute the base by aligning the cache top to a cache line
|
||||||
x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63);
|
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;
|
CodeHolder ch;
|
||||||
ch.init(Environment::host(), uint64_t(dst));
|
ch.init(Environment::host(), uint64_t(dst));
|
||||||
|
@ -56,6 +56,7 @@ void osd_process_kill()
|
|||||||
kill(getpid(), SIGKILL);
|
kill(getpid(), SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// osd_break_into_debugger
|
// 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
|
// osd_get_clipboard_text
|
||||||
//============================================================
|
//============================================================
|
||||||
|
@ -53,6 +53,7 @@ void osd_process_kill()
|
|||||||
kill(getpid(), SIGKILL);
|
kill(getpid(), SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// osd_break_into_debugger
|
// osd_break_into_debugger
|
||||||
//============================================================
|
//============================================================
|
||||||
@ -68,6 +69,31 @@ void osd_break_into_debugger(const char *message)
|
|||||||
#endif
|
#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
|
#ifdef SDLMAME_ANDROID
|
||||||
std::string osd_get_clipboard_text() noexcept
|
std::string osd_get_clipboard_text() noexcept
|
||||||
{
|
{
|
||||||
|
@ -106,6 +106,42 @@ void osd_break_into_debugger(const char *message)
|
|||||||
#endif
|
#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
|
// get_clipboard_text_by_format
|
||||||
//============================================================
|
//============================================================
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <system_error>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -128,6 +129,8 @@ osd_ticks_t osd_ticks_per_second() noexcept;
|
|||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
void osd_sleep(osd_ticks_t duration) noexcept;
|
void osd_sleep(osd_ticks_t duration) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
WORK ITEM INTERFACES
|
WORK ITEM INTERFACES
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -350,6 +353,14 @@ void osd_work_item_release(osd_work_item *item);
|
|||||||
void osd_break_into_debugger(const char *message);
|
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
|
UNCATEGORIZED INTERFACES
|
||||||
|
Loading…
Reference in New Issue
Block a user