Merge "logd: logcat --clear respect pruneMargin" am: 3d0186b97e
am: daae7558e8
Change-Id: I7fc1b18b080083fd7a48b1bcec8ec8e11139d4d2
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index d9ec081..ded6c8c 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -605,6 +605,33 @@
}
};
+// Determine if watermark is within pruneMargin + 1s from the end of the list,
+// the caller will use this result to set an internal busy flag indicating
+// the prune operation could not be completed because a reader is blocking
+// the request.
+bool LogBuffer::isBusy(log_time watermark) {
+ LogBufferElementCollection::iterator ei = mLogElements.end();
+ --ei;
+ return watermark < ((*ei)->getRealTime() - pruneMargin - log_time(1, 0));
+}
+
+// If the selected reader is blocking our pruning progress, decide on
+// what kind of mitigation is necessary to unblock the situation.
+void LogBuffer::kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows) {
+ if (stats.sizes(id) > (2 * log_buffer_size(id))) { // +100%
+ // A misbehaving or slow reader has its connection
+ // dropped if we hit too much memory pressure.
+ me->release_Locked();
+ } else if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
+ // Allow a blocked WRAP timeout reader to
+ // trigger and start reporting the log data.
+ me->triggerReader_Locked();
+ } else {
+ // tell slow reader to skip entries to catch up
+ me->triggerSkip_Locked(id, pruneRows);
+ }
+}
+
// prune "pruneRows" of type "id" from the buffer.
//
// This garbage collection task is used to expire log entries. It is called to
@@ -695,12 +722,8 @@
}
if (oldest && (watermark <= element->getRealTime())) {
- busy = true;
- if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
- oldest->triggerReader_Locked();
- } else {
- oldest->triggerSkip_Locked(id, pruneRows);
- }
+ busy = isBusy(watermark);
+ if (busy) kickMe(oldest, id, pruneRows);
break;
}
@@ -787,10 +810,8 @@
LogBufferElement* element = *it;
if (oldest && (watermark <= element->getRealTime())) {
- busy = true;
- if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
- oldest->triggerReader_Locked();
- }
+ busy = isBusy(watermark);
+ // Do not let chatty eliding trigger any reader mitigation
break;
}
@@ -941,19 +962,8 @@
}
if (oldest && (watermark <= element->getRealTime())) {
- busy = true;
- if (whitelist) {
- break;
- }
-
- if (stats.sizes(id) > (2 * log_buffer_size(id))) {
- // kick a misbehaving log reader client off the island
- oldest->release_Locked();
- } else if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
- oldest->triggerReader_Locked();
- } else {
- oldest->triggerSkip_Locked(id, pruneRows);
- }
+ busy = isBusy(watermark);
+ if (!whitelist && busy) kickMe(oldest, id, pruneRows);
break;
}
@@ -985,15 +995,8 @@
}
if (oldest && (watermark <= element->getRealTime())) {
- busy = true;
- if (stats.sizes(id) > (2 * log_buffer_size(id))) {
- // kick a misbehaving log reader client off the island
- oldest->release_Locked();
- } else if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
- oldest->triggerReader_Locked();
- } else {
- oldest->triggerSkip_Locked(id, pruneRows);
- }
+ busy = isBusy(watermark);
+ if (busy) kickMe(oldest, id, pruneRows);
break;
}
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index f0d6fcb..0942987 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -184,6 +184,9 @@
static const log_time pruneMargin;
void maybePrune(log_id_t id);
+ bool isBusy(log_time watermark);
+ void kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows);
+
bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
LogBufferElementCollection::iterator erase(
LogBufferElementCollection::iterator it, bool coalesce = false);