Browse Source

Paper over a race in DoubleBuffer.

I'm still somewhat okay throwing InterruptDisabler at races as they screw me.
Eventually I'm gonna have to devise a different strategy though.
Andreas Kling 6 years ago
parent
commit
3ac977f50b
4 changed files with 20 additions and 4 deletions
  1. 5 1
      Kernel/DoubleBuffer.cpp
  2. 1 1
      Kernel/kmalloc.cpp
  3. 9 1
      Kernel/kmalloc.h
  4. 5 1
      Widgets/EventLoop.cpp

+ 5 - 1
Kernel/DoubleBuffer.cpp

@@ -2,9 +2,13 @@
 
 void DoubleBuffer::flip()
 {
+    InterruptDisabler disabler;
     ASSERT(m_read_buffer_index == m_read_buffer->size());
     swap(m_read_buffer, m_write_buffer);
-    m_write_buffer->clear();
+    if (m_write_buffer->capacity() < 32)
+        m_write_buffer->clear_with_capacity();
+    else
+        m_write_buffer->clear();
     m_read_buffer_index = 0;
 }
 

+ 1 - 1
Kernel/kmalloc.cpp

@@ -90,7 +90,7 @@ void* kmalloc_page_aligned(size_t size)
     return ptr;
 }
 
-void* kmalloc(dword size)
+void* kmalloc_impl(dword size)
 {
     InterruptDisabler disabler;
 

+ 9 - 1
Kernel/kmalloc.h

@@ -1,7 +1,7 @@
 #pragma once
 
 void kmalloc_init();
-void *kmalloc(dword size) __attribute__ ((malloc));
+void* kmalloc_impl(dword size) __attribute__ ((malloc));
 void* kmalloc_eternal(size_t) __attribute__ ((malloc));
 void* kmalloc_page_aligned(size_t) __attribute__ ((malloc));
 void* kmalloc_aligned(size_t, size_t alignment) __attribute__ ((malloc));
@@ -17,3 +17,11 @@ extern volatile size_t kmalloc_sum_page_aligned;
 
 inline void* operator new(size_t, void* p) { return p; }
 inline void* operator new[](size_t, void* p) { return p; }
+
+ALWAYS_INLINE void* kmalloc(size_t size)
+{
+    // Any kernel allocation >= 32K is very suspicious, catch them.
+    if (size >= 0x8000)
+        asm volatile("cli;hlt");
+    return kmalloc_impl(size);
+}

+ 5 - 1
Widgets/EventLoop.cpp

@@ -36,7 +36,11 @@ int EventLoop::exec()
     for (;;) {
         if (m_queuedEvents.is_empty())
             waitForEvent();
-        auto events = move(m_queuedEvents);
+        Vector<QueuedEvent> events;
+        {
+            InterruptDisabler disabler;
+            events = move(m_queuedEvents);
+        }
         for (auto& queuedEvent : events) {
             auto* receiver = queuedEvent.receiver;
             auto& event = *queuedEvent.event;