summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Ni <yangni@google.com>2015-04-07 16:00:31 -0700
committerYang Ni <yangni@google.com>2015-04-14 10:15:54 -0700
commitf02a2b0a2749d4a4f07edbc23eddff2e51d11b72 (patch)
treed4aa344011cf33ed5d7a906c2832d737cf2bfd97
parentb1bfb9d7adbabd3e705e54c6720ba955ed148230 (diff)
downloadrs-f02a2b0a2749d4a4f07edbc23eddff2e51d11b72.tar.gz
Compute checksum for script group generated code
Change-Id: I5f469266fd11b5031d1357f356ac40e00f5c0348
-rw-r--r--cpu_ref/rsCpuScript.cpp58
-rw-r--r--cpu_ref/rsCpuScript.h2
-rw-r--r--cpu_ref/rsCpuScriptGroup2.cpp102
-rw-r--r--cpu_ref/rsCpuScriptGroup2.h1
4 files changed, 114 insertions, 49 deletions
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 6099cf4d..fb87dd1a 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -150,33 +150,6 @@ bool isChecksumNeeded() {
return (buf[0] == '1');
}
-bool addFileToChecksum(const char *fileName, uint32_t &checksum) {
- int FD = open(fileName, O_RDONLY);
- if (FD == -1) {
- ALOGE("Cannot open file \'%s\' to compute checksum", fileName);
- return false;
- }
-
- char buf[256];
- while (true) {
- ssize_t nread = read(FD, buf, sizeof(buf));
- if (nread < 0) { // bail out on failed read
- ALOGE("Error while computing checksum for file \'%s\'", fileName);
- return false;
- }
-
- checksum = adler32(checksum, (const unsigned char *) buf, nread);
- if (static_cast<size_t>(nread) < sizeof(buf)) // EOF
- break;
- }
-
- if (TEMP_FAILURE_RETRY(close(FD)) != 0) {
- ALOGE("Cannot close file \'%s\' after computing checksum", fileName);
- return false;
- }
- return true;
-}
-
char *constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize,
const char *commandLine,
const std::vector<const char *> &bccFiles) {
@@ -191,7 +164,7 @@ char *constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize,
// include checksum of bccFiles
for (auto bccFile : bccFiles) {
- if (!addFileToChecksum(bccFile, checksum)) {
+ if (!android::renderscript::addFileToChecksum(bccFile, checksum)) {
// return empty checksum instead of something partial/corrupt
return nullptr;
}
@@ -208,6 +181,35 @@ char *constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize,
namespace android {
namespace renderscript {
+#ifndef RS_COMPATIBILITY_LIB
+bool addFileToChecksum(const char *fileName, uint32_t &checksum) {
+ int FD = open(fileName, O_RDONLY);
+ if (FD == -1) {
+ ALOGE("Cannot open file \'%s\' to compute checksum", fileName);
+ return false;
+ }
+
+ char buf[256];
+ while (true) {
+ ssize_t nread = read(FD, buf, sizeof(buf));
+ if (nread < 0) { // bail out on failed read
+ ALOGE("Error while computing checksum for file \'%s\'", fileName);
+ return false;
+ }
+
+ checksum = adler32(checksum, (const unsigned char *) buf, nread);
+ if (static_cast<size_t>(nread) < sizeof(buf)) // EOF
+ break;
+ }
+
+ if (TEMP_FAILURE_RETRY(close(FD)) != 0) {
+ ALOGE("Cannot close file \'%s\' after computing checksum", fileName);
+ return false;
+ }
+ return true;
+}
+#endif // !RS_COMPATIBILITY_LIB
+
RsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
mCtx = ctx;
mScript = s;
diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h
index 72da1415..f38158a4 100644
--- a/cpu_ref/rsCpuScript.h
+++ b/cpu_ref/rsCpuScript.h
@@ -145,6 +145,8 @@ Allocation * rsdScriptGetAllocationForPointer(
const Script *script,
const void *);
+bool addFileToChecksum(const char *fileName, uint32_t &checksum);
+
}
#ifdef __LP64__
diff --git a/cpu_ref/rsCpuScriptGroup2.cpp b/cpu_ref/rsCpuScriptGroup2.cpp
index 38ddd5df..df1172b7 100644
--- a/cpu_ref/rsCpuScriptGroup2.cpp
+++ b/cpu_ref/rsCpuScriptGroup2.cpp
@@ -11,6 +11,8 @@
#include <vector>
#ifndef RS_COMPATIBILITY_LIB
+#include <zlib.h>
+
#include "bcc/Config/Config.h"
#endif
@@ -225,9 +227,34 @@ string getCoreLibPath(Context* context, string* coreLibRelaxedPath) {
#endif
}
-string getFileName(string path) {
- unsigned found = path.find_last_of("/\\");
- return path.substr(found + 1);
+bool getChecksum(const std::vector<string>& inputBitcodeFilenames,
+ const string& coreLibPath, const string& coreLibRelaxedPath,
+ const char* commandLine,
+ char* checksumStr) {
+ uint32_t checksum = adler32(0L, Z_NULL, 0);
+
+ for (const auto& bcFilename : inputBitcodeFilenames) {
+ if (!android::renderscript::addFileToChecksum(bcFilename.c_str(), checksum)) {
+ return false;
+ }
+ }
+
+ if (!android::renderscript::addFileToChecksum(coreLibPath.c_str(), checksum)) {
+ return false;
+ }
+
+ if (!coreLibRelaxedPath.empty() &&
+ !android::renderscript::addFileToChecksum(coreLibRelaxedPath.c_str(), checksum)) {
+ return false;
+ }
+
+ // include checksum of command line arguments
+ checksum = adler32(checksum, (const unsigned char *) commandLine,
+ strlen(commandLine));
+
+ sprintf(checksumStr, "%08x", checksum);
+
+ return true;
}
void setupCompileArguments(
@@ -260,7 +287,6 @@ void setupCompileArguments(
args->push_back(output_dir.c_str());
args->push_back("-o");
args->push_back(output_filename.c_str());
- args->push_back(nullptr);
}
void generateSourceSlot(const Closure& closure,
@@ -291,10 +317,6 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
return;
}
- //===--------------------------------------------------------------------===//
- // Fuse the input kernels and generate native code in an object file
- //===--------------------------------------------------------------------===//
-
std::set<string> inputSet;
for (Closure* closure : mGroup->mClosures) {
const Script* script = closure->mFunctionID.get()->mScript;
@@ -336,26 +358,66 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
rsAssert(cacheDir != nullptr);
string objFilePath(cacheDir);
- objFilePath.append("/fusedXXXXXX.o");
- // Find unique object file name, to make following file names unique.
- int tempfd = mkstemps(&objFilePath[0], 2);
- if (tempfd == -1) {
- return;
- }
- TEMP_FAILURE_RETRY(close(tempfd));
+ objFilePath.append("/");
+ objFilePath.append(mGroup->mName);
+ objFilePath.append(".o");
- string outputFileName = getFileName(objFilePath.substr(0, objFilePath.size() - 2));
+ string outputFileName(mGroup->mName);
string coreLibRelaxedPath;
const string& coreLibPath = getCoreLibPath(getCpuRefImpl()->getContext(),
&coreLibRelaxedPath);
+
vector<const char*> arguments;
string output_dir(cacheDir);
setupCompileArguments(inputs, kernelBatches, invokeBatches, output_dir,
- outputFileName, coreLibPath, coreLibRelaxedPath, &arguments);
+ outputFileName, coreLibPath, coreLibRelaxedPath,
+ &arguments);
+
+ std::unique_ptr<const char> cmdLine(rsuJoinStrings(arguments.size() - 1,
+ arguments.data()));
+
+ if (!getChecksum(inputs, coreLibPath, coreLibRelaxedPath, cmdLine.get(),
+ mChecksum)) {
+ return;
+ }
+
+ const char* resName = outputFileName.c_str();
+
+ //===--------------------------------------------------------------------===//
+ // Try to load a shared lib from code cache matching filename and checksum
+ //===--------------------------------------------------------------------===//
+
+ mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
+ if (mScriptObj != nullptr) {
+ mExecutable = ScriptExecutable::createFromSharedObject(
+ getCpuRefImpl()->getContext(), mScriptObj);
+ if (mExecutable != nullptr) {
+ if (mExecutable->isChecksumValid(mChecksum)) {
+ return;
+ } else {
+ ALOGE("Invalid checksum from cached so: %s (expected: %s)",
+ mExecutable->getBuildChecksum(), mChecksum);
+ }
+ delete mExecutable;
+ mExecutable = nullptr;
+ } else {
+ ALOGE("Failed to create an executable object from so file");
+ }
+ dlclose(mScriptObj);
+ mScriptObj = nullptr;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Fuse the input kernels and generate native code in an object file
+ //===--------------------------------------------------------------------===//
+
+ arguments.push_back("-build-checksum");
+ arguments.push_back(mChecksum);
+ arguments.push_back(nullptr);
bool compiled = rsuExecuteCommand(RsdCpuScriptImpl::BCC_EXE_PATH,
- arguments.size()-1,
- arguments.data());
+ arguments.size()-1,
+ arguments.data());
if (!compiled) {
return;
}
@@ -364,8 +426,6 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) {
// Create and load the shared lib
//===--------------------------------------------------------------------===//
- const char* resName = outputFileName.c_str();
-
if (!SharedLibraryUtils::createSharedLibrary(cacheDir, resName)) {
ALOGE("Failed to link object file '%s'", resName);
unlink(objFilePath.c_str());
diff --git a/cpu_ref/rsCpuScriptGroup2.h b/cpu_ref/rsCpuScriptGroup2.h
index 1883f903..e3f345e2 100644
--- a/cpu_ref/rsCpuScriptGroup2.h
+++ b/cpu_ref/rsCpuScriptGroup2.h
@@ -74,6 +74,7 @@ private:
RsdCpuReferenceImpl* mCpuRefImpl;
const ScriptGroup2* mGroup;
List<Batch*> mBatches;
+ char mChecksum[9];
ScriptExecutable* mExecutable;
void* mScriptObj;
};