1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
/* smp_lock.h: Locking and unlocking the kernel on the Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#ifndef __SPARC_SMPLOCK_H
#define __SPARC_SMPLOCK_H
#include <asm/smp.h>
#include <asm/bitops.h>
#include <asm/atops.h>
#include <asm/pgtable.h>
#ifdef __SMP__
/*
* Locking the kernel
*/
/* Knock knock... */
extern __inline void lock_kernel(void)
{
unsigned long flags;
int proc = smp_processor_id();
save_flags(flags); cli(); /* need this on sparc? */
while(ldstub(&kernel_flag)) {
if(proc == active_kernel_processor)
break;
do {
#ifdef __SMP_PROF__
smp_spins[smp_processor_id()]++;
#endif
barrier();
} while(kernel_flag); /* Don't lock the bus more than we have to. */
}
active_kernel_processor = proc;
kernel_counter++;
restore_flags(flags);
}
/* I want out... */
extern __inline void unlock_kernel(void)
{
unsigned long flags;
save_flags(flags); cli(); /* need this on sparc? */
if(kernel_counter == 0)
panic("Bogus kernel counter.\n");
if(!--kernel_counter) {
active_kernel_processor = NO_PROC_ID;
kernel_flag = KLOCK_CLEAR;
}
restore_flags(flags);
}
#endif /* !(__SPARC_SMPLOCK_H) */
#endif /* (__SMP__) */
|