1 #ifndef __I386_SMPLOCK_H
2 #define __I386_SMPLOCK_H
3
4 #ifdef __SMP__
5
6 /*
7 * Locking the kernel
8 */
9
10 extern __inline void lock_kernel(void)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
11 {
12 unsigned long flags;
13 int proc = smp_processor_id();
14
15 save_flags(flags);
16 cli();
17 /* set_bit works atomic in SMP machines */
18 while(set_bit(0, (void *)&kernel_flag))
19 {
20 /*
21 * We just start another level if we have the lock
22 */
23 if (proc == active_kernel_processor)
24 break;
25 do
26 {
27 #ifdef __SMP_PROF__
28 smp_spins[smp_processor_id()]++;
29 #endif
30 /*
31 * Doing test_bit here doesn't lock the bus
32 */
33 if (test_bit(proc, (void *)&smp_invalidate_needed))
34 if (clear_bit(proc, (void *)&smp_invalidate_needed))
35 local_invalidate();
36 }
37 while(test_bit(0, (void *)&kernel_flag));
38 }
39 /*
40 * We got the lock, so tell the world we are here and increment
41 * the level counter
42 */
43 active_kernel_processor = proc;
44 kernel_counter++;
45 restore_flags(flags);
46 }
47
48 extern __inline void unlock_kernel(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
49 {
50 unsigned long flags;
51 save_flags(flags);
52 cli();
53 /*
54 * If it's the last level we have in the kernel, then
55 * free the lock
56 */
57 if (kernel_counter == 0)
58 panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */
59
60 if(! --kernel_counter)
61 {
62 active_kernel_processor = NO_PROC_ID;
63 clear_bit(0, (void *)&kernel_flag);
64 }
65 restore_flags(flags);
66 }
67
68 #endif
69 #endif