From: Ben Pfaff Date: Thu, 9 Jan 2014 01:13:28 +0000 (-0800) Subject: ovs-atomic: New functions atomic_flag_init(), atomic_flag_destroy(). X-Git-Tag: sliver-openvswitch-2.1.90-1~10^2~38 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=4597d2a57226eaec787d6501e88ab32f3b6209e1;p=sliver-openvswitch.git ovs-atomic: New functions atomic_flag_init(), atomic_flag_destroy(). Standard C11 doesn't need these functions because it is able to require implementations not to need them. But we can't construct a portable implementation that does not need them in every case, so this commit adds them. These functions are only needed for atomic_flag objects that are dynamically allocated (because statically allocated objects can use ATOMIC_FLAG_INIT). So far there aren't any of those, but an upcoming commit will introduce one. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- diff --git a/lib/ovs-atomic-c11.h b/lib/ovs-atomic-c11.h index 9dc687c0d..97262b27b 100644 --- a/lib/ovs-atomic-c11.h +++ b/lib/ovs-atomic-c11.h @@ -60,3 +60,15 @@ typedef _Atomic(int64_t) atomic_int64_t; (*(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. */ +} diff --git a/lib/ovs-atomic-flag-gcc4.7+.h b/lib/ovs-atomic-flag-gcc4.7+.h index c42c7cad8..385d0de92 100644 --- a/lib/ovs-atomic-flag-gcc4.7+.h +++ b/lib/ovs-atomic-flag-gcc4.7+.h @@ -26,6 +26,18 @@ typedef struct { } 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) diff --git a/lib/ovs-atomic-gcc4+.h b/lib/ovs-atomic-gcc4+.h index 4476162b3..4938261ee 100644 --- a/lib/ovs-atomic-gcc4+.h +++ b/lib/ovs-atomic-gcc4+.h @@ -238,6 +238,18 @@ typedef struct { } 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) { diff --git a/lib/ovs-atomic-pthreads.c b/lib/ovs-atomic-pthreads.c index a501b8256..731113596 100644 --- a/lib/ovs-atomic-pthreads.c +++ b/lib/ovs-atomic-pthreads.c @@ -1,5 +1,5 @@ /* - * 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. @@ -20,6 +20,23 @@ #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_) { diff --git a/lib/ovs-atomic-pthreads.h b/lib/ovs-atomic-pthreads.h index 2f47a9c97..840c7a641 100644 --- a/lib/ovs-atomic-pthreads.h +++ b/lib/ovs-atomic-pthreads.h @@ -148,6 +148,9 @@ typedef struct { } 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); diff --git a/lib/ovs-atomic.h b/lib/ovs-atomic.h index a9ae4aec5..e7141145b 100644 --- a/lib/ovs-atomic.h +++ b/lib/ovs-atomic.h @@ -204,9 +204,31 @@ * 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)