Pārlūkot izejas kodu

Generalize the SpinLock and move it to AK.

Add a separate lock to protect the VFS. I think this might be a good idea.
I'm not sure it's a good approach though. I'll fiddle with it as I go along.

It's really fun to figure out all these things on my own.
Andreas Kling 6 gadi atpakaļ
vecāks
revīzija
018da1be11

+ 54 - 0
AK/Lock.h

@@ -0,0 +1,54 @@
+#pragma once
+
+#include "Types.h"
+
+namespace AK {
+
+static inline dword CAS(volatile dword* mem, dword newval, dword oldval)
+{
+    dword ret;
+    asm volatile(
+        "cmpxchgl %2, %1"
+        :"=a"(ret), "=m"(*mem)
+        :"r"(newval), "m"(*mem), "0"(oldval));
+    return ret;
+}
+
+class SpinLock {
+public:
+    SpinLock() { }
+    ~SpinLock() { unlock(); }
+
+    void lock()
+    {
+        for (;;) {
+            if (CAS(&m_lock, 1, 0) == 1)
+                return;
+        }
+    }
+
+    void unlock()
+    {
+        // barrier();
+        m_lock = 0;
+    }
+
+private:
+    volatile dword m_lock { 0 };
+};
+
+class Locker {
+public:
+    explicit Locker(SpinLock& l) : m_lock(l) { m_lock.lock(); }
+    ~Locker() { unlock(); }
+    void unlock() { m_lock.unlock(); }
+
+private:
+    SpinLock& m_lock;
+};
+
+}
+
+using AK::SpinLock;
+using AK::Locker;
+

+ 1 - 66
Kernel/Syscall.cpp

@@ -2,6 +2,7 @@
 #include "Task.h"
 #include "Syscall.h"
 #include "Console.h"
+#include <AK/Lock.h>
 
 extern "C" void syscall_entry();
 extern "C" void syscall_ISR();
@@ -38,72 +39,6 @@ asm(
     "    iret\n"
 );
 
-static inline dword CAS(dword* mem, dword newval, dword oldval)
-{
-    dword ret;
-    asm volatile(
-        "cmpxchgl %2, %1"
-        :"=a"(ret), "=m"(*mem)
-        :"r"(newval), "m"(*mem), "0"(oldval));
-    return ret;
-}
-
-class SpinLock {
-public:
-    SpinLock()
-    {
-    }
-
-    ~SpinLock()
-    {
-        unlock();
-    }
-
-    void lock()
-    {
-        volatile dword count = 0;
-        for (;;) {
-            if (CAS(&m_lock, 1, 0) == 1)
-                return;
-            ++count;
-
-        }
-        if (count)
-            kprintf("waited %u in %s\n",count, current->name().characters());
-    }
-
-    void unlock()
-    {
-        // barrier();
-        m_lock = 0;
-    }
-
-private:
-    dword m_lock { 0 };
-};
-
-class Locker {
-public:
-    explicit Locker(SpinLock& l)
-        : m_lock(l)
-    {
-        m_lock.lock();
-    }
-
-    ~Locker()
-    {
-        unlock();
-    }
-
-    void unlock()
-    {
-        m_lock.unlock();
-    }
-
-private:
-    SpinLock& m_lock;
-};
-
 namespace Syscall {
 
 static SpinLock* s_lock;

+ 0 - 23
Kernel/Task.cpp

@@ -494,28 +494,6 @@ bool scheduleNewTask()
     }
 }
 
