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],
lib_LTLIBRARIES = libcoloredstderr.la
libcoloredstderr_la_SOURCES = coloredstderr.c \
+ compiler.h \
constants.h \
debug.h \
hookmacros.h \
#include "constants.h"
+#include "compiler.h"
#ifdef DEBUG
# include "debug.h"
#endif
debug("%3d -> %3d\t\t\t[%d]\n", oldfd, newfd, getpid());
#endif
- if (!initialized) {
+ if (unlikely(!initialized)) {
init_from_environment();
}
debug("%3d -> .\t\t\t[%d]\n", fd, getpid());
#endif
- if (!initialized) {
+ if (unlikely(!initialized)) {
init_from_environment();
}
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();
}
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();
}
--- /dev/null
+/*
+ * 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
#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(); \
} \
}
_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;