summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_macosx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/lib/osdlib_macosx.cpp')
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp228
1 files changed, 158 insertions, 70 deletions
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 372293ec1a3..54836f9ec69 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -8,26 +8,26 @@
//
//============================================================
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <dlfcn.h>
+// MAME headers
+#include "osdcore.h"
+#include "osdlib.h"
+#include <csignal>
#include <cstdio>
+#include <cstdlib>
#include <iomanip>
#include <memory>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <Carbon/Carbon.h>
-// MAME headers
-#include "osdcore.h"
-#include "osdlib.h"
//============================================================
// osd_getenv
@@ -56,36 +56,6 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}
-//============================================================
-// osd_alloc_executable
-//
-// allocates "size" bytes of executable memory. this must take
-// things like NX support into account.
-//============================================================
-
-void *osd_alloc_executable(size_t size)
-{
-#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX)
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
-#elif defined(SDLMAME_UNIX)
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0);
-#endif
-}
-
-//============================================================
-// osd_free_executable
-//
-// frees memory allocated with osd_alloc_executable
-//============================================================
-
-void osd_free_executable(void *ptr, size_t size)
-{
-#ifdef SDLMAME_SOLARIS
- munmap((char *)ptr, size);
-#else
- munmap(ptr, size);
-#endif
-}
//============================================================
// osd_break_into_debugger
@@ -98,7 +68,7 @@ void osd_break_into_debugger(const char *message)
struct kinfo_proc info;
info.kp_proc.p_flag = 0;
std::size_t infosz = sizeof(info);
- sysctl(mib, ARRAY_LENGTH(mib), &info, &infosz, nullptr, 0);
+ sysctl(mib, std::size(mib), &info, &infosz, nullptr, 0);
if (info.kp_proc.p_flag & P_TRACED)
{
printf("MAME exception: %s\n", message);
@@ -113,10 +83,26 @@ 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
//============================================================
-std::string osd_get_clipboard_text(void)
+std::string osd_get_clipboard_text() noexcept
{
std::string result;
bool has_result = false;
@@ -152,31 +138,48 @@ std::string osd_get_clipboard_text(void)
CFStringEncoding encoding;
if (UTTypeConformsTo(flavor_type, kUTTypeUTF16PlainText))
encoding = kCFStringEncodingUTF16;
- else if (UTTypeConformsTo (flavor_type, kUTTypeUTF8PlainText))
+ else if (UTTypeConformsTo(flavor_type, kUTTypeUTF8PlainText))
encoding = kCFStringEncodingUTF8;
- else if (UTTypeConformsTo (flavor_type, kUTTypePlainText))
+ else if (UTTypeConformsTo(flavor_type, kUTTypePlainText))
encoding = kCFStringEncodingMacRoman;
else
continue;
CFDataRef flavor_data;
err = PasteboardCopyItemFlavorData(pasteboard_ref, item_id, flavor_type, &flavor_data);
+ if (err)
+ continue;
- if (!err)
+ CFDataRef utf8_data;
+ if (kCFStringEncodingUTF8 == encoding)
+ {
+ utf8_data = flavor_data;
+ }
+ else
{
CFStringRef string_ref = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, flavor_data, encoding);
- CFDataRef data_ref = CFStringCreateExternalRepresentation (kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?');
- CFRelease(string_ref);
CFRelease(flavor_data);
+ if (!string_ref)
+ continue;
- CFIndex const length = CFDataGetLength(data_ref);
- CFRange const range = CFRangeMake(0, length);
-
- result.resize(length);
- CFDataGetBytes(data_ref, range, reinterpret_cast<unsigned char *>(&result[0]));
- has_result = true;
+ utf8_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?');
+ CFRelease(string_ref);
+ }
- CFRelease(data_ref);
+ if (utf8_data)
+ {
+ CFIndex const length = CFDataGetLength(utf8_data);
+ CFRange const range = CFRangeMake(0, length);
+ try
+ {
+ result.resize(length);
+ CFDataGetBytes(utf8_data, range, reinterpret_cast<UInt8 *>(result.data()));
+ has_result = true;
+ }
+ catch (std::bad_alloc const &)
+ {
+ }
+ CFRelease(utf8_data);
}
}
@@ -188,34 +191,72 @@ std::string osd_get_clipboard_text(void)
return result;
}
+
//============================================================
-// osd_getpid
+// osd_set_clipboard_text
//============================================================
-int osd_getpid(void)
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept
{
- return getpid();
+ // FIXME: better conversion of OSStatus to std::error_condition
+ OSStatus err;
+
+ CFDataRef const data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8 const *>(text.data()), text.length());
+ if (!data)
+ return std::errc::not_enough_memory;
+
+ PasteboardRef pasteboard_ref;
+ err = PasteboardCreate(kPasteboardClipboard, &pasteboard_ref);
+ if (err)
+ {
+ CFRelease(data);
+ return std::errc::io_error;
+ }
+
+ err = PasteboardClear(pasteboard_ref);
+ if (err)
+ {
+ CFRelease(data);
+ CFRelease(pasteboard_ref);
+ return std::errc::io_error;
+ }
+
+ err = PasteboardPutItemFlavor(pasteboard_ref, PasteboardItemID(1), kUTTypeUTF8PlainText, data, kPasteboardFlavorNoFlags);
+ CFRelease(data);
+ CFRelease(pasteboard_ref);
+ if (err)
+ return std::errc::io_error;
+
+ return std::error_condition();
}
+
//============================================================
-// dynamic_module_posix_impl
+// osd_getpid
//============================================================
+int osd_getpid() noexcept
+{
+ return getpid();
+}
+
+
namespace osd {
+
+namespace {
+
class dynamic_module_posix_impl : public dynamic_module
{
public:
- dynamic_module_posix_impl(std::vector<std::string> &libraries)
- : m_module(nullptr)
+ dynamic_module_posix_impl(std::vector<std::string> &&libraries) : m_libraries(std::move(libraries))
{
- m_libraries = libraries;
}
virtual ~dynamic_module_posix_impl() override
{
- if (m_module != nullptr)
+ if (m_module)
dlclose(m_module);
- };
+ }
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
@@ -225,19 +266,17 @@ protected:
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
- {
return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
- }
for (auto const &library : m_libraries)
{
- void *module = dlopen(library.c_str(), RTLD_LAZY);
+ void *const module = dlopen(library.c_str(), RTLD_LAZY);
if (module != nullptr)
{
- generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+ generic_fptr_t const function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
- if (function != nullptr)
+ if (function)
{
m_module = module;
return function;
@@ -254,12 +293,61 @@ protected:
private:
std::vector<std::string> m_libraries;
- void * m_module;
+ void * m_module = nullptr;
};
+} // anonymous namespace
+
+
+bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept
+{
+ char const *const begin(reinterpret_cast<char const *>(start));
+ char const *const end(begin + size);
+ __builtin___clear_cache(const_cast<char *>(begin), const_cast<char *>(end));
+ return true;
+}
+
+
+void *virtual_memory_allocation::do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept
+{
+ long const p(sysconf(_SC_PAGE_SIZE));
+ if (0 >= p)
+ return nullptr;
+ std::size_t s(0);
+ for (std::size_t b : blocks)
+ s += (b + p - 1) / p;
+ s *= p;
+ if (!s)
+ return nullptr;
+ void *const result(mmap(nullptr, s, PROT_NONE, MAP_ANON | MAP_SHARED, -1, 0));
+ if (result == (void *)-1)
+ return nullptr;
+ size = s;
+ page_size = p;
+ return result;
+}
+
+void virtual_memory_allocation::do_free(void *start, std::size_t size) noexcept
+{
+ munmap(start, size);
+}
+
+bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) noexcept
+{
+ int prot((NONE == access) ? PROT_NONE : 0);
+ if (access & READ)
+ prot |= PROT_READ;
+ if (access & WRITE)
+ prot |= PROT_WRITE;
+ if (access & EXECUTE)
+ prot |= PROT_EXEC;
+ return mprotect(start, size, prot) == 0;
+}
+
+
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
- return std::make_unique<dynamic_module_posix_impl>(names);
+ return std::make_unique<dynamic_module_posix_impl>(std::move(names));
}
} // namespace osd