File: /usr/include/asm/smplock.h

1     /*
2      * <asm/smplock.h>
3      *
4      * i386 SMP lock implementation
5      */
6     #include <linux/interrupt.h>
7     #include <linux/spinlock.h>
8     #include <linux/sched.h>
9     #include <asm/current.h>
10     
11     extern spinlock_t kernel_flag;
12     
13     #define kernel_locked()		spin_is_locked(&kernel_flag)
14     
15     /*
16      * Release global kernel lock and global interrupt lock
17      */
18     #define release_kernel_lock(task, cpu) \
19     do { \
20     	if (task->lock_depth >= 0) \
21     		spin_unlock(&kernel_flag); \
22     	release_irqlock(cpu); \
23     	__sti(); \
24     } while (0)
25     
26     /*
27      * Re-acquire the kernel lock
28      */
29     #define reacquire_kernel_lock(task) \
30     do { \
31     	if (task->lock_depth >= 0) \
32     		spin_lock(&kernel_flag); \
33     } while (0)
34     
35     
36     /*
37      * Getting the big kernel lock.
38      *
39      * This cannot happen asynchronously,
40      * so we only need to worry about other
41      * CPU's.
42      */
43     extern __inline__ void lock_kernel(void)
44     {
45     #if 1
46     	if (!++current->lock_depth)
47     		spin_lock(&kernel_flag);
48     #else
49     	__asm__ __volatile__(
50     		"incl %1\n\t"
51     		"jne 9f"
52     		spin_lock_string
53     		"\n9:"
54     		:"=m" (__dummy_lock(&kernel_flag)),
55     		 "=m" (current->lock_depth));
56     #endif
57     }
58     
59     extern __inline__ void unlock_kernel(void)
60     {
61     	if (current->lock_depth < 0)
62     		BUG();
63     #if 1
64     	if (--current->lock_depth < 0)
65     		spin_unlock(&kernel_flag);
66     #else
67     	__asm__ __volatile__(
68     		"decl %1\n\t"
69     		"jns 9f\n\t"
70     		spin_unlock_string
71     		"\n9:"
72     		:"=m" (__dummy_lock(&kernel_flag)),
73     		 "=m" (current->lock_depth));
74     #endif
75     }
76