27
27
#include < unistd.h>
28
28
29
29
#include < unordered_map>
30
+ #include < utility>
30
31
31
32
#include < cutils/properties.h>
32
33
#include < private/android_logger.h>
43
44
// Default
44
45
#define log_buffer_size (id ) mMaxSize [id]
45
46
46
- const log_time LogBuffer::pruneMargin (3 , 0 );
47
-
48
47
void LogBuffer::init () {
49
48
log_id_for_each (i) {
50
49
mLastSet [i] = false ;
@@ -390,59 +389,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
390
389
391
390
// assumes LogBuffer::wrlock() held, owns elem, look after garbage collection
392
391
void LogBuffer::log (LogBufferElement* elem) {
393
- // cap on how far back we will sort in-place, otherwise append
394
- static uint32_t too_far_back = 5 ; // five seconds
395
- // Insert elements in time sorted order if possible
396
- // NB: if end is region locked, place element at end of list
397
- LogBufferElementCollection::iterator it = mLogElements .end ();
398
- LogBufferElementCollection::iterator last = it;
399
- if (__predict_true (it != mLogElements .begin ())) --it;
400
- if (__predict_false (it == mLogElements .begin ()) ||
401
- __predict_true ((*it)->getRealTime () <= elem->getRealTime ()) ||
402
- __predict_false ((((*it)->getRealTime ().tv_sec - too_far_back) >
403
- elem->getRealTime ().tv_sec ) &&
404
- (elem->getLogId () != LOG_ID_KERNEL) &&
405
- ((*it)->getLogId () != LOG_ID_KERNEL))) {
406
- mLogElements .push_back (elem);
407
- } else {
408
- log_time end (log_time::EPOCH);
409
- bool end_set = false ;
410
- bool end_always = false ;
411
-
412
- LogTimeEntry::rdlock ();
413
-
414
- LastLogTimes::iterator times = mTimes .begin ();
415
- while (times != mTimes .end ()) {
416
- LogTimeEntry* entry = times->get ();
417
- if (!entry->mNonBlock ) {
418
- end_always = true ;
419
- break ;
420
- }
421
- // it passing mEnd is blocked by the following checks.
422
- if (!end_set || (end <= entry->mEnd )) {
423
- end = entry->mEnd ;
424
- end_set = true ;
425
- }
426
- times++;
427
- }
428
-
429
- if (end_always || (end_set && (end > (*it)->getRealTime ()))) {
430
- mLogElements .push_back (elem);
431
- } else {
432
- // should be short as timestamps are localized near end()
433
- do {
434
- last = it;
435
- if (__predict_false (it == mLogElements .begin ())) {
436
- break ;
437
- }
438
- --it;
439
- } while (((*it)->getRealTime () > elem->getRealTime ()) &&
440
- (!end_set || (end <= (*it)->getRealTime ())));
441
- mLogElements .insert (last, elem);
442
- }
443
- LogTimeEntry::unlock ();
444
- }
445
-
392
+ mLogElements .push_back (elem);
446
393
stats.add (elem);
447
394
maybePrune (elem->getLogId ());
448
395
}
@@ -614,12 +561,11 @@ class LogBufferElementLast {
614
561
}
615
562
616
563
void clear (LogBufferElement* element) {
617
- log_time current =
618
- element->getRealTime () - log_time (EXPIRE_RATELIMIT, 0 );
564
+ uint64_t current = element->getRealTime ().nsec () - (EXPIRE_RATELIMIT * NS_PER_SEC);
619
565
for (LogBufferElementMap::iterator it = map.begin (); it != map.end ();) {
620
566
LogBufferElement* mapElement = it->second ;
621
- if (( mapElement->getDropped () >= EXPIRE_THRESHOLD) &&
622
- ( current > mapElement->getRealTime ())) {
567
+ if (mapElement->getDropped () >= EXPIRE_THRESHOLD &&
568
+ current > mapElement->getRealTime (). nsec ( )) {
623
569
it = map.erase (it);
624
570
} else {
625
571
++it;
@@ -628,16 +574,6 @@ class LogBufferElementLast {
628
574
}
629
575
};
630
576
631
- // Determine if watermark is within pruneMargin + 1s from the end of the list,
632
- // the caller will use this result to set an internal busy flag indicating
633
- // the prune operation could not be completed because a reader is blocking
634
- // the request.
635
- bool LogBuffer::isBusy (log_time watermark) {
636
- LogBufferElementCollection::iterator ei = mLogElements .end ();
637
- --ei;
638
- return watermark < ((*ei)->getRealTime () - pruneMargin - log_time (1 , 0 ));
639
- }
640
-
641
577
// If the selected reader is blocking our pruning progress, decide on
642
578
// what kind of mitigation is necessary to unblock the situation.
643
579
void LogBuffer::kickMe (LogTimeEntry* me, log_id_t id, unsigned long pruneRows) {
@@ -726,8 +662,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
726
662
}
727
663
times++;
728
664
}
729
- log_time watermark (log_time::tv_sec_max, log_time::tv_nsec_max);
730
- if (oldest) watermark = oldest->mStart - pruneMargin;
731
665
732
666
LogBufferElementCollection::iterator it;
733
667
@@ -749,9 +683,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
749
683
mLastSet [id] = true ;
750
684
}
751
685
752
- if (oldest && (watermark <= element->getRealTime () )) {
753
- busy = isBusy (watermark) ;
754
- if (busy) kickMe (oldest, id, pruneRows);
686
+ if (oldest && oldest-> mStart <= element->getSequence ( )) {
687
+ busy = true ;
688
+ kickMe (oldest, id, pruneRows);
755
689
break ;
756
690
}
757
691
@@ -837,8 +771,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
837
771
while (it != mLogElements .end ()) {
838
772
LogBufferElement* element = *it;
839
773
840
- if (oldest && (watermark <= element->getRealTime () )) {
841
- busy = isBusy (watermark) ;
774
+ if (oldest && oldest-> mStart <= element->getSequence ( )) {
775
+ busy = true ;
842
776
// Do not let chatty eliding trigger any reader mitigation
843
777
break ;
844
778
}
@@ -989,9 +923,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
989
923
mLastSet [id] = true ;
990
924
}
991
925
992
- if (oldest && (watermark <= element->getRealTime () )) {
993
- busy = isBusy (watermark) ;
994
- if (!whitelist && busy ) kickMe (oldest, id, pruneRows);
926
+ if (oldest && oldest-> mStart <= element->getSequence ( )) {
927
+ busy = true ;
928
+ if (!whitelist) kickMe (oldest, id, pruneRows);
995
929
break ;
996
930
}
997
931
@@ -1022,9 +956,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
1022
956
mLastSet [id] = true ;
1023
957
}
1024
958
1025
- if (oldest && (watermark <= element->getRealTime () )) {
1026
- busy = isBusy (watermark) ;
1027
- if (busy) kickMe (oldest, id, pruneRows);
959
+ if (oldest && oldest-> mStart <= element->getSequence ( )) {
960
+ busy = true ;
961
+ kickMe (oldest, id, pruneRows);
1028
962
break ;
1029
963
}
1030
964
@@ -1111,43 +1045,32 @@ unsigned long LogBuffer::getSize(log_id_t id) {
1111
1045
return retval;
1112
1046
}
1113
1047
1114
- log_time LogBuffer::flushTo (SocketClient* reader, const log_time& start,
1115
- pid_t * lastTid, bool privileged, bool security,
1116
- int (*filter)(const LogBufferElement* element,
1117
- void * arg),
1118
- void* arg) {
1048
+ uint64_t LogBuffer::flushTo (SocketClient* reader, uint64_t start, pid_t * lastTid, bool privileged,
1049
+ bool security,
1050
+ int (*filter)(const LogBufferElement* element, void * arg), void* arg) {
1119
1051
LogBufferElementCollection::iterator it;
1120
1052
uid_t uid = reader->getUid ();
1121
1053
1122
1054
rdlock ();
1123
1055
1124
- if (start == log_time::EPOCH ) {
1056
+ if (start <= 1 ) {
1125
1057
// client wants to start from the beginning
1126
1058
it = mLogElements .begin ();
1127
1059
} else {
1128
- // Cap to 300 iterations we look back for out-of-order entries.
1129
- size_t count = 300 ;
1130
-
1131
1060
// Client wants to start from some specified time. Chances are
1132
1061
// we are better off starting from the end of the time sorted list.
1133
- LogBufferElementCollection::iterator last;
1134
- for (last = it = mLogElements .end (); it != mLogElements .begin ();
1062
+ for (it = mLogElements .end (); it != mLogElements .begin ();
1135
1063
/* do nothing */ ) {
1136
1064
--it;
1137
1065
LogBufferElement* element = *it;
1138
- if (element->getRealTime () > start) {
1139
- last = it;
1140
- } else if (element->getRealTime () == start) {
1141
- last = ++it;
1142
- break ;
1143
- } else if (!--count) {
1066
+ if (element->getSequence () <= start) {
1067
+ it++;
1144
1068
break ;
1145
1069
}
1146
1070
}
1147
- it = last;
1148
1071
}
1149
1072
1150
- log_time curr = start;
1073
+ uint64_t curr = start;
1151
1074
1152
1075
LogBufferElement* lastElement = nullptr ; // iterator corruption paranoia
1153
1076
static const size_t maxSkip = 4194304 ; // maximum entries to skip
0 commit comments