mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 11:48:13 +00:00
Add an InterruptDisabler helper class and use that for kmalloc.
The naive spinlock was not nearly enough to protect kmalloc from reentrancy problems. I don't want to deal with coming up with a fancy lock for kmalloc right now, so I made an InterruptDisabler thingy instead. It does CLI and then STI iff interrupts were previously enabled.
This commit is contained in:
parent
9a296d63f3
commit
0c5bbac86e
4 changed files with 35 additions and 14 deletions
|
@ -18,7 +18,7 @@ bool ProcFileSystem::initialize()
|
||||||
{
|
{
|
||||||
SyntheticFileSystem::initialize();
|
SyntheticFileSystem::initialize();
|
||||||
addFile(createGeneratedFile("summary", [] {
|
addFile(createGeneratedFile("summary", [] {
|
||||||
cli();
|
InterruptDisabler disabler;
|
||||||
auto tasks = Task::allTasks();
|
auto tasks = Task::allTasks();
|
||||||
char* buffer;
|
char* buffer;
|
||||||
auto stringImpl = StringImpl::createUninitialized(tasks.size() * 128, 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 += ksprintf(ptr, "kmalloc: alloc: %u / free: %u\n", sum_alloc, sum_free);
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
sti();
|
|
||||||
return ByteBuffer::copy((byte*)buffer, ptr - buffer);
|
return ByteBuffer::copy((byte*)buffer, ptr - buffer);
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -185,7 +185,7 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid)
|
||||||
if (!elfData)
|
if (!elfData)
|
||||||
return nullptr;
|
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);
|
Task* t = new Task(parts.takeLast(), uid, gid);
|
||||||
|
|
||||||
ExecSpace space;
|
ExecSpace space;
|
||||||
|
@ -218,7 +218,6 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid)
|
||||||
#ifdef TASK_DEBUG
|
#ifdef TASK_DEBUG
|
||||||
kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
|
kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
|
||||||
#endif
|
#endif
|
||||||
sti();
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -461,11 +460,9 @@ void yield()
|
||||||
|
|
||||||
//kprintf("%s<%u> yield()\n", current->name().characters(), current->pid());
|
//kprintf("%s<%u> yield()\n", current->name().characters(), current->pid());
|
||||||
|
|
||||||
cli();
|
InterruptDisabler disabler;
|
||||||
if (!scheduleNewTask()) {
|
if (!scheduleNewTask())
|
||||||
sti();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
//kprintf("yield() jumping to new task: %x (%s)\n", current->farPtr().selector, current->name().characters());
|
//kprintf("yield() jumping to new task: %x (%s)\n", current->farPtr().selector, current->name().characters());
|
||||||
switchNow();
|
switchNow();
|
||||||
|
|
|
@ -79,6 +79,35 @@ void writeGDTEntry(WORD selector, Descriptor&);
|
||||||
#define cli() asm volatile("cli")
|
#define cli() asm volatile("cli")
|
||||||
#define sti() asm volatile("sti")
|
#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 */
|
/* Map IRQ0-15 @ ISR 0x50-0x5F */
|
||||||
#define IRQ_VECTOR_BASE 0x50
|
#define IRQ_VECTOR_BASE 0x50
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "VGA.h"
|
#include "VGA.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "Assertions.h"
|
#include "Assertions.h"
|
||||||
#include <AK/Lock.h>
|
|
||||||
|
|
||||||
#define SANITIZE_KMALLOC
|
#define SANITIZE_KMALLOC
|
||||||
|
|
||||||
|
@ -30,12 +29,9 @@ PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8];
|
||||||
volatile DWORD sum_alloc = 0;
|
volatile DWORD sum_alloc = 0;
|
||||||
volatile DWORD sum_free = POOL_SIZE;
|
volatile DWORD sum_free = POOL_SIZE;
|
||||||
|
|
||||||
static SpinLock s_kmallocLock;
|
|
||||||
|
|
||||||
PUBLIC void
|
PUBLIC void
|
||||||
kmalloc_init()
|
kmalloc_init()
|
||||||
{
|
{
|
||||||
s_kmallocLock.init();
|
|
||||||
memset( &alloc_map, 0, sizeof(alloc_map) );
|
memset( &alloc_map, 0, sizeof(alloc_map) );
|
||||||
memset( (void *)BASE_PHYS, 0, POOL_SIZE );
|
memset( (void *)BASE_PHYS, 0, POOL_SIZE );
|
||||||
|
|
||||||
|
@ -46,7 +42,7 @@ kmalloc_init()
|
||||||
PUBLIC void *
|
PUBLIC void *
|
||||||
kmalloc( DWORD size )
|
kmalloc( DWORD size )
|
||||||
{
|
{
|
||||||
Locker locker(s_kmallocLock);
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
DWORD chunks_needed, chunks_here, first_chunk;
|
DWORD chunks_needed, chunks_here, first_chunk;
|
||||||
DWORD real_size;
|
DWORD real_size;
|
||||||
|
@ -123,7 +119,7 @@ kfree( void *ptr )
|
||||||
if( !ptr )
|
if( !ptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Locker locker(s_kmallocLock);
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
allocation_t *a = (allocation_t *)((((BYTE *)ptr) - sizeof(allocation_t)));
|
allocation_t *a = (allocation_t *)((((BYTE *)ptr) - sizeof(allocation_t)));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue