atomic_ops.txt has incorrect, misleading and insufficient information
PATCH 1/1 atomic_ops.txt has incorrect, misleading and insufficient information
From: Matti Linnanvuori <[email protected]>
atomic_ops.txt has incorrect, misleading and insufficient
information about semantics of initializer, atomic_set, atomic_read and atomic_xchg. It also incorrectly implies that operations mentioned above are not actual atomic operations. Included is most of the patch Document non-semantics of atomic_read() and atomic_set() by Chris Snook, except the word "assignment".
Signed-off-by Matti Linnanvuori <[email protected]>
---
Documentation-atomic_ops.txt 2007-09-15 09:56:16.136312500 +0300 renamed from Documentation-atomic_ops.txt 2007-09-14 23:49:20.126251500 +0300 +52 -3
@@ -12,7 +12,11 @@ Also, it should be made opaque such that C integer type will fail. Something like the following should suffice: - typedef struct { volatile int counter; } atomic_t; + typedef struct { int counter; } atomic_t; + + Historically, counter has been declared volatile. This is now +discouraged. See Documentation/volatile-considered-harmful.txt for the +complete rationale. The first operations to implement for atomic_t's are the initializers and plain reads.
@@ -24,6 +28,13 @@ The first macro is used in definitions, static atomic_t my_counter = ATOMIC_INIT(1); +The initializer is atomic in that the return values of the atomic +operations are guaranteed to be correct reflecting the initialized +value if the initializer is used before runtime. If the initializer +is used at runtime, a proper implicit or explicit read memory barrier +is needed before reading the value with atomic_read from another +thread. + The second interface can be used at runtime, as in: struct foo { atomic_t counter; };
@@ -36,13 +47,45 @@ The second interface can be used at runt return -ENOMEM; atomic_set(&k->counter, 0); +The setting is atomic in that the return values of the atomic +operations by all threads are guaranteed to be correct reflecting +either the value before the setting or the value that has been set +with this setting. A proper implicit or explicit memory barrier is +needed before the value set with the operation is guaranteed to be +readable with atomic_read from another thread. + Next, we have: #define atomic_read(v) ((v)->counter) -which simply reads the current value of the counter. +which simply reads the counter value currently visible to the calling +thread. The read is atomic in that the return value is guaranteed to +be one of the values initialized or modified with the interface +operations if a proper implicit or explicit memory barrier is used +after possible runtime initialization by any other thread and the +value is modified only with the interface operations. atomic_read +does not guarantee that the runtime initialization by any other +thread is visible yet, so the user of the interface must take care of +that with a proper implicit or explicit memory barrier. + +*** WARNING: atomic_read() and atomic_set() DO NOT IMPLY BARRIERS! *** + +Some architectures may choose to use the volatile keyword, barriers, or +inline assembly to guarantee some degree of immediacy for atomic_read() +and atomic_set(). This is not uniformly guaranteed, and may change in +the future, so all users of atomic_t should treat atomic_read() and +atomic_set() as simple C statements that may be reordered or +optimized away entirely by the compiler or processor, and explicitly +invoke the appropriate compiler and/or memory barrier for each use case. +Failure to do so will result in code that may suddenly break when used with +different architectures or compiler optimizations, or even changes in +unrelated code which changes how the compiler optimizes the section +accessing atomic_t variables. -Now, we move onto the actual atomic operation interfaces. +*** YOU HAVE BEEN WARNED! *** + +Now, we move onto the atomic operation interfaces typically +implemented with the help of assembly code. void atomic_add(int i, atomic_t *v); void atomic_sub(int i, atomic_t *v);
@@ -117,6 +160,12 @@ operation. Then: + int atomic_xchg(atomic_t *v, int new); + +This performs an atomic exchange operation on the atomic variable v, +with the given new value. It returns the old value that the atomic +variable v had just before the operation. + int atomic_cmpxchg(atomic_t *v, int old, int new); This performs an atomic compare exchange operation on the atomic value v,
Machen Sie Yahoo! zu Ihrer Startseite. Los geht's:
http://de.yahoo.com/set