(*(ORIG) = atomic_fetch_xor_explicit(RMW, ARG, ORDER), (void) 0)
#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \
(*(ORIG) = atomic_fetch_and_explicit(RMW, ARG, ORDER), (void) 0)
+
+static inline void
+atomic_flag_init(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static inline void
+atomic_flag_destroy(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
} atomic_flag;
#define ATOMIC_FLAG_INIT { .b = false }
+static inline void
+atomic_flag_init(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static inline void
+atomic_flag_destroy(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
static inline bool
atomic_flag_test_and_set_explicit(volatile atomic_flag *object,
memory_order order)
} atomic_flag;
#define ATOMIC_FLAG_INIT { false }
+static inline void
+atomic_flag_init(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static inline void
+atomic_flag_destroy(volatile atomic_flag *object OVS_UNUSED)
+{
+ /* Nothing to do. */
+}
+
static inline bool
atomic_flag_test_and_set(volatile atomic_flag *object)
{
/*
- * Copyright (c) 2013 Nicira, Inc.
+ * Copyright (c) 2013, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "ovs-thread.h"
#if OVS_ATOMIC_PTHREADS_IMPL
+void
+atomic_flag_init(volatile atomic_flag *flag_)
+{
+ atomic_flag *flag = CONST_CAST(atomic_flag *, flag_);
+
+ pthread_mutex_init(&flag->mutex, NULL);
+ atomic_flag_clear(flag_);
+}
+
+void
+atomic_flag_destroy(volatile atomic_flag *flag_)
+{
+ atomic_flag *flag = CONST_CAST(atomic_flag *, flag_);
+
+ pthread_mutex_destroy(&flag->mutex);
+}
+
bool
atomic_flag_test_and_set(volatile atomic_flag *flag_)
{
} atomic_flag;
#define ATOMIC_FLAG_INIT { false, PTHREAD_MUTEX_INITIALIZER }
+void atomic_flag_init(volatile atomic_flag *);
+void atomic_flag_destroy(volatile atomic_flag *);
+
bool atomic_flag_test_and_set(volatile atomic_flag *);
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
* atomic_flag is a typedef for a type with two states, set and clear, that
* provides atomic test-and-set functionality.
*
+ *
+ * Life Cycle
+ * ----------
+ *
* ATOMIC_FLAG_INIT is an initializer for atomic_flag. The initial state is
* "clear".
*
+ * C11 does not have an initialization or destruction function for atomic_flag,
+ * because implementations should not need one (one may simply
+ * atomic_flag_clear() an uninitialized atomic_flag), but some implementations
+ * of the OVS atomics do need them. Thus, the following two functions are
+ * provided for initializing and destroying non-static atomic_flags:
+ *
+ * void atomic_flag_init(volatile atomic_flag *object);
+ *
+ * Initializes 'object'. The initial state is "clear".
+ *
+ * void atomic_flag_destroy(volatile atomic_flag *object);
+ *
+ * Destroys 'object'.
+ *
+ *
+ * Operations
+ * ----------
+ *
* The following functions are available.
*
* bool atomic_flag_test_and_set(atomic_flag *object)