check_include_file(linux/magic.h HAVE_LINUX_MAGIC_H)
check_include_file(locale.h HAVE_LOCALE_H)
check_include_file(signal.h HAVE_SIGNAL_H)
+check_include_file(stdatomic.h HAVE_STDATOMIC_H)
check_include_file(stdio.h HAVE_STDIO_H) # dbus-sysdeps.h
check_include_files("stdint.h;sys/types.h;sys/event.h" HAVE_SYS_EVENT_H)
check_include_file(sys/inotify.h HAVE_SYS_INOTIFY_H)
/* Define to 1 if you have stdio.h */
#cmakedefine HAVE_STDIO_H 1
+#cmakedefine HAVE_STDATOMIC_H 1
#cmakedefine HAVE_SYSLOG_H 1
#cmakedefine HAVE_SYS_EVENTS_H 1
#cmakedefine HAVE_SYS_INOTIFY_H 1
linux/close_range.h
locale.h
signal.h
+stdatomic.h
sys/prctl.h
sys/random.h
sys/resource.h
#include <systemd/sd-daemon.h>
#endif
-#if !DBUS_USE_SYNC
+#if !defined(HAVE_STDATOMIC_H) && !DBUS_USE_SYNC
#include <pthread.h>
#endif
return getpid ();
}
-#if !DBUS_USE_SYNC
+#if !defined(HAVE_STDATOMIC_H) && !DBUS_USE_SYNC
/* To be thread-safe by default on platforms that don't necessarily have
* atomic operations (notably Debian armel, which is armv4t), we must
* use a mutex that can be initialized statically, like this.
dbus_int32_t
_dbus_atomic_inc (DBusAtomic *atomic)
{
-#if DBUS_USE_SYNC
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "old = *atomic; *atomic += 1; return old" */
+ return atomic_fetch_add (&atomic->value, 1);
+#elif DBUS_USE_SYNC
+ /* Atomic version of "*atomic += 1; return *atomic - 1" */
return __sync_add_and_fetch(&atomic->value, 1)-1;
#else
dbus_int32_t res;
dbus_int32_t
_dbus_atomic_dec (DBusAtomic *atomic)
{
-#if DBUS_USE_SYNC
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "old = *atomic; *atomic -= 1; return old" */
+ return atomic_fetch_sub (&atomic->value, 1);
+#elif DBUS_USE_SYNC
+ /* Atomic version of "*atomic -= 1; return *atomic + 1" */
return __sync_sub_and_fetch(&atomic->value, 1)+1;
#else
dbus_int32_t res;
dbus_int32_t
_dbus_atomic_get (DBusAtomic *atomic)
{
-#if DBUS_USE_SYNC
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "return *atomic" */
+ return atomic_load (&atomic->value);
+#elif DBUS_USE_SYNC
__sync_synchronize ();
return atomic->value;
#else
void
_dbus_atomic_set_zero (DBusAtomic *atomic)
{
-#if DBUS_USE_SYNC
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "*atomic = 0" */
+ atomic_store (&atomic->value, 0);
+#elif DBUS_USE_SYNC
/* Atomic version of "*atomic &= 0; return *atomic" */
__sync_and_and_fetch (&atomic->value, 0);
#else
void
_dbus_atomic_set_nonzero (DBusAtomic *atomic)
{
-#if DBUS_USE_SYNC
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "*atomic = 1" */
+ atomic_store (&atomic->value, 1);
+#elif DBUS_USE_SYNC
/* Atomic version of "*atomic |= 1; return *atomic" */
__sync_or_and_fetch (&atomic->value, 1);
#else
dbus_int32_t
_dbus_atomic_inc (DBusAtomic *atomic)
{
- // +/- 1 is needed here!
- // no volatile argument with mingw
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "old = *atomic; *atomic += 1; return old" */
+ return atomic_fetch_add (&atomic->value, 1);
+#else
+ /* Atomic version of "*atomic += 1; return *atomic - 1" */
return InterlockedIncrement (&atomic->value) - 1;
+#endif
}
/**
dbus_int32_t
_dbus_atomic_dec (DBusAtomic *atomic)
{
- // +/- 1 is needed here!
- // no volatile argument with mingw
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "old = *atomic; *atomic -= 1; return old" */
+ return atomic_fetch_sub (&atomic->value, 1);
+#else
+ /* Atomic version of "*atomic -= 1; return *atomic + 1" */
return InterlockedDecrement (&atomic->value) + 1;
+#endif
}
/**
dbus_int32_t
_dbus_atomic_get (DBusAtomic *atomic)
{
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "return *atomic" */
+ return atomic_load (&atomic->value);
+#else
/* In this situation, GLib issues a MemoryBarrier() and then returns
* atomic->value. However, mingw from mingw.org (not to be confused with
* mingw-w64 from mingw-w64.sf.net) does not have MemoryBarrier in its
InterlockedExchange (&dummy, 1);
return atomic->value;
+#endif
}
/**
void
_dbus_atomic_set_zero (DBusAtomic *atomic)
{
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "*atomic = 0" */
+ atomic_store (&atomic->value, 0);
+#else
InterlockedExchange (&atomic->value, 0);
+#endif
}
/**
void
_dbus_atomic_set_nonzero (DBusAtomic *atomic)
{
+#ifdef HAVE_STDATOMIC_H
+ /* Atomic version of "*atomic = 1" */
+ atomic_store (&atomic->value, 1);
+#else
InterlockedExchange (&atomic->value, 1);
+#endif
}
/**
#include <inttypes.h>
#endif
+#ifdef HAVE_STDATOMIC_H
+#include <stdatomic.h>
+#endif
+
#include <dbus/dbus-errors.h>
#include <dbus/dbus-file.h>
#include <dbus/dbus-string.h>
*/
struct DBusAtomic
{
-#ifdef DBUS_WIN
+#ifdef HAVE_STDATOMIC_H
+ atomic_int value; /**< Value of the atomic integer. */
+#elif defined(DBUS_WIN)
volatile long value; /**< Value of the atomic integer. */
#else
volatile dbus_int32_t value; /**< Value of the atomic integer. */
'linux/magic.h',
'locale.h',
'signal.h',
+ 'stdatomic.h',
'syslog.h',
'sys/prctl.h',
'sys/random.h',