summaryrefslogtreecommitdiff
path: root/Kernel/Arch
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-01 12:45:51 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-01 12:47:33 +0100
commit9ed272ce985fb9af6a5e49f808f66212ef4b767c (patch)
tree1f5cbf913a745bdee8867ffacadfd6f16472d588 /Kernel/Arch
parentf067730f6be9bd10f299d295adfd49175f4e91d7 (diff)
downloadserenity-9ed272ce985fb9af6a5e49f808f66212ef4b767c.zip
Kernel: Disable interrupts while setting up a thread blocker
There was a race window between instantiating a WaitQueueBlocker and setting the thread state to Blocked. If a thread was preempted between those steps, someone else might try to wake the wait queue and find an unblocked thread in a wait queue, which is not sane.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r--Kernel/Arch/i386/CPU.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h
index 5fa9057bb1..27d7d132f4 100644
--- a/Kernel/Arch/i386/CPU.h
+++ b/Kernel/Arch/i386/CPU.h
@@ -289,6 +289,21 @@ private:
u32 m_flags;
};
+inline bool cli_and_save_interrupt_flag()
+{
+ u32 flags = cpu_flags();
+ cli();
+ return flags & 0x200;
+}
+
+inline void restore_interrupt_flag(bool flag)
+{
+ if (flag)
+ sti();
+ else
+ cli();
+}
+
class InterruptDisabler {
public:
InterruptDisabler()