summaryrefslogtreecommitdiffstats
path: root/runtime/gc
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2015-02-16 13:51:51 +0000
committerNarayan Kamath <narayan@google.com>2015-02-21 11:19:07 +0000
commit5a2be3f40125af8b25fbbd9d55dc968168c76ed7 (patch)
tree070b920e71c927f112a6922f5e7b59668392f762 /runtime/gc
parentd98ff78976696fdde1e7868d4687719a0439544b (diff)
downloadart-5a2be3f40125af8b25fbbd9d55dc968168c76ed7.zip
art-5a2be3f40125af8b25fbbd9d55dc968168c76ed7.tar.gz
art-5a2be3f40125af8b25fbbd9d55dc968168c76ed7.tar.bz2
Implement a simple count based boot marker.
We write the number of failed boots to the marker and only prune the dalvik cache if the number of consecutive failed boots is higher than a predefined threshold. Note that the code is forgiving of errors related to boot markers; we continue the boot process even if we're unable to create / write or flush the boot marker. bug: 19360096 Change-Id: Ia17c3b783318ddf43c9199d0f7f09c54a4176667
Diffstat (limited to 'runtime/gc')
-rw-r--r--runtime/gc/space/image_space.cc48
1 files changed, 39 insertions, 9 deletions
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 261d3c2..d873e6d 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -19,6 +19,7 @@
#include <dirent.h>
#include <sys/statvfs.h>
#include <sys/types.h>
+#include <unistd.h>
#include <random>
@@ -122,21 +123,50 @@ static void RealPruneDalvikCache(const std::string& cache_dir_path) {
// every zygote boot and delete it when the boot completes. If we find a file already
// present, it usually means the boot didn't complete. We wipe the entire dalvik
// cache if that's the case.
-static void MarkZygoteStart(const InstructionSet isa) {
+static void MarkZygoteStart(const InstructionSet isa, const uint32_t max_failed_boots) {
const std::string isa_subdir = GetDalvikCacheOrDie(GetInstructionSetString(isa), false);
const std::string boot_marker = isa_subdir + "/.booting";
+ const char* file_name = boot_marker.c_str();
- if (OS::FileExists(boot_marker.c_str())) {
+ uint32_t num_failed_boots = 0;
+ std::unique_ptr<File> file(OS::OpenFileReadWrite(file_name));
+ if (file.get() == nullptr) {
+ file.reset(OS::CreateEmptyFile(file_name));
+
+ if (file.get() == nullptr) {
+ PLOG(WARNING) << "Failed to create boot marker.";
+ return;
+ }
+ } else {
+ if (!file->ReadFully(&num_failed_boots, sizeof(num_failed_boots))) {
+ PLOG(WARNING) << "Failed to read boot marker.";
+ file->Erase();
+ return;
+ }
+ }
+
+ if (max_failed_boots != 0 && num_failed_boots > max_failed_boots) {
LOG(WARNING) << "Incomplete boot detected. Pruning dalvik cache";
RealPruneDalvikCache(isa_subdir);
}
- VLOG(startup) << "Creating boot start marker: " << boot_marker;
- std::unique_ptr<File> f(OS::CreateEmptyFile(boot_marker.c_str()));
- if (f.get() != nullptr) {
- if (f->FlushCloseOrErase() != 0) {
- PLOG(WARNING) << "Failed to write boot marker.";
- }
+ ++num_failed_boots;
+ VLOG(startup) << "Number of failed boots on : " << boot_marker << " = " << num_failed_boots;
+
+ if (lseek(file->Fd(), 0, SEEK_SET) == -1) {
+ PLOG(WARNING) << "Failed to write boot marker.";
+ file->Erase();
+ return;
+ }
+
+ if (!file->WriteFully(&num_failed_boots, sizeof(num_failed_boots))) {
+ PLOG(WARNING) << "Failed to write boot marker.";
+ file->Erase();
+ return;
+ }
+
+ if (file->FlushCloseOrErase() != 0) {
+ PLOG(WARNING) << "Failed to flush boot marker.";
}
}
@@ -450,7 +480,7 @@ ImageSpace* ImageSpace::Create(const char* image_location,
&has_cache, &is_global_cache);
if (Runtime::Current()->IsZygote()) {
- MarkZygoteStart(image_isa);
+ MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots());
}
ImageSpace* space;