summaryrefslogtreecommitdiff
path: root/cpu_ref
diff options
context:
space:
mode:
Diffstat (limited to 'cpu_ref')
-rw-r--r--cpu_ref/rsCpuExecutable.cpp41
-rw-r--r--cpu_ref/rsCpuExecutable.h14
-rw-r--r--cpu_ref/rsCpuScript.cpp38
-rw-r--r--cpu_ref/rsCpuScript.h22
-rw-r--r--cpu_ref/rsCpuScriptGroup2.cpp20
5 files changed, 103 insertions, 32 deletions
diff --git a/cpu_ref/rsCpuExecutable.cpp b/cpu_ref/rsCpuExecutable.cpp
index a79f671a..83ef7574 100644
--- a/cpu_ref/rsCpuExecutable.cpp
+++ b/cpu_ref/rsCpuExecutable.cpp
@@ -60,7 +60,8 @@ static int copyFile(const char *dstFile, const char *srcFile) {
}
static std::string findSharedObjectName(const char *cacheDir,
- const char *resName) {
+ const char *resName,
+ const bool reuse = true) {
std::string scriptSOName(cacheDir);
#if defined(RS_COMPATIBILITY_LIB) && !defined(__LP64__)
size_t cutPos = scriptSOName.rfind("cache");
@@ -74,6 +75,20 @@ static std::string findSharedObjectName(const char *cacheDir,
scriptSOName.append("/librs.");
#endif // RS_COMPATIBILITY_LIB
scriptSOName.append(resName);
+ if (!reuse) {
+ // If the generated shared library is not reused, e.g., with a debug
+ // context or forced by a system property, multiple threads may read
+ // and write the shared library at the same time. To avoid the race
+ // on the generated shared library, delete it before finishing script
+ // initialization. To avoid deleting a file generated by a regular
+ // context, use a special suffix here.
+ // Because the script initialization is guarded by a lock from the Java
+ // API, it is safe to name this file with a consistent name and suffix
+ // and delete it after loading. The same lock has also prevented write-
+ // write races on the .so during script initialization even if reuse is
+ // true.
+ scriptSOName.append("#delete_after_load");
+ }
scriptSOName.append(".so");
return scriptSOName;
@@ -88,8 +103,13 @@ const char* SharedLibraryUtils::RS_CACHE_DIR = "com.android.renderscript.cache";
bool SharedLibraryUtils::createSharedLibrary(const char *driverName,
const char *cacheDir,
- const char *resName) {
- std::string sharedLibName = findSharedObjectName(cacheDir, resName);
+ const char *resName,
+ const bool reuse,
+ std::string *fullPath) {
+ std::string sharedLibName = findSharedObjectName(cacheDir, resName, reuse);
+ if (fullPath) {
+ *fullPath = sharedLibName;
+ }
std::string objFileName = cacheDir;
objFileName.append("/");
objFileName.append(resName);
@@ -125,6 +145,21 @@ bool SharedLibraryUtils::createSharedLibrary(const char *driverName,
const char* RsdCpuScriptImpl::BCC_EXE_PATH = "/system/bin/bcc";
+void* SharedLibraryUtils::loadAndDeleteSharedLibrary(const char *fullPath) {
+ void *loaded = dlopen(fullPath, RTLD_NOW | RTLD_LOCAL);
+ if (loaded == nullptr) {
+ ALOGE("Unable to open shared library (%s): %s", fullPath, dlerror());
+ return nullptr;
+ }
+
+ int r = unlink(fullPath);
+ if (r != 0) {
+ ALOGE("Could not unlink copy %s", fullPath);
+ return nullptr;
+ }
+ return loaded;
+}
+
void* SharedLibraryUtils::loadSharedLibrary(const char *cacheDir,
const char *resName,
const char *nativeLibDir,
diff --git a/cpu_ref/rsCpuExecutable.h b/cpu_ref/rsCpuExecutable.h
index ee58e377..82cf7742 100644
--- a/cpu_ref/rsCpuExecutable.h
+++ b/cpu_ref/rsCpuExecutable.h
@@ -31,9 +31,14 @@ class Context;
class SharedLibraryUtils {
public:
#ifndef RS_COMPATIBILITY_LIB
+ // Creates a shared library in cacheDir for the bitcode named resName.
+ // If reuse is false and SOPath is not nullptr, saves the filename
+ // used for the shared library in SOPath.
static bool createSharedLibrary(const char* driverName,
const char* cacheDir,
- const char* resName);
+ const char* resName,
+ const bool reuse = true,
+ std::string *SOPath = nullptr);
#endif
// Load the shared library referred to by cacheDir and resName. If we have
@@ -48,6 +53,13 @@ public:
const char *nativeLibDir = nullptr,
bool *alreadyLoaded = nullptr);
+ // Load the shared library referred to by fullPath, and delete it right
+ // after loading it. Files loaded by this function are only used once, e.g.,
+ // shared libraries generated for scripts in a debug context. Deleting them
+ // is OK in this case since the shared libraries have already been dlopened.
+ // Deletion is also required because such files are not intended for reuse.
+ static void* loadAndDeleteSharedLibrary(const char *fullPath);
+
// Create a len length string containing random characters from [A-Za-z0-9].
static std::string getRandomString(size_t len);
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 545e92f3..dec9ab29 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -57,24 +57,6 @@ static bool allocationLODIsNull(const android::renderscript::Allocation *alloc)
#ifndef RS_COMPATIBILITY_LIB
-static bool is_force_recompile() {
- char buf[PROP_VALUE_MAX];
-
- // Re-compile if floating point precision has been overridden.
- android::renderscript::property_get("debug.rs.precision", buf, "");
- if (buf[0] != '\0') {
- return true;
- }
-
- // Re-compile if debug.rs.forcerecompile is set.
- android::renderscript::property_get("debug.rs.forcerecompile", buf, "0");
- if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
- return true;
- } else {
- return false;
- }
-}
-
static void setCompileArguments(std::vector<const char*>* args,
const std::string& bcFileName,
const char* cacheDir, const char* resName,
@@ -381,7 +363,8 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
compileArguments.push_back(checksumStr.c_str());
compileArguments.push_back(nullptr);
- if (!is_force_recompile() && !useRSDebugContext) {
+ const bool reuse = !is_force_recompile() && !useRSDebugContext;
+ if (reuse) {
mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
// Read RS info from the shared object to detect checksum mismatch
@@ -391,8 +374,8 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
}
}
- // If we can't, it's either not there or out of date. We compile the bit code and try loading
- // again.
+ // If reuse is desired and we can't, it's either not there or out of date.
+ // We compile the bit code and try loading again.
if (mScriptSO == nullptr) {
if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize,
compileArguments))
@@ -402,14 +385,21 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
return false;
}
- if (!SharedLibraryUtils::createSharedLibrary(mCtx->getContext()->getDriverName(),
- cacheDir, resName)) {
+ std::string SOPath;
+
+ if (!SharedLibraryUtils::createSharedLibrary(
+ mCtx->getContext()->getDriverName(), cacheDir, resName, reuse,
+ &SOPath)) {
ALOGE("Linker: Failed to link object file '%s'", resName);
mCtx->unlockMutex();
return false;
}
- mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
+ if (reuse) {
+ mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
+ } else {
+ mScriptSO = SharedLibraryUtils::loadAndDeleteSharedLibrary(SOPath.c_str());
+ }
if (mScriptSO == nullptr) {
ALOGE("Unable to load '%s'", resName);
mCtx->unlockMutex();
diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h
index 1814d5ff..dc96f8ba 100644
--- a/cpu_ref/rsCpuScript.h
+++ b/cpu_ref/rsCpuScript.h
@@ -171,4 +171,26 @@ uint32_t constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize,
} // namespace android
+namespace {
+
+inline bool is_force_recompile() {
+ char buf[PROP_VALUE_MAX];
+
+ // Re-compile if floating point precision has been overridden.
+ android::renderscript::property_get("debug.rs.precision", buf, "");
+ if (buf[0] != '\0') {
+ return true;
+ }
+
+ // Re-compile if debug.rs.forcerecompile is set.
+ android::renderscript::property_get("debug.rs.forcerecompile", buf, "0");
+ if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+} // anonymous namespace
+
#endif // RSD_CPU_SCRIPT_H
diff --git a/cpu_ref/rsCpuScriptGroup2.cpp b/cpu_ref/rsCpuScriptGroup2.cpp
index 11393ff4..d624e623 100644
--- a/cpu_ref/rsCpuScriptGroup2.cpp
+++ b/cpu_ref/rsCpuScriptGroup2.cpp
@@ -473,8 +473,13 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
bool alreadyLoaded = false;
std::string cloneName;
- mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nullptr,
- &alreadyLoaded);
+ const bool useRSDebugContext =
+ (mCpuRefImpl->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG);
+ const bool reuse = !is_force_recompile() && !useRSDebugContext;
+ if (reuse) {
+ mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nullptr,
+ &alreadyLoaded);
+ }
if (mScriptObj != nullptr) {
// A shared library named resName is found in code cache directory
// cacheDir, and loaded with the handle stored in mScriptObj.
@@ -528,8 +533,11 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
// Create and load the shared lib
//===--------------------------------------------------------------------===//
+ std::string SOPath;
+
if (!SharedLibraryUtils::createSharedLibrary(
- getCpuRefImpl()->getContext()->getDriverName(), cacheDir, resName)) {
+ getCpuRefImpl()->getContext()->getDriverName(), cacheDir, resName,
+ reuse, &SOPath)) {
ALOGE("Failed to link object file '%s'", resName);
unlink(objFilePath.c_str());
return;
@@ -537,7 +545,11 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
unlink(objFilePath.c_str());
- mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
+ if (reuse) {
+ mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
+ } else {
+ mScriptObj = SharedLibraryUtils::loadAndDeleteSharedLibrary(SOPath.c_str());
+ }
if (mScriptObj == nullptr) {
ALOGE("Unable to load '%s'", resName);
return;