Loading libutils/include/utils/FastStrcmp.h +35 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ #ifndef _ANDROID_UTILS_FASTSTRCMP_H__ #define _ANDROID_UTILS_FASTSTRCMP_H__ #include <ctype.h> #include <string.h> #ifndef __predict_true #define __predict_true(exp) __builtin_expect((exp) != 0, 1) #endif #ifdef __cplusplus // Optimized for instruction cache locality Loading @@ -28,25 +35,41 @@ // // fastcmp<strncmp>(str1, str2, len) // // NB: Does not work for the case insensitive str*cmp functions. // NB: use fasticmp for the case insensitive str*cmp functions. // NB: Returns boolean, do not use if expecting to check negative value. // Thus not semantically identical to the expected function behavior. template <int (*cmp)(const char* l, const char* r, const size_t s)> static inline int fastcmp(const char* l, const char* r, const size_t s) { return (*l != *r) || cmp(l + 1, r + 1, s - 1); const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const char* l, const char* r, const size_t s)> static inline int fasticmp(const char* l, const char* r, const size_t s) { const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((tolower(*l) != tolower(*r)) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const void* l, const void* r, const size_t s)> static inline int fastcmp(const void* lv, const void* rv, const size_t s) { const char* l = static_cast<const char*>(lv); const char* r = static_cast<const char*>(rv); return (*l != *r) || cmp(l + 1, r + 1, s - 1); const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const char* l, const char* r)> static inline int fastcmp(const char* l, const char* r) { return (*l != *r) || cmp(l + 1, r + 1); return (*l != *r) || (__predict_true(*l) && cmp(l + 1, r + 1)); } template <int (*cmp)(const char* l, const char* r)> static inline int fasticmp(const char* l, const char* r) { return (tolower(*l) != tolower(*r)) || (__predict_true(*l) && cmp(l + 1, r + 1)); } #endif Loading logd/LogBuffer.cpp +8 −12 Original line number Diff line number Diff line Loading @@ -132,11 +132,11 @@ static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) { // is it mostly identical? // if (!elem) return DIFFERENT; unsigned short lenl = elem->getMsgLen(); if (!lenl) return DIFFERENT; ssize_t lenl = elem->getMsgLen(); if (lenl <= 0) return DIFFERENT; // value if this represents a chatty elem // if (!last) return DIFFERENT; unsigned short lenr = last->getMsgLen(); if (!lenr) return DIFFERENT; ssize_t lenr = last->getMsgLen(); if (lenr <= 0) return DIFFERENT; // value if this represents a chatty elem // if (elem->getLogId() != last->getLogId()) return DIFFERENT; if (elem->getUid() != last->getUid()) return DIFFERENT; if (elem->getPid() != last->getPid()) return DIFFERENT; Loading @@ -163,8 +163,6 @@ static enum match_type identical(LogBufferElement* elem, } // audit message (except sequence number) identical? static const char avc[] = "): avc: "; if (last->isBinary()) { if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) { Loading @@ -175,6 +173,7 @@ static enum match_type identical(LogBufferElement* elem, msgr += sizeof(android_log_event_string_t); lenr -= sizeof(android_log_event_string_t); } static const char avc[] = "): avc: "; const char* avcl = android::strnstr(msgl, lenl, avc); if (!avcl) return DIFFERENT; lenl -= avcl - msgl; Loading @@ -182,10 +181,7 @@ static enum match_type identical(LogBufferElement* elem, if (!avcr) return DIFFERENT; lenr -= avcr - msgr; if (lenl != lenr) return DIFFERENT; // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)" // condition, it might become superfluous. if (lenl > strlen(avc) && fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) { return DIFFERENT; } Loading Loading @@ -1094,12 +1090,12 @@ log_time LogBuffer::flushTo( // client wants to start from the beginning it = mLogElements.begin(); } else { LogBufferElementCollection::iterator last = mLogElements.begin(); LogBufferElementCollection::iterator last; // 30 second limit to continue search for out-of-order entries. log_time min = start - log_time(30, 0); // Client wants to start from some specified time. Chances are // we are better off starting from the end of the time sorted list. for (it = mLogElements.end(); it != mLogElements.begin(); for (last = it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { --it; LogBufferElement* element = *it; Loading Loading
libutils/include/utils/FastStrcmp.h +35 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ #ifndef _ANDROID_UTILS_FASTSTRCMP_H__ #define _ANDROID_UTILS_FASTSTRCMP_H__ #include <ctype.h> #include <string.h> #ifndef __predict_true #define __predict_true(exp) __builtin_expect((exp) != 0, 1) #endif #ifdef __cplusplus // Optimized for instruction cache locality Loading @@ -28,25 +35,41 @@ // // fastcmp<strncmp>(str1, str2, len) // // NB: Does not work for the case insensitive str*cmp functions. // NB: use fasticmp for the case insensitive str*cmp functions. // NB: Returns boolean, do not use if expecting to check negative value. // Thus not semantically identical to the expected function behavior. template <int (*cmp)(const char* l, const char* r, const size_t s)> static inline int fastcmp(const char* l, const char* r, const size_t s) { return (*l != *r) || cmp(l + 1, r + 1, s - 1); const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const char* l, const char* r, const size_t s)> static inline int fasticmp(const char* l, const char* r, const size_t s) { const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((tolower(*l) != tolower(*r)) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const void* l, const void* r, const size_t s)> static inline int fastcmp(const void* lv, const void* rv, const size_t s) { const char* l = static_cast<const char*>(lv); const char* r = static_cast<const char*>(rv); return (*l != *r) || cmp(l + 1, r + 1, s - 1); const ssize_t n = s; // To help reject negative sizes, treat like zero return __predict_true(n > 0) && ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } template <int (*cmp)(const char* l, const char* r)> static inline int fastcmp(const char* l, const char* r) { return (*l != *r) || cmp(l + 1, r + 1); return (*l != *r) || (__predict_true(*l) && cmp(l + 1, r + 1)); } template <int (*cmp)(const char* l, const char* r)> static inline int fasticmp(const char* l, const char* r) { return (tolower(*l) != tolower(*r)) || (__predict_true(*l) && cmp(l + 1, r + 1)); } #endif Loading
logd/LogBuffer.cpp +8 −12 Original line number Diff line number Diff line Loading @@ -132,11 +132,11 @@ static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) { // is it mostly identical? // if (!elem) return DIFFERENT; unsigned short lenl = elem->getMsgLen(); if (!lenl) return DIFFERENT; ssize_t lenl = elem->getMsgLen(); if (lenl <= 0) return DIFFERENT; // value if this represents a chatty elem // if (!last) return DIFFERENT; unsigned short lenr = last->getMsgLen(); if (!lenr) return DIFFERENT; ssize_t lenr = last->getMsgLen(); if (lenr <= 0) return DIFFERENT; // value if this represents a chatty elem // if (elem->getLogId() != last->getLogId()) return DIFFERENT; if (elem->getUid() != last->getUid()) return DIFFERENT; if (elem->getPid() != last->getPid()) return DIFFERENT; Loading @@ -163,8 +163,6 @@ static enum match_type identical(LogBufferElement* elem, } // audit message (except sequence number) identical? static const char avc[] = "): avc: "; if (last->isBinary()) { if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) { Loading @@ -175,6 +173,7 @@ static enum match_type identical(LogBufferElement* elem, msgr += sizeof(android_log_event_string_t); lenr -= sizeof(android_log_event_string_t); } static const char avc[] = "): avc: "; const char* avcl = android::strnstr(msgl, lenl, avc); if (!avcl) return DIFFERENT; lenl -= avcl - msgl; Loading @@ -182,10 +181,7 @@ static enum match_type identical(LogBufferElement* elem, if (!avcr) return DIFFERENT; lenr -= avcr - msgr; if (lenl != lenr) return DIFFERENT; // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)" // condition, it might become superfluous. if (lenl > strlen(avc) && fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) { return DIFFERENT; } Loading Loading @@ -1094,12 +1090,12 @@ log_time LogBuffer::flushTo( // client wants to start from the beginning it = mLogElements.begin(); } else { LogBufferElementCollection::iterator last = mLogElements.begin(); LogBufferElementCollection::iterator last; // 30 second limit to continue search for out-of-order entries. log_time min = start - log_time(30, 0); // Client wants to start from some specified time. Chances are // we are better off starting from the end of the time sorted list. for (it = mLogElements.end(); it != mLogElements.begin(); for (last = it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { --it; LogBufferElement* element = *it; Loading