Skip to content

Commit

Permalink
osd: Added helper for getting CPU cache line size.
Browse files Browse the repository at this point in the history
  • Loading branch information
cuavas committed Jan 12, 2025
1 parent 65f39de commit 366af66
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 4 deletions.
17 changes: 15 additions & 2 deletions src/devices/cpu/drcbex64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
16 changes: 14 additions & 2 deletions src/devices/cpu/drcbex86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
17 changes: 17 additions & 0 deletions src/osd/modules/lib/osdlib_macosx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}


//============================================================
// osd_break_into_debugger
//============================================================
Expand All @@ -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
//============================================================
Expand Down
26 changes: 26 additions & 0 deletions src/osd/modules/lib/osdlib_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}


//============================================================
// osd_break_into_debugger
//============================================================
Expand All @@ -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
{
Expand Down
35 changes: 35 additions & 0 deletions src/osd/modules/lib/osdlib_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,41 @@ 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))
{
std::free(result);
return std::make_pair(std::error_condition(), unsigned(result[i].Cache.LineSize));
}
}

std::free(result);
return std::make_pair(std::errc::operation_not_permitted, 0U);
}


//============================================================
// get_clipboard_text_by_format
//============================================================
Expand Down
11 changes: 11 additions & 0 deletions src/osd/osdcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <iosfwd>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -128,6 +129,8 @@ osd_ticks_t osd_ticks_per_second() noexcept;
-----------------------------------------------------------------------------*/
void osd_sleep(osd_ticks_t duration) noexcept;



/***************************************************************************
WORK ITEM INTERFACES
***************************************************************************/
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 366af66

Please sign in to comment.