From 91b1fc555899408595f2be440a3295ed5594e93c Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 25 Aug 2010 10:26:22 -0700 Subject: [PATCH] ibacm: support distros with older versions of gcc ibacm implements atomics using gcc intrinsics that were introduced in gcc 4.1.2. If an older version of gcc is used to compile the code, an error results. Check that the required atomic calls are supported, and if not, provide our own implementation. This fixes a build issue on RH 5.x. Signed-off-by: Sean Hefty --- configure.in | 10 ++++++++++ linux/osd.h | 32 ++++++++++++++++++++++++++++++-- src/acm.c | 8 ++++++++ src/acme.c | 4 ++++ src/libacm.c | 4 ++++ windows/osd.h | 1 + 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 997c775..dfddeac 100644 --- a/configure.in +++ b/configure.in @@ -39,6 +39,16 @@ AC_CHECK_HEADER(infiniband/umad.h, [], AC_MSG_ERROR([ not found. Is libibumad installed?])) fi +dnl Check for gcc atomic intrinsics +AC_MSG_CHECKING(compiler support for atomics) +AC_TRY_LINK([int i = 0;], + [ return __sync_add_and_fetch(&i, 1) != __sync_sub_and_fetch(&i, 1); ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_DEFINE(DEFINE_ATOMICS, 1, [Set to 1 to implement atomics]) + ]) + AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script, if test -n "`$LD --help < /dev/null 2>/dev/null | grep version-script`"; then ac_cv_version_script=yes diff --git a/linux/osd.h b/linux/osd.h index 722e1b1..28c3647 100644 --- a/linux/osd.h +++ b/linux/osd.h @@ -65,9 +65,37 @@ #endif #define ntohll(x) htonll(x) +#if DEFINE_ATOMICS +typedef struct { pthread_mutex_t mut; int val; } atomic_t; +static inline int atomic_inc(atomic_t *atomic) +{ + int v; + + pthread_mutex_lock(&atomic->mut); + v = ++(atomic->val); + pthread_mutex_unlock(&atomic->mut); + return v; +} +static inline int atomic_dec(atomic_t *atomic) +{ + int v; + + pthread_mutex_lock(&atomic->mut); + v = --(atomic->val); + pthread_mutex_unlock(&atomic->mut); + return v; +} +static inline void atomic_init(atomic_t *atomic) +{ + pthread_mutex_init(&atomic->mut, NULL); + atomic->val = 0; +} +#else typedef struct { volatile int val; } atomic_t; -#define atomic_inc(v) (__sync_fetch_and_add(&(v)->val, 1) + 1) -#define atomic_dec(v) (__sync_fetch_and_sub(&(v)->val, 1) - 1) +#define atomic_inc(v) (__sync_add_and_fetch(&(v)->val, 1)) +#define atomic_dec(v) (__sync_sub_and_fetch(&(v)->val, 1)) +#define atomic_init(v) ((v)->val = 0) +#endif #define atomic_get(v) ((v)->val) #define atomic_set(v, s) ((v)->val = s) diff --git a/src/acm.c b/src/acm.c index 7c8b84b..820365c 100644 --- a/src/acm.c +++ b/src/acm.c @@ -27,6 +27,10 @@ * SOFTWARE. */ +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + #include #include #include @@ -268,6 +272,7 @@ acm_init_dest(struct acm_dest *dest, uint8_t addr_type, uint8_t *addr, size_t si memcpy(dest->address, addr, size); dest->addr_type = addr_type; DListInit(&dest->req_queue); + atomic_init(&dest->refcnt); atomic_set(&dest->refcnt, 1); lock_init(&dest->lock); } @@ -1560,6 +1565,7 @@ static void acm_init_server(void) lock_init(&client[i].lock); client[i].index = i; client[i].sock = INVALID_SOCKET; + atomic_init(&client[i].refcnt); } } @@ -2680,6 +2686,8 @@ int CDECL_FUNC main(int argc, char **argv) acm_log(0, "Assistant to the InfiniBand Communication Manager\n"); acm_log_options(); + atomic_init(&tid); + atomic_init(&wait_cnt); DListInit(&dev_list); DListInit(&timeout_list); event_init(&timeout_event); diff --git a/src/acme.c b/src/acme.c index 7428a57..e03679f 100644 --- a/src/acme.c +++ b/src/acme.c @@ -27,6 +27,10 @@ * SOFTWARE. */ +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + #include #include #include diff --git a/src/libacm.c b/src/libacm.c index 32fd7e2..9d56cd2 100644 --- a/src/libacm.c +++ b/src/libacm.c @@ -27,6 +27,10 @@ * SOFTWARE. */ +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + #include #include "libacm.h" #include diff --git a/windows/osd.h b/windows/osd.h index 10e5e18..9587c51 100644 --- a/windows/osd.h +++ b/windows/osd.h @@ -44,6 +44,7 @@ typedef struct { volatile LONG val; } atomic_t; #define atomic_dec(v) InterlockedDecrement(&(v)->val) #define atomic_get(v) ((v)->val) #define atomic_set(v, s) ((v)->val = s) +#define atomic_init(v) ((v)->val = 0) #define event_t HANDLE #define event_init(e) *(e) = CreateEvent(NULL, FALSE, FALSE, NULL) -- 2.41.0