From 8f83a35511e4b53ac2850e93571d9154af63f7c0 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 16 Dec 2016 16:09:15 -0800 Subject: [PATCH] logd: correct duplicate message state machine Inspection turned up that for the case of three identical messages, the result would be a stutter of the first message only. Added comments to describe the state machine, incoming variables, outcoming and false condition outputs, for proper maintenance in the future. Test: gTest liblog-benchmarks BM_log_maximum* and manually check for correct midstream chatty messages, Bug: 33535908 Change-Id: I852260d18a484e6207b80063159f1a74eaa83b55 --- logd/LogBuffer.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index d4765964d..3552f7073 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -206,6 +206,68 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, if (currentLast) { LogBufferElement *dropped = droppedElements[log_id]; unsigned short count = dropped ? dropped->getDropped() : 0; + // + // State Init + // incoming: + // dropped = NULL + // currentLast = NULL; + // elem = incoming message + // outgoing: + // dropped = NULL -> State 0 + // currentLast = copy of elem + // log elem + // State 0 + // incoming: + // count = 0 + // dropped = NULL + // currentLast = copy of last message + // elem = incoming message + // outgoing: (if *elem == *currentLast) + // dropped = copy of first identical message -> State 1 + // currentLast = reference to elem + // break: (if *elem != *currentLast) + // dropped = NULL -> State 0 + // delete copy of last message (incoming currentLast) + // currentLast = copy of elem + // log elem + // State 1 + // incoming: + // count = 0 + // dropped = copy of first identical message + // currentLast = reference to last held-back incoming + // message + // elem = incoming message + // outgoing: (if *elem == *currentLast) + // delete copy of first identical message (dropped) + // dropped = reference to last held-back incoming + // message set to chatty count of 1 -> State 2 + // currentLast = reference to elem + // break: + // delete dropped + // dropped = NULL -> State 0 + // log reference to last held-back (currentLast) + // currentLast = copy of elem + // log elem + // State 2 + // incoming: + // count = chatty count + // dropped = chatty message holding count + // currentLast = reference to last held-back incoming + // message. + // dropped = chatty message holding count + // elem = incoming message + // outgoing: (if *elem == *currentLast) + // delete chatty message holding count + // dropped = reference to last held-back incoming + // message, set to chatty count + 1 + // currentLast = reference to elem + // break: + // log dropped (chatty message) + // dropped = NULL -> State 0 + // log reference to last held-back (currentLast) + // currentLast = copy of elem + // log elem + // if (identical(elem, currentLast)) { if (dropped) { if (count == USHRT_MAX) { @@ -226,13 +288,15 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, pthread_mutex_unlock(&mLogElementsLock); return len; } - if (dropped) { - log(dropped); + if (dropped) { // State 1 or 2 + if (count) { // State 2 + log(dropped); // report chatty + } else { // State 1 + delete dropped; + } droppedElements[log_id] = NULL; - } - if (count) { - log(currentLast); - } else { + log(currentLast); // report last message in the series + } else { // State 0 delete currentLast; } }