From: Ben Gras Date: Mon, 20 Jun 2005 14:53:13 +0000 (+0000) Subject: Added function read_cpu_flags() that returns current cpu flags as a X-Git-Tag: v3.1.0~716 X-Git-Url: http://zhaoyanbai.com/repos/nsupdate.html?a=commitdiff_plain;h=3eeff022fb90cae1725a033dcd82e48694cd9762;p=minix.git Added function read_cpu_flags() that returns current cpu flags as a 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. --- diff --git a/kernel/const.h b/kernel/const.h index 4cd225d69..91f5a965b 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -3,6 +3,7 @@ #include /* interrupt numbers and hardware vectors */ #include /* port addresses and magic numbers */ #include /* BIOS addresses, sizes and magic numbers */ +#include /* BIOS addresses, sizes and magic numbers */ #include /* To translate an address in kernel space to a physical address. This is @@ -73,8 +74,14 @@ #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, diff --git a/kernel/klib386.s b/kernel/klib386.s index 99efb682e..1a9097351 100755 --- a/kernel/klib386.s +++ b/kernel/klib386.s @@ -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 + diff --git a/kernel/main.c b/kernel/main.c index 32c104f31..ee9f1460b 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -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); + } diff --git a/kernel/proto.h b/kernel/proto.h index 52f5c361e..da0fb5eaf 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -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) );