diff options
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/common-utils.h | 15 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/gf-event.h | 4 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 54 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 2 |
5 files changed, 53 insertions, 41 deletions
diff --git a/configure.ac b/configure.ac index 17db0b053f4..d24a7b5cee6 100644 --- a/configure.ac +++ b/configure.ac @@ -911,6 +911,25 @@ if test "x${have_backtrace}" = "xyes"; then fi AC_SUBST(HAVE_BACKTRACE) +dnl Old (before C11) compiler can compile (but not link) this: +dnl +dnl int main () { +dnl _Static_assert(1, "True"); +dnl return 0; +dnl } +dnl +dnl assuming that _Static_assert is an implicitly declared function. So +dnl we're trying to link just to make sure that this is not the case. + +AC_MSG_CHECKING([whether $CC supports C11 _Static_assert]) +AC_TRY_LINK([], [_Static_assert(1, "True");], + [STATIC_ASSERT=yes], [STATIC_ASSERT=no]) + +AC_MSG_RESULT([$STATIC_ASSERT]) +if test x$STATIC_ASSERT = "xyes"; then + AC_DEFINE(HAVE_STATIC_ASSERT, 1, [Define if C11 _Static_assert is supported.]) +fi + if test "x${have_backtrace}" != "xyes"; then AC_TRY_COMPILE([#include <math.h>], [double x=0.0; x=ceil(0.0);], [], diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h index 69c258d678f..1954cca639f 100644 --- a/libglusterfs/src/glusterfs/common-utils.h +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -18,6 +18,7 @@ #include <string.h> #include <assert.h> #include <pthread.h> +#include <unistd.h> #include <openssl/md5.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> @@ -26,6 +27,11 @@ #include <fnmatch.h> #include <uuid/uuid.h> +/* FreeBSD, etc. */ +#ifndef __BITS_PER_LONG +#define __BITS_PER_LONG (CHAR_BIT * (sizeof(long))) +#endif + #ifndef ffsll #define ffsll(x) __builtin_ffsll(x) #endif @@ -441,6 +447,15 @@ BIT_VALUE(unsigned char *array, unsigned int index) } while (0) #endif +/* Compile-time assert, borrowed from Linux kernel. */ +#ifdef HAVE_STATIC_ASSERT +#define GF_STATIC_ASSERT(expr, ...) \ + __gf_static_assert(expr, ##__VA_ARGS__, #expr) +#define __gf_static_assert(expr, msg, ...) _Static_assert(expr, msg) +#else +#define GF_STATIC_ASSERT(expr, ...) +#endif + #define GF_ABORT(msg...) \ do { \ gf_msg_callingfn("", GF_LOG_CRITICAL, 0, LG_MSG_ASSERTION_FAILED, \ diff --git a/libglusterfs/src/glusterfs/gf-event.h b/libglusterfs/src/glusterfs/gf-event.h index c0f05e7c83b..40f8fbdf10a 100644 --- a/libglusterfs/src/glusterfs/gf-event.h +++ b/libglusterfs/src/glusterfs/gf-event.h @@ -12,6 +12,7 @@ #define _GF_EVENT_H_ #include <pthread.h> +#include "common-utils.h" #include "list.h" struct event_pool; @@ -31,6 +32,9 @@ typedef void (*event_handler_t)(int fd, int idx, int gen, void *data, #define EVENT_EPOLL_SLOTS 1024 #define EVENT_MAX_THREADS 1024 +/* See rpcsvc.h to check why. */ +GF_STATIC_ASSERT(EVENT_MAX_THREADS % __BITS_PER_LONG == 0); + struct event_pool { struct event_ops *ops; diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index f7d911bf1c6..eace6eaee31 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -66,59 +66,33 @@ rpcsvc_request_handler(void *arg); static int rpcsvc_match_subnet_v4(const char *addrtok, const char *ipaddr); -void +static void rpcsvc_toggle_queue_status(rpcsvc_program_t *prog, - rpcsvc_request_queue_t *queue, char status[]) + rpcsvc_request_queue_t *queue, + unsigned long status[]) { - int queue_index = 0, status_index = 0, set_bit = 0; - - if (queue != &prog->request_queue[0]) { - queue_index = (queue - &prog->request_queue[0]); - } - - status_index = queue_index / 8; - set_bit = queue_index % 8; + unsigned queue_index = queue - prog->request_queue; - status[status_index] ^= (1 << set_bit); - - return; + status[queue_index / __BITS_PER_LONG] ^= (1UL << (queue_index % + __BITS_PER_LONG)); } int rpcsvc_get_free_queue_index(rpcsvc_program_t *prog) { - int queue_index = 0, max_index = 0, i = 0; - unsigned int right_most_unset_bit = 0; + unsigned i, j = 0; - right_most_unset_bit = 8; - - max_index = gf_roof(EVENT_MAX_THREADS, 8) / 8; - for (i = 0; i < max_index; i++) { - if (prog->request_queue_status[i] == 0) { - right_most_unset_bit = 0; + for (i = 0; i < EVENT_MAX_THREADS / __BITS_PER_LONG; i++) + if (prog->request_queue_status[i] != ULONG_MAX) { + j = __builtin_ctzl(~prog->request_queue_status[i]); break; - } else { - /* get_rightmost_set_bit (sic)*/ - right_most_unset_bit = __builtin_ctz( - ~prog->request_queue_status[i]); - if (right_most_unset_bit < 8) { - break; - } } - } - - if (right_most_unset_bit > 7) { - queue_index = -1; - } else { - queue_index = i * 8; - queue_index += right_most_unset_bit; - } - if (queue_index != -1) { - prog->request_queue_status[i] |= (0x1 << right_most_unset_bit); - } + if (i == EVENT_MAX_THREADS / __BITS_PER_LONG) + return -1; - return queue_index; + prog->request_queue_status[i] |= (1UL << j); + return i * __BITS_PER_LONG + j; } rpcsvc_notify_wrapper_t * diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index a88fc841b60..c370b330572 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -457,7 +457,7 @@ struct rpcsvc_program { gf_boolean_t alive; gf_boolean_t synctask; - char request_queue_status[EVENT_MAX_THREADS / 8 + 1]; + unsigned long request_queue_status[EVENT_MAX_THREADS / __BITS_PER_LONG]; }; typedef struct rpcsvc_cbk_program { |