patch-1.3.54 linux/include/asm-i386/smp_lock.h

Next file: linux/include/linux/fdreg.h
Previous file: linux/include/asm-i386/pgtable.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.53/linux/include/asm-i386/smp_lock.h linux/include/asm-i386/smp_lock.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_SMPLOCK_H
+#define __LINUX_SMPLOCK_H
+
+#ifdef __SMP__
+
+/*
+ *	Locking the kernel 
+ */
+ 
+extern __inline void lock_kernel(void)
+{
+	unsigned long flags;
+	int proc = smp_processor_id();
+
+	save_flags(flags);
+	cli();
+	/* set_bit works atomic in SMP machines */
+	while(set_bit(0, (void *)&kernel_flag)) 
+	{
+		/*
+		 *	We just start another level if we have the lock 
+		 */
+		if (proc == active_kernel_processor)
+			break;
+		do 
+		{
+			smp_spins++;
+			/*
+			 *	Doing test_bit here doesn't lock the bus 
+			 */
+			if (test_bit(proc, (void *)&smp_invalidate_needed))
+				if (clear_bit(proc, (void *)&smp_invalidate_needed))
+					local_invalidate();
+		}
+		while(test_bit(0, (void *)&kernel_flag));
+	}
+	/* 
+	 *	We got the lock, so tell the world we are here and increment
+	 *	the level counter 
+	 */
+	active_kernel_processor = proc;
+	kernel_counter++;
+	restore_flags(flags);
+}
+
+extern __inline void unlock_kernel(void)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	/*
+	 *	If it's the last level we have in the kernel, then
+	 *	free the lock 
+	 */
+	if (kernel_counter == 0)
+		panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */
+	
+	if(! --kernel_counter) 
+	{
+		active_kernel_processor = NO_PROC_ID;
+		clear_bit(0, (void *)&kernel_flag);
+	}
+	restore_flags(flags);
+}
+
+#endif
+#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this