-static void drawSchedulerBanner(Task& task)
-{
-    return;
-    // FIXME: We need a kernel lock to do stuff like this :(
-    //return;
-    auto c = vga_get_cursor();
-    auto a = vga_get_attr();
-    vga_set_cursor(0, 50);
-    vga_set_attr(0x20);
-    kprintf("          ");
-    kprintf("          ");
-    kprintf("          ");
-    vga_set_cursor(0, 50);
-    kprintf("pid: %u ", task.pid());
-    vga_set_cursor(0, 58);
-    kprintf("%s", task.name().characters());
-    vga_set_cursor(0, 65);
-    kprintf("eip: %p", task.tss().eip);
-    vga_set_attr(a);
-    vga_set_cursor(c);
-}
-
 static bool contextSwitch(Task* t)
 {
     //kprintf("c_s to %s (same:%u)\n", t->name().characters(), current == t);
@@ -573,7 +551,6 @@ static bool contextSwitch(Task* t)
     tssDescriptor.type = 11; // Busy TSS
 
     flushGDT();
-    drawSchedulerBanner(*t);
 
     t->didSchedule();
     return true;

+ 3 - 10
Kernel/VGA.cpp

@@ -33,22 +33,15 @@ byte vga_get_attr()
 
 void vga_init()
 {
-    DWORD i;
-
     current_attr = 0x07;
-    vga_mem = (BYTE *)0xb8000;
+    vga_mem = (byte*)0xb8000;
 
-    for (i = 0; i < (80 * 24); ++i) {
+    for (word i = 0; i < (80 * 25); ++i) {
         vga_mem[i*2] = ' ';
         vga_mem[i*2 + 1] = 0x07;
     }
 
-    // Fill the bottom line with blue.
-    for (i = (80 * 24); i < (80 * 25); ++i) {
-        vga_mem[i*2] = ' ';
-        vga_mem[i*2 + 1] = 0x17;
-    }
-    vga_set_cursor( 0 );
+    vga_set_cursor(0);
 }
 
 WORD vga_get_cursor()

+ 0 - 17
Kernel/i8253.cpp

@@ -95,23 +95,6 @@ void clock_handle()
     current->tss().cs = regs.cs;
     current->tss().eflags = regs.eflags;
 
-#if 0
-    BYTE a = vga_get_attr();
-    WORD foo = vga_get_cursor();
-
-    vga_set_attr(0x50);
-    vga_set_cursor(0);
-
-    kprintf("\n\n");
-    kprintf("Task %u interrupted at %x             \n", current->pid(), regs.eip );
-    kprintf("EAX=%x EBX=%x ECX=%x EDX=%x           \n", regs.eax, regs.ebx, regs.ecx, regs.edx);
-    kprintf("ESI=%x EDI=%x EBP=%x ESP=%x           \n", regs.esi, regs.edi, regs.ebp, regs.esp);
-    kprintf("FLAGS=%x", regs.eflags);
-
-    vga_set_cursor(foo);
-    vga_set_attr(a);
-#endif
-
     // Compute task ESP.
     // Add 12 for CS, EIP, EFLAGS (interrupt mechanic)
 

+ 1 - 51
Kernel/init.cpp

@@ -32,53 +32,6 @@
 //#define TEST_ELF_LOADER
 //#define TEST_CRASHY_USER_PROCESSES
 
-static void motd_main() NORETURN;
-static void motd_main()
-{
-    kprintf("Hello in motd_main!\n");
-    int fd = Userspace::open("/test.asm");
-    kprintf("motd: fd=%d\n", fd);
-    ASSERT(fd != -1);
-    DO_SYSCALL_A3(0x2000, 1, 2, 3);
-    kprintf("getuid(): %u\n", Userspace::getuid());
-    auto buffer = DataBuffer::createUninitialized(33);
-    memset(buffer->data(), 0, buffer->length());
-    int nread = Userspace::read(fd, buffer->data(), buffer->length() - 1);
-    kprintf("read(): %d\n", nread);
-    buffer->data()[nread] = 0;
-    kprintf("read(): '%s'\n", buffer->data());
-    for (;;) {
-        //kill(4, 5);
-        sleep(1 * TICKS_PER_SECOND);
-    }
-}
-
-static void syscall_test_main() NORETURN;
-static void syscall_test_main()
-{
-    kprintf("Hello in syscall_test_main!\n");
-    for (;;) {
-        Userspace::getuid();
-//        Userspace::yield();
-        //kprintf("getuid(): %u\n", Userspace::getuid());
-        sleep(1 * TICKS_PER_SECOND);
-    }
-}
-
-static void user_main() NORETURN;
-static void user_main()
-{
-    DO_SYSCALL_A3(0x3000, 2, 3, 4);
-    // Crash ourselves!
-    char* x = reinterpret_cast<char*>(0xbeefbabe);
-    *x = 1;
-    HANG;
-    for (;;) {
-        // nothing?
-        Userspace::sleep(1 * TICKS_PER_SECOND);
-    }
-}
-
 system_t system;
 
 void banner()
@@ -192,10 +145,7 @@ static void init_stage2()
 
     auto* shTask = Task::create("/bin/sh", (uid_t)100, (gid_t)100);
 
-    //new Task(motd_main, "motd", IPC::Handle::MotdTask, Task::Ring0);
-    //new Task(syscall_test_main, "syscall_test", IPC::Handle::MotdTask, Task::Ring3);
-
-    kprintf("init stage2 is done!\n");
+    banner();
 
 #if 0
     // It would be nice to exit this process, but right now it instantiates all kinds of things.

+ 0 - 36
LibC/syscall.h

@@ -1,36 +0,0 @@
-#pragma once
-
-#include "types.h"
-
-extern "C" {
-
-inline dword syscall_a0(dword function)
-{
-    dword result;
-    asm volatile("int $0x80":"=a"(result):"a"(function));
-    return result;
-}
-
-inline dword syscall_a1(dword function, dword arg1)
-{
-    dword result;
-    asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1));
-    return result;
-}
-
-inline dword syscall_a2(dword function, dword arg1, dword arg2)
-{
-    dword result;
-    asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2));
-    return result;
-}
-
-inline dword syscall_a3(dword function, dword arg1, dword arg2, dword arg3)
-{
-    dword result;
-    asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2),"b"(arg3));
-    return result;
-}
-
-}
-

