Commit e9582c7f authored by Maria Matejka's avatar Maria Matejka
Browse files

Worker: Add atomic fallback for gcc 4.4 -- 4.8

Anyway, we suggest using a compiler that supports atomic_* calls.
We don't guarantee that this will work in all cases .
parent f001e32c
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -22,6 +22,30 @@ AC_DEFUN([BIRD_CHECK_THREAD_LOCAL],
  )
])

AC_DEFUN([BIRD_CHECK_OLD_SYNC],
[
  AC_CACHE_CHECK(
    [whether GCC old-style __sync_* calls are available],
    [bird_cv_old_sync],
    [
      AC_COMPILE_IFELSE([
	AC_LANG_PROGRAM([
	  #include <stdint.h>
	], [
	  uint64_t value = 0;
	  __sync_fetch_and_add(&value, 64);
	  __sync_fetch_and_sub(&value, 42);
	  uint64_t old = __sync_val_compare_and_swap(&value, 22, 64);
	])
      ],
      [bird_cv_old_sync=yes],
      [bird_cv_old_sync=no],
      )
    ]
  )
])


AC_DEFUN([BIRD_CHECK_PTHREADS],
[
  bird_tmp_cflags="$CFLAGS"
+11 −0
Original line number Diff line number Diff line
@@ -129,6 +129,17 @@ elif test "$bird_cv_thread_local" = old ; then
  AC_DEFINE([HAVE_OLD_THREAD_LOCAL], [1], [Define to 1 if _Thread_local has to be defined as __thread])
fi

AC_CHECK_HEADER([stdatomic.h],
		[AC_DEFINE([HAVE_ATOMIC], [1], [Define to 1 if stdatomic.h is present])],
		[
		BIRD_CHECK_OLD_SYNC
		if test "$bird_cv_old_sync" = no ; then
		  AC_MSG_ERROR([No atomic operations available.])
		fi
		],
		[]
		)

if test "$enable_pthreads" != no ; then
  BIRD_CHECK_PTHREADS

lib/atomic.h

0 → 100644
+36 −0
Original line number Diff line number Diff line
#ifndef _BIRD_ATOMIC_H_
#define _BIRD_ATOMIC_H_

#if HAVE_ATOMIC
#include <stdatomic.h>
#else

#define _Atomic

#define atomic_load(ptr) __sync_val_compare_and_swap(ptr, 0, 0)
#define atomic_load_explicit(ptr, mem) atomic_load(ptr)
#define atomic_store(ptr, val) __sync_lock_test_and_set(ptr, val)

#define atomic_fetch_add(ptr, val) __sync_fetch_and_add((ptr), (val))
#define atomic_fetch_add_explicit(ptr, val, memory) __sync_fetch_and_add((ptr), (val))
#define atomic_fetch_sub(ptr, val) __sync_fetch_and_sub((ptr), (val))
#define atomic_fetch_sub_explicit(ptr, val, memory) __sync_fetch_and_sub((ptr), (val))

#define atomic_compare_exchange_weak(ptr, desired, wanted) ({ \
    typeof(desired) _desptr = desired; /* save the pointer */ \
    typeof(*_desptr) _old = __sync_val_compare_and_swap(ptr, *_desptr, wanted); /* do the exchange */ \
    int result = _old == *_desptr; /* get the return value */ \
    *_desptr = _old; /* store the old value */ \
    result; /* and return */ })

#define atomic_compare_exchange_strong(ptr, desired, wanted) \
  atomic_compare_exchange_weak(ptr, desired, wanted)

#define atomic_compare_exchange_weak_explicit(ptr, desired, wanted, success, failure) \
  atomic_compare_exchange_weak(ptr, desired, wanted)

#define atomic_compare_exchange_strong_explicit(ptr, desired, wanted, success, failure) \
  atomic_compare_exchange_weak(ptr, desired, wanted)

#endif
#endif
+1 −2
Original line number Diff line number Diff line
@@ -44,8 +44,7 @@
#include "lib/string.h"
#include "lib/alloca.h"
#include "lib/worker.h"

#include <stdatomic.h>
#include "lib/atomic.h"

pool *rt_table_pool;

+4 −3
Original line number Diff line number Diff line
@@ -15,10 +15,11 @@

#include "conf/conf.h"

#include "lib/atomic.h"

#include <errno.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdatomic.h>
#include <pthread.h>
#include <unistd.h>

@@ -421,11 +422,11 @@ static struct resclass domain_resclass = {
  .memsize = NULL
};

_Thread_local static struct locked_domain {
static _Thread_local struct locked_domain {
  struct domain *domain;
  int write;
} *locked_domains = NULL;
_Thread_local static uint locked_max = 0, locked_cnt = 0;
static _Thread_local uint locked_max = 0, locked_cnt = 0;

struct domain *
domain_new(pool *p)
Loading