]> Zhao Yanbai Git Server - minix.git/commitdiff
Added function read_cpu_flags() that returns current cpu flags as a
authorBen Gras <ben@minix3.org>
Mon, 20 Jun 2005 14:53:13 +0000 (14:53 +0000)
committerBen Gras <ben@minix3.org>
Mon, 20 Jun 2005 14:53:13 +0000 (14:53 +0000)
long.  This is used to check for interrupts being disabled at the time
of a lock() call, if enabled in config.h. The number of times this
happens is then counted in the kinfo structure. These events (recursive
lockings) lead to nasty race conditions.

kernel/const.h
kernel/klib386.s
kernel/main.c
kernel/proto.h

index 4cd225d6990c4557282b99e6befad7f26850f280..91f5a965b55ba85db16cc26a98be0a98971c9704 100755 (executable)
@@ -3,6 +3,7 @@
 #include <ibm/interrupt.h>     /* interrupt numbers and hardware vectors */
 #include <ibm/ports.h>         /* port addresses and magic numbers */
 #include <ibm/bios.h>          /* BIOS addresses, sizes and magic numbers */
+#include <ibm/cpu.h>           /* BIOS addresses, sizes and magic numbers */
 #include <minix/config.h>
 
 /* To translate an address in kernel space to a physical address.  This is
 #define locktimeend(c)
 #endif
 
+#if ENABLE_K_LOCKCHECK
+#define lockcheck if(!(read_cpu_flags() & X86_FLAG_I)) kinfo.relocking++;
+#else
+#define lockcheck
+#endif
+
 /* Disable/Enable hardware interrupts. */
-#define lock(c, v)     do { intr_disable(); locktimestart(c, v); } while(0)
+#define lock(c, v)     do { lockcheck; intr_disable(); locktimestart(c, v); } while(0)
 #define unlock(c)      do { locktimeend(c); intr_enable(); } while(0)
 
 /* Sizes of memory tables. The boot monitor distinguishes three memory areas, 
index 99efb682edebe8d95a417b4ee4b68dd82f83fef7..1a9097351467ce856eaef71d2be91b836262a7a6 100755 (executable)
@@ -32,6 +32,7 @@
 .define        _idle_task      ! task executed when there is no work
 .define        _level0         ! call a function at level 0
 .define        _read_tsc       ! read the cycle counter (Pentium and up)
+.define        _read_cpu_flags ! read the cpu flags
 
 ! The routines only guarantee to preserve the registers the C compiler
 ! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
@@ -546,3 +547,15 @@ _read_tsc:
        pop ebp
        ret
 
+!*===========================================================================*
+!*                           read_flags                                             *
+!*===========================================================================*
+! PUBLIC unsigned long read_cpu_flags(void);
+! Read the cycle counter of the CPU. Pentium and up. 
+.align 16
+_read_cpu_flags:
+       pushf
+       mov eax, (esp)
+       popf
+       ret
+
index 32c104f3131aec7d28a50eb5b64bb6cfc704f782..ee9f1460b6a3c225220b4d03c1c03a1e70e6054e 100755 (executable)
@@ -180,6 +180,7 @@ PRIVATE void announce(void)
   /* Check if boot device was loaded with the kernel. */
   if (kinfo.bootdev_base > 0)
       kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size);
+
 }
 
 
index 52f5c361ec9f990be0d67f736ae87de5bd03da88..da0fb5eaffe900d5d7bcca476dd1a010f1103800 100755 (executable)
@@ -97,6 +97,7 @@ _PROTOTYPE( void reset, (void)                                                );
 _PROTOTYPE( void level0, (void (*func)(void))                          );
 _PROTOTYPE( void monitor, (void)                                       );
 _PROTOTYPE( void read_tsc, (unsigned long *high, unsigned long *low)   );
+_PROTOTYPE( unsigned long read_cpu_flags, (void)                       );
 
 /* mpx*.s */
 _PROTOTYPE( void idle_task, (void)                                     );