diff options
author | Yang Ni <yangni@google.com> | 2015-04-07 16:00:31 -0700 |
---|---|---|
committer | Yang Ni <yangni@google.com> | 2015-04-14 10:15:54 -0700 |
commit | f02a2b0a2749d4a4f07edbc23eddff2e51d11b72 (patch) | |
tree | d4aa344011cf33ed5d7a906c2832d737cf2bfd97 | |
parent | b1bfb9d7adbabd3e705e54c6720ba955ed148230 (diff) | |
download | rs-f02a2b0a2749d4a4f07edbc23eddff2e51d11b72.tar.gz |
Compute checksum for script group generated code
Change-Id: I5f469266fd11b5031d1357f356ac40e00f5c0348
-rw-r--r-- | cpu_ref/rsCpuScript.cpp | 58 | ||||
-rw-r--r-- | cpu_ref/rsCpuScript.h | 2 | ||||
-rw-r--r-- | cpu_ref/rsCpuScriptGroup2.cpp | 102 | ||||
-rw-r--r-- | cpu_ref/rsCpuScriptGroup2.h | 1 |
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; }; |