ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / sparc / lib / atomic32.c
1 /*
2  * atomic32.c: 32-bit atomic_t implementation
3  *
4  * Copyright (C) 2004 Keith M Wesolowski
5  * 
6  * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf
7  */
8
9 #include <asm/atomic.h>
10 #include <linux/spinlock.h>
11 #include <linux/module.h>
12
13 #ifdef CONFIG_SMP
14 #define ATOMIC_HASH_SIZE        4
15 #define ATOMIC_HASH(a)  (&__atomic_hash[(((unsigned long)a)>>8) & (ATOMIC_HASH_SIZE-1)])
16
17 spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
18         [0 ... (ATOMIC_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
19 };
20
21 #else /* SMP */
22
23 #define ATOMIC_HASH_SIZE        1
24 #define ATOMIC_HASH(a)          0
25
26 #endif /* SMP */
27
28 int __atomic_add_return(int i, atomic_t *v)
29 {
30         int ret;
31         unsigned long flags;
32         spin_lock_irqsave(ATOMIC_HASH(v), flags);
33
34         ret = (v->counter += i);
35
36         spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
37         return ret;
38 }
39
40 void atomic_set(atomic_t *v, int i)
41 {
42         unsigned long flags;
43         spin_lock_irqsave(ATOMIC_HASH(v), flags);
44
45         v->counter = i;
46
47         spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
48 }
49
50 EXPORT_SYMBOL(__atomic_add_return);
51 EXPORT_SYMBOL(atomic_set);
52