+ 8 - 0
VirtualFileSystem/FileHandle.cpp

@@ -24,6 +24,8 @@ bool additionWouldOverflow(Unix::off_t a, Unix::off_t b)
 
 int FileHandle::stat(Unix::stat* buffer)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     if (!m_vnode)
         return -EBADF;
 
@@ -49,6 +51,8 @@ int FileHandle::stat(Unix::stat* buffer)
 
 Unix::off_t FileHandle::seek(Unix::off_t offset, int whence)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     if (!m_vnode)
         return -EBADF;
 
@@ -91,6 +95,8 @@ Unix::off_t FileHandle::seek(Unix::off_t offset, int whence)
 
 Unix::ssize_t FileHandle::read(byte* buffer, Unix::size_t count)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     if (m_vnode->isCharacterDevice()) {
         // FIXME: What should happen to m_currentOffset?
         return m_vnode->characterDevice()->read(buffer, count);
@@ -102,6 +108,8 @@ Unix::ssize_t FileHandle::read(byte* buffer, Unix::size_t count)
 
 ByteBuffer FileHandle::readEntireFile()
 {
+    Locker locker(VirtualFileSystem::lock());
+
     if (m_vnode->isCharacterDevice()) {
         auto buffer = ByteBuffer::createUninitialized(1024);
         Unix::ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size());

+ 17 - 0
VirtualFileSystem/VirtualFileSystem.cpp

@@ -20,9 +20,18 @@ VirtualFileSystem& VirtualFileSystem::the()
     return *s_the;
 }
 
+static SpinLock* s_vfsLock;
+
+SpinLock& VirtualFileSystem::lock()
+{
+    ASSERT(s_vfsLock);
+    return *s_vfsLock;
+}
+
 void VirtualFileSystem::initializeGlobals()
 {
     s_the = nullptr;
+    s_vfsLock = new SpinLock;
     FileSystem::initializeGlobals();
 }
 
@@ -336,6 +345,8 @@ void VirtualFileSystem::listDirectoryRecursively(const String& path)
 
 bool VirtualFileSystem::touch(const String& path)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     auto inode = resolvePath(path);
     if (!inode.isValid())
         return false;
@@ -344,6 +355,8 @@ bool VirtualFileSystem::touch(const String& path)
 
 OwnPtr<FileHandle> VirtualFileSystem::open(const String& path)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     auto inode = resolvePath(path);
     if (!inode.isValid())
         return nullptr;
@@ -355,6 +368,8 @@ OwnPtr<FileHandle> VirtualFileSystem::open(const String& path)
 
 OwnPtr<FileHandle> VirtualFileSystem::create(const String& path)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     // FIXME: Do the real thing, not just this fake thing!
     (void) path;
     m_rootNode->fileSystem()->createInode(m_rootNode->fileSystem()->rootInode(), "empty", 0100644, 0);
@@ -363,6 +378,8 @@ OwnPtr<FileHandle> VirtualFileSystem::create(const String& path)
 
 OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path)
 {
+    Locker locker(VirtualFileSystem::lock());
+
     // FIXME: Do the real thing, not just this fake thing!
     (void) path;
     m_rootNode->fileSystem()->makeDirectory(m_rootNode->fileSystem()->rootInode(), "mydir", 0400755);

+ 2 - 0
VirtualFileSystem/VirtualFileSystem.h

@@ -5,6 +5,7 @@
 #include <AK/RetainPtr.h>
 #include <AK/String.h>
 #include <AK/Vector.h>
+#include <AK/Lock.h>
 #include "InodeIdentifier.h"
 #include "Limits.h"
 
@@ -15,6 +16,7 @@ class FileSystem;
 class VirtualFileSystem {
 public:
     static void initializeGlobals();
+    static SpinLock& lock();
 
     struct Node {
         InodeIdentifier inode;

+ 2 - 0
VirtualFileSystem/test.cpp

@@ -21,6 +21,8 @@ int main(int c, char** v)
     if (c >= 2)
         filename = v[1];
 
+    VirtualFileSystem::initializeGlobals();
+
     VirtualFileSystem vfs;
 
     auto zero = make<ZeroDevice>();