diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 7bde996892..57d7493fd1 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -18,7 +18,7 @@ bool ProcFileSystem::initialize() { SyntheticFileSystem::initialize(); addFile(createGeneratedFile("summary", [] { - cli(); + InterruptDisabler disabler; auto tasks = Task::allTasks(); char* buffer; auto stringImpl = StringImpl::createUninitialized(tasks.size() * 128, buffer); @@ -36,7 +36,6 @@ bool ProcFileSystem::initialize() } ptr += ksprintf(ptr, "kmalloc: alloc: %u / free: %u\n", sum_alloc, sum_free); *ptr = '\0'; - sti(); return ByteBuffer::copy((byte*)buffer, ptr - buffer); })); return true; diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 4382b8db73..331be38ffb 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -185,7 +185,7 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid) if (!elfData) return nullptr; - cli(); + InterruptDisabler disabler; // FIXME: Get rid of this, jesus christ. This "critical" section is HUGE. Task* t = new Task(parts.takeLast(), uid, gid); ExecSpace space; @@ -218,7 +218,6 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid) #ifdef TASK_DEBUG kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip); #endif - sti(); return t; } @@ -461,11 +460,9 @@ void yield() //kprintf("%s<%u> yield()\n", current->name().characters(), current->pid()); - cli(); - if (!scheduleNewTask()) { - sti(); + InterruptDisabler disabler; + if (!scheduleNewTask()) return; - } //kprintf("yield() jumping to new task: %x (%s)\n", current->farPtr().selector, current->name().characters()); switchNow(); diff --git a/Kernel/i386.h b/Kernel/i386.h index b9dc62a42b..3ffb4a8e31 100644 --- a/Kernel/i386.h +++ b/Kernel/i386.h @@ -79,6 +79,35 @@ void writeGDTEntry(WORD selector, Descriptor&); #define cli() asm volatile("cli") #define sti() asm volatile("sti") +static inline dword cpuFlags() +{ + dword flags; + asm volatile( + "pushf\n" + "pop %0\n" + :"=rm"(flags) + ::"memory"); + return flags; +} + +class InterruptDisabler { +public: + InterruptDisabler() + { + m_flags = cpuFlags(); + cli(); + } + + ~InterruptDisabler() + { + if (m_flags & 0x200) + sti(); + } + +private: + dword m_flags; +}; + /* Map IRQ0-15 @ ISR 0x50-0x5F */ #define IRQ_VECTOR_BASE 0x50 diff --git a/Kernel/kmalloc.cpp b/Kernel/kmalloc.cpp index dbd873836d..693c29e98a 100644 --- a/Kernel/kmalloc.cpp +++ b/Kernel/kmalloc.cpp @@ -10,7 +10,6 @@ #include "VGA.h" #include "system.h" #include "Assertions.h" -#include #define SANITIZE_KMALLOC @@ -30,12 +29,9 @@ PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8]; volatile DWORD sum_alloc = 0; volatile DWORD sum_free = POOL_SIZE; -static SpinLock s_kmallocLock; - PUBLIC void kmalloc_init() { - s_kmallocLock.init(); memset( &alloc_map, 0, sizeof(alloc_map) ); memset( (void *)BASE_PHYS, 0, POOL_SIZE ); @@ -46,7 +42,7 @@ kmalloc_init() PUBLIC void * kmalloc( DWORD size ) { - Locker locker(s_kmallocLock); + InterruptDisabler disabler; DWORD chunks_needed, chunks_here, first_chunk; DWORD real_size; @@ -123,7 +119,7 @@ kfree( void *ptr ) if( !ptr ) return; - Locker locker(s_kmallocLock); + InterruptDisabler disabler; allocation_t *a = (allocation_t *)((((BYTE *)ptr) - sizeof(allocation_t)));