Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f8890d9 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge "utils: Add FastStrcmp.h"

parents aece4251 0eeb06b9
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
/*
 * 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__
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+10 −10
Original line number Diff line number Diff line
@@ -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;
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -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();
+2 −2
Original line number Diff line number Diff line
@@ -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;
Loading