Merge "utils: Add FastStrcmp.h"
This commit is contained in:
commit
0f8890d985
7 changed files with 71 additions and 33 deletions
54
include/utils/FastStrcmp.h
Normal file
54
include/utils/FastStrcmp.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_UTILS_FASTSTRCMP_H__
|
||||
#define _ANDROID_UTILS_FASTSTRCMP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// Optimized for instruction cache locality
|
||||
//
|
||||
// Template class fastcmp used to create more time-efficient str*cmp
|
||||
// functions by pre-checking the first character before resorting
|
||||
// to calling the underlying string function. Profiled with a
|
||||
// measurable speedup when used in hot code. Usage is of the form:
|
||||
//
|
||||
// fastcmp<strncmp>(str1, str2, len)
|
||||
//
|
||||
// NB: Does not work 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _ANDROID_UTILS_FASTSTRCMP_H__
|
|
@ -89,7 +89,7 @@ char *android::tidToName(pid_t tid) {
|
|||
size_t name_len = strlen(name);
|
||||
// KISS: ToDo: Only checks prefix truncated, not suffix, or both
|
||||
if ((retval_len < name_len)
|
||||
&& !fast<strcmp>(retval, name + name_len - retval_len)) {
|
||||
&& !fastcmp<strcmp>(retval, name + name_len - retval_len)) {
|
||||
free(retval);
|
||||
retval = name;
|
||||
} else {
|
||||
|
|
|
@ -321,7 +321,7 @@ static const char *strnstr(const char *s, size_t len, const char *needle) {
|
|||
}
|
||||
--len;
|
||||
} while (*s++ != c);
|
||||
} while (fast<memcmp>(s, needle, needleLen));
|
||||
} while (fastcmp<memcmp>(s, needle, needleLen));
|
||||
s--;
|
||||
}
|
||||
return s;
|
||||
|
@ -640,7 +640,7 @@ int LogKlog::log(const char *buf, size_t len) {
|
|||
|
||||
static const char infoBrace[] = "[INFO]";
|
||||
static const size_t infoBraceLen = strlen(infoBrace);
|
||||
if ((taglen >= infoBraceLen) && !fast<strncmp>(p, infoBrace, infoBraceLen)) {
|
||||
if ((taglen >= infoBraceLen) && !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) {
|
||||
// <PRI>[<TIME>] "[INFO]"<tag> ":" message
|
||||
bt = p + infoBraceLen;
|
||||
taglen -= infoBraceLen;
|
||||
|
@ -675,7 +675,7 @@ int LogKlog::log(const char *buf, size_t len) {
|
|||
p = cp + 1;
|
||||
} else if ((taglen > size) && (tolower(*bt) == tolower(*cp))) {
|
||||
// clean up any tag stutter
|
||||
if (!fast<strncasecmp>(bt + 1, cp + 1, size - 1)) { // no match
|
||||
if (!fastcmp<strncasecmp>(bt + 1, cp + 1, size - 1)) { // no match
|
||||
// <PRI>[<TIME>] <tag> <tag> : message
|
||||
// <PRI>[<TIME>] <tag> <tag>: message
|
||||
// <PRI>[<TIME>] <tag> '<tag>.<num>' : message
|
||||
|
@ -697,8 +697,8 @@ int LogKlog::log(const char *buf, size_t len) {
|
|||
static const char host[] = "_host";
|
||||
static const size_t hostlen = strlen(host);
|
||||
if ((size > hostlen) &&
|
||||
!fast<strncmp>(bt + size - hostlen, host, hostlen) &&
|
||||
!fast<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) {
|
||||
!fastcmp<strncmp>(bt + size - hostlen, host, hostlen) &&
|
||||
!fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) {
|
||||
const char *b = cp;
|
||||
cp += size - hostlen;
|
||||
taglen -= size - hostlen;
|
||||
|
@ -746,10 +746,10 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':'));
|
|||
// register names like x18 but not driver names like en0
|
||||
|| ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2])))
|
||||
// blacklist
|
||||
|| ((size == cpuLen) && !fast<strncmp>(tag, cpu, cpuLen))
|
||||
|| ((size == warningLen) && !fast<strncasecmp>(tag, warning, warningLen))
|
||||
|| ((size == errorLen) && !fast<strncasecmp>(tag, error, errorLen))
|
||||
|| ((size == infoLen) && !fast<strncasecmp>(tag, info, infoLen))) {
|
||||
|| ((size == cpuLen) && !fastcmp<strncmp>(tag, cpu, cpuLen))
|
||||
|| ((size == warningLen) && !fastcmp<strncasecmp>(tag, warning, warningLen))
|
||||
|| ((size == errorLen) && !fastcmp<strncasecmp>(tag, error, errorLen))
|
||||
|| ((size == infoLen) && !fastcmp<strncasecmp>(tag, info, infoLen))) {
|
||||
p = start;
|
||||
etag = tag = "";
|
||||
}
|
||||
|
@ -761,7 +761,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':'));
|
|||
const char *mp = strnrchr(tag, ']', taglen);
|
||||
if (mp && (++mp < etag)) {
|
||||
size_t s = etag - mp;
|
||||
if (((s + s) < taglen) && !fast<memcmp>(mp, mp - 1 - s, s)) {
|
||||
if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) {
|
||||
taglen = mp - tag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ bool LogReader::onDataAvailable(SocketClient *cli) {
|
|||
}
|
||||
|
||||
bool nonBlock = false;
|
||||
if (!fast<strncmp>(buffer, "dumpAndClose", 12)) {
|
||||
if (!fastcmp<strncmp>(buffer, "dumpAndClose", 12)) {
|
||||
// Allow writer to get some cycles, and wait for pending notifications
|
||||
sched_yield();
|
||||
LogTimeEntry::lock();
|
||||
|
|
|
@ -53,7 +53,7 @@ char *pidToName(pid_t pid) {
|
|||
if (ret > 0) {
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
// frameworks intermediate state
|
||||
if (fast<strcmp>(buffer, "<pre-initialized>")) {
|
||||
if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
|
||||
retval = strdup(buffer);
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ const char *LogStatistics::uidToName(uid_t uid) const {
|
|||
if (nameTmp) {
|
||||
if (!name) {
|
||||
name = strdup(nameTmp);
|
||||
} else if (fast<strcmp>(name, nameTmp)) {
|
||||
} else if (fastcmp<strcmp>(name, nameTmp)) {
|
||||
free(const_cast<char *>(name));
|
||||
name = NULL;
|
||||
break;
|
||||
|
|
|
@ -307,7 +307,7 @@ struct PidEntry : public EntryBaseDropped {
|
|||
const char*getName() const { return name; }
|
||||
|
||||
inline void add(pid_t newPid) {
|
||||
if (name && !fast<strncmp>(name, "zygote", 6)) {
|
||||
if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
|
||||
free(name);
|
||||
name = NULL;
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ struct TidEntry : public EntryBaseDropped {
|
|||
const char*getName() const { return name; }
|
||||
|
||||
inline void add(pid_t incomingTid) {
|
||||
if (name && !fast<strncmp>(name, "zygote", 6)) {
|
||||
if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
|
||||
free(name);
|
||||
name = NULL;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/FastStrcmp.h>
|
||||
#include <private/android_logger.h>
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
|
@ -50,21 +51,4 @@ static inline bool worstUidEnabledForLogid(log_id_t id) {
|
|||
(id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS);
|
||||
}
|
||||
|
||||
template <int (*cmp)(const char *l, const char *r, const size_t s)>
|
||||
static inline int fast(const char *l, const char *r, const size_t s) {
|
||||
return (*l != *r) || cmp(l + 1, r + 1, s - 1);
|
||||
}
|
||||
|
||||
template <int (*cmp)(const void *l, const void *r, const size_t s)>
|
||||
static inline int fast(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);
|
||||
}
|
||||
|
||||
template <int (*cmp)(const char *l, const char *r)>
|
||||
static inline int fast(const char *l, const char *r) {
|
||||
return (*l != *r) || cmp(l + 1, r + 1);
|
||||
}
|
||||
|
||||
#endif // _LOGD_LOG_UTILS_H__
|
||||
|
|
Loading…
Reference in a new issue