Part 2. There are a couple of different ways of using / implementing bit-op-s. I try to summarize them: 1. "Stand alone" bit operations: By "stand alone" I mean that a modification to a bit field member is independent of any other operation before / after the bit operation in question. There is no ordering with respect to the other operations. They do not provide any SMP synch. semantics, there is no need to implement them as some atomic operations. 2. Atomic bit operations: As Linux turned to SMP safe, a couple of bit operations have been re-implemented by use of some atomic operations. An early implementation on PCs determined the basic semantics of these operations, including their fencing behavior. atomic_ops.txt: " obj->dead = 1; if (test_and_set_bit(0, &obj->flags)) /* ... */; obj->killed = 1; The implementation of test_and_set_bit() must guarentee that "obj->dead = 1;" is visible to cpus before the atomic memory operation done by test_and_set_bit() becomes visible. Likewise, the atomic memory operation done by test_and_set_bit() must become visible before "obj->killed = 1;" is visible." I am not convenienced that this is a good sync. strategy. Unfortunately, the acquisition / release semantics were not defined in Linux via some architecture independent and explicit way. People simply abused the fact that the bidirectional fencing is implicitly provided by some architectures for free. Theoretically, the code fragments like above have to be cleared up to use explicit ordering primitives. The description in atomic_ops.txt should state that this is not the way to do... (see the Fencing bit operations below). There can be ~20 "test_and_set_bit()" here or there. The atomic bit operation with requirements to order the preceding / following operations are mainly used for locking(-like) purposes: 3. Fencing bit operations: Should someone still insist on using the atomic bit operations as today, s/he should change to use e.g.: obj->dead = 1; if (test_and_set_bit_N_fence(0, &obj->flags)) /* ... */; obj->killed = 1; 4. Bit-lock operations: I summarized the ordering requirements here: http://marc.theaimsgroup.com/?l=linux-ia64&m=114362989421046&w=2 In order to let the architectures implement these bit-lock operations efficiently, the usage has to indicate the _minimal_ required ordering semantics, e.g.: test_and_set_bit_N_acquire() or ordered_test_and_set_bit(acquire, ...) release_N_clear_bit() etc. The style like: do_some_ordering_before() bit_op() do_some_ordering_after() is quite correct, however, the compiler is not sufficiently intelligent to let the architecture dependent part to merge e.g. into a single machine instruction (if it exists). Regards,Zoltan
- : send the line "unsubscribe linux-ia64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |