Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71207
b: refs/heads/master
c: 2633357
h: refs/heads/master
i:
  71205: d8d32c4
  71203: b16061c
  71199: 6ffe387
v: v3
  • Loading branch information
Nick Piggin authored and Linus Torvalds committed Oct 18, 2007
1 parent 43ee0ec commit 8c574a2
Show file tree
Hide file tree
Showing 28 changed files with 97 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 38048983e14c0fb6324175fbaf2be1baa842f5ee
refs/heads/master: 26333576fd0d0b52f6e4025c5aded97e188bdd44
14 changes: 14 additions & 0 deletions trunk/Documentation/atomic_ops.txt
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,20 @@ brothers:
*/
smp_mb__after_clear_bit();

There are two special bitops with lock barrier semantics (acquire/release,
same as spinlocks). These operate in the same way as their non-_lock/unlock
postfixed variants, except that they are to provide acquire/release semantics,
respectively. This means they can be used for bit_spin_trylock and
bit_spin_unlock type operations without specifying any more barriers.

int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
void clear_bit_unlock(unsigned long nr, unsigned long *addr);
void __clear_bit_unlock(unsigned long nr, unsigned long *addr);

The __clear_bit_unlock version is non-atomic, however it still implements
unlock barrier semantics. This can be useful if the lock itself is protecting
the other bits in the word.

Finally, there are non-atomic versions of the bitmask operations
provided. They are used in contexts where some other higher-level SMP
locking scheme is being used to protect the bitmask, and thus less
Expand Down
14 changes: 12 additions & 2 deletions trunk/Documentation/memory-barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,8 @@ kernel.

Any atomic operation that modifies some state in memory and returns information
about the state (old or new) implies an SMP-conditional general memory barrier
(smp_mb()) on each side of the actual operation. These include:
(smp_mb()) on each side of the actual operation (with the exception of
explicit lock operations, described later). These include:

xchg();
cmpxchg();
Expand Down Expand Up @@ -1536,10 +1537,19 @@ If they're used for constructing a lock of some description, then they probably
do need memory barriers as a lock primitive generally has to do things in a
specific order.


Basically, each usage case has to be carefully considered as to whether memory
barriers are needed or not.

The following operations are special locking primitives:

test_and_set_bit_lock();
clear_bit_unlock();
__clear_bit_unlock();

These implement LOCK-class and UNLOCK-class operations. These should be used in
preference to other operations when implementing locking primitives, because
their implementations can be optimised on many architectures.

[!] Note that special memory barrier primitives are available for these
situations because on some CPUs the atomic instructions used imply full memory
barriers, and so barrier instructions are superfluous in conjunction with them,
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-alpha/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ static inline unsigned int hweight8(unsigned int w)
#else
#include <asm-generic/bitops/hweight.h>
#endif
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-arm/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ static inline int constant_fls(int x)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

/*
* Ext2 is defined to use little-endian byte ordering.
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-avr32/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ static inline int ffs(unsigned long word)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-blackfin/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ static __inline__ int __test_bit(int nr, const void *addr)

#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-cris/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-frv/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ int __ilog2_u64(u64 n)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-generic/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
Expand Down
45 changes: 45 additions & 0 deletions trunk/include/asm-generic/bitops/lock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef _ASM_GENERIC_BITOPS_LOCK_H_
#define _ASM_GENERIC_BITOPS_LOCK_H_

/**
* test_and_set_bit_lock - Set a bit and return its old value, for lock
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and provides acquire barrier semantics.
* It can be used to implement bit locks.
*/
#define test_and_set_bit_lock(nr, addr) test_and_set_bit(nr, addr)

/**
* clear_bit_unlock - Clear a bit in memory, for unlock
* @nr: the bit to set
* @addr: the address to start counting from
*
* This operation is atomic and provides release barrier semantics.
*/
#define clear_bit_unlock(nr, addr) \
do { \
smp_mb__before_clear_bit(); \
clear_bit(nr, addr); \
} while (0)

/**
* __clear_bit_unlock - Clear a bit in memory, for unlock
* @nr: the bit to set
* @addr: the address to start counting from
*
* This operation is like clear_bit_unlock, however it is not atomic.
* It does provide release barrier semantics so it can be used to unlock
* a bit lock, however it would only be used if no other CPU can modify
* any bits in the memory until the lock is released (a good example is
* if the bit lock itself protects access to the other bits in the word).
*/
#define __clear_bit_unlock(nr, addr) \
do { \
smp_mb(); \
__clear_bit(nr, addr); \
} while (0)

#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */

1 change: 1 addition & 0 deletions trunk/include/asm-h8300/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static __inline__ unsigned long __ffs(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/minix.h>
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/asm-ia64/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ hweight64 (unsigned long x)
#define hweight16(x) (unsigned int) hweight64((x) & 0xfffful)
#define hweight8(x) (unsigned int) hweight64((x) & 0xfful)

#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

#include <asm-generic/bitops/find.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-m32r/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-m68k/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ static inline int fls(int x)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

/* Bitmap functions for the minix filesystem */

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-m68knommu/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr)

#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

static __inline__ int ext2_set_bit(int nr, volatile void * addr)
{
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-mips/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ static inline int ffs(int word)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/minix.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-parisc/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ static __inline__ int fls(int x)

#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>

#endif /* __KERNEL__ */
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-powerpc/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ static __inline__ int fls(unsigned int x)
#include <asm-generic/bitops/fls64.h>

#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
unsigned long find_next_zero_bit(const unsigned long *addr,
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-s390/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ static inline int sched_find_first_bit(unsigned long *b)
#include <asm-generic/bitops/fls64.h>

#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

/*
* ATTENTION: intel byte ordering convention for ext2 and minix !!
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-sh/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ static inline unsigned long __ffs(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-sh64/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static __inline__ unsigned long ffz(unsigned long word)
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-sparc/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
#include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-sparc64/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static inline unsigned int hweight8(unsigned int w)
#include <asm-generic/bitops/hweight.h>

#endif
#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */

#include <asm-generic/bitops/find.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-v850/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static inline int __test_bit (int nr, const void *addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>
#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a)
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-x86/bitops_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ static inline int fls(int x)
}

#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-x86/bitops_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ static __inline__ int fls(int x)
#define ARCH_HAS_FAST_MULTIPLIER 1

#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-xtensa/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static inline int fls (unsigned int x)
#endif

#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/minix.h>

Expand Down

0 comments on commit 8c574a2

Please sign in to comment.