]> ruderich.org/simon Gitweb - coloredstderr/coloredstderr.git/commitdiff
Use likely()/unlikely() macros to improve branch prediction.
authorSimon Ruderich <simon@ruderich.org>
Mon, 10 Jun 2013 04:06:00 +0000 (06:06 +0200)
committerSimon Ruderich <simon@ruderich.org>
Mon, 10 Jun 2013 12:05:51 +0000 (14:05 +0200)
configure.ac
src/Makefile.am
src/coloredstderr.c
src/compiler.h [new file with mode: 0644]
src/hookmacros.h

index 6248625db45315e73f11a1899cf0cf6b8e8b93ac..ec5b65898d6d14f161557937e89f17406eb71732 100644 (file)
@@ -47,6 +47,14 @@ AC_C_INLINE
 AC_FUNC_FORK
 AC_CHECK_FUNCS([dup2 memmove setenv strdup])
 
+dnl Thanks to gperftools' configure.ac (https://code.google.com/p/gperftools).
+AC_MSG_CHECKING([for __builtin_expect])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([],[return __builtin_expect(main != 0, 1)])],
+               [AC_DEFINE([HAVE___BUILTIN_EXPECT], 1,
+                          [Define to 1 if the compiler supports __builtin_expect().])
+                AC_MSG_RESULT([yes])],
+               [AC_MSG_RESULT([no])])
+
 AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([dlsym() is required])])
 
 AC_ARG_ENABLE([debug],
index b62b114041e0d615c6b5c3784fb0af835b39cb23..1526e1d5eafc640df46936b89fd9cff40b26fc8e 100644 (file)
@@ -1,5 +1,6 @@
 lib_LTLIBRARIES             = libcoloredstderr.la
 libcoloredstderr_la_SOURCES = coloredstderr.c \
+                              compiler.h \
                               constants.h \
                               debug.h \
                               hookmacros.h \
index a95486dc4be6bbf865aaef66718ab8eefdf7b061..72a881fb866ab12e0e92188c58456e4e2979c1a7 100644 (file)
@@ -51,6 +51,7 @@ static int force_write_to_non_tty;
 
 
 #include "constants.h"
+#include "compiler.h"
 #ifdef DEBUG
 # include "debug.h"
 #endif
@@ -68,7 +69,7 @@ static void dup_fd(int oldfd, int newfd) {
     debug("%3d -> %3d\t\t\t[%d]\n", oldfd, newfd, getpid());
 #endif
 
-    if (!initialized) {
+    if (unlikely(!initialized)) {
         init_from_environment();
     }
 
@@ -90,7 +91,7 @@ static void close_fd(int fd) {
     debug("%3d ->   .\t\t\t[%d]\n", fd, getpid());
 #endif
 
-    if (!initialized) {
+    if (unlikely(!initialized)) {
         init_from_environment();
     }
 
@@ -124,7 +125,7 @@ inline static void init_pre_post_string(void) {
 static void handle_fd_pre(int fd) {
     int saved_errno = errno;
 
-    if (!pre_string || !post_string) {
+    if (unlikely(!pre_string || !post_string)) {
         init_pre_post_string();
     }
 
@@ -145,7 +146,7 @@ static void handle_fd_post(int fd) {
 static void handle_file_pre(FILE *stream) {
     int saved_errno = errno;
 
-    if (!pre_string || !post_string) {
+    if (unlikely(!pre_string || !post_string)) {
         init_pre_post_string();
     }
 
diff --git a/src/compiler.h b/src/compiler.h
new file mode 100644 (file)
index 0000000..3d92f2f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Compiler specific macros.
+ *
+ * Copyright (C) 2013  Simon Ruderich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H 1
+
+/* Branch prediction information for the compiler. */
+#ifdef HAVE___BUILTIN_EXPECT
+# define likely(x)   __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define likely(x)   x
+# define unlikely(x) x
+#endif
+
+#endif
index 35e64703ddcc1933891ea8645d155c6edea9282f..0eb47cd67abd45451dc85b02e0573a7e04119ced 100644 (file)
 
 #define _HOOK_PRE(type, name) \
         int handle; \
-        if (!(real_ ## name )) { \
+        if (unlikely(!(real_ ## name ))) { \
             *(void **) (&(real_ ## name)) = dlsym_function(#name); \
             /* Initialize our data while we're at it. */ \
-            if (!initialized) { \
+            if (unlikely(!initialized)) { \
                 init_from_environment(); \
             } \
         }
@@ -68,8 +68,8 @@
         _HOOK_PRE_FD_(type, name, fd)
 #define _HOOK_PRE_FD_(type, name, fd) \
         _HOOK_PRE(type, name) \
-        if (tracked_fds_find(fd)) { \
-            if (force_write_to_non_tty) { \
+        if (unlikely(tracked_fds_find(fd))) { \
+            if (unlikely(force_write_to_non_tty)) { \
                 handle = 1; \
             } else { \
                 handle = isatty(fd); \
         } else { \
             handle = 0; \
         } \
-        if (handle) { \
+        if (unlikely(handle)) { \
             handle_fd_pre(fd); \
         }
 #define _HOOK_PRE_FILE(type, name, file) \
         type result; \
         _HOOK_PRE(type, name) \
-        if (tracked_fds_find(fileno(file))) { \
-            if (force_write_to_non_tty) { \
+        if (unlikely(tracked_fds_find(fileno(file)))) { \
+            if (unlikely(force_write_to_non_tty)) { \
                 handle = 1; \
             } else { \
                 handle = isatty(fileno(file)); \
         } else { \
             handle = 0; \
         } \
-        if (handle) { \
+        if (unlikely(handle)) { \
             handle_file_pre(file); \
         }
 #define _HOOK_POST_FD_(fd) \
-        if (handle) { \
+        if (unlikely(handle)) { \
             handle_fd_post(fd); \
         }
 #define _HOOK_POST_FD(fd) \
         _HOOK_POST_FD_(fd) \
         return result;
 #define _HOOK_POST_FILE(file) \
-        if (handle) { \
+        if (unlikely(handle)) { \
             handle_file_post(file); \
         } \
         return result;