From f5148527919574c2e2ff74c21eeb31a0cbea57e6 Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Mon, 3 Feb 2020 20:57:34 +0100 Subject: [PATCH] Use ASharedMemory api instead of direct access to /dev/ashmem which is deprecated. --- Common/MemArenaAndroid.cpp | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index 31eda9d3d0..4a9242b2df 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include // Hopefully this ABI will never change... @@ -39,11 +41,41 @@ bool MemArena::NeedsProbing() { return false; } +static int get_sdk_version() { + char sdk[PROP_VALUE_MAX] = {0}; + if (__system_property_get("ro.build.version.sdk", sdk) != 0) { + return atoi(sdk); + } + return -1; +} + // ashmem_create_region - creates a new ashmem region and returns the file // descriptor, or <0 on error +// This function is defined in much later version of the ndk, so we can only access it via dlopen(). // `name' is an optional label to give the region (visible in /proc/pid/maps) // `size' is the size of the region, in page-aligned bytes static int ashmem_create_region(const char *name, size_t size) { + static void* handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL); + using type_ASharedMemory_create = int(*)(const char *name, size_t size); + static type_ASharedMemory_create function_create = nullptr; + + if (handle != nullptr) { + function_create = + reinterpret_cast(dlsym(handle, "ASharedMemory_create")); + } + + if (function_create != nullptr) { + return function_create(name, size); + } else { + return -1; + } +} + +// legacy_ashmem_create_region - creates a new ashmem region and returns the file +// descriptor, or <0 on error +// `name' is an optional label to give the region (visible in /proc/pid/maps) +// `size' is the size of the region, in page-aligned bytes +static int legacy_ashmem_create_region(const char *name, size_t size) { int fd = open(ASHMEM_DEVICE, O_RDWR); if (fd < 0) return fd; @@ -76,7 +108,14 @@ size_t MemArena::roundup(size_t x) { void MemArena::GrabLowMemSpace(size_t size) { // Use ashmem so we don't have to allocate a file on disk! - fd = ashmem_create_region("PPSSPP_RAM", size); + const char* name = "PPSSPP_RAM"; + + // Since version 26 Android provides a new api for accessing SharedMemory. + if (get_sdk_version() >= 26) { + fd = ashmem_create_region(name, size); + } else { + fd = legacy_ashmem_create_region(name, size); + } // Note that it appears that ashmem is pinned by default, so no need to pin. if (fd < 0) { ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x errno: %d", (int)size, (int)(errno));