diff --git a/AK/Lock.h b/AK/Lock.h new file mode 100644 index 0000000000..e4a0a77daa --- /dev/null +++ b/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; + diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 74cb4f5ae7..ede05bda5f 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -2,6 +2,7 @@ #include "Task.h" #include "Syscall.h" #include "Console.h" +#include 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; diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index ea979dc971..075c4709a8 100644 --- a/Kernel/Task.cpp +++ b/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; diff --git a/Kernel/VGA.cpp b/Kernel/VGA.cpp index 782a730485..458a3c967c 100644 --- a/Kernel/VGA.cpp +++ b/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() diff --git a/Kernel/i8253.cpp b/Kernel/i8253.cpp index cfa24a3aef..d6bf648d25 100644 --- a/Kernel/i8253.cpp +++ b/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) diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 86e3d53f08..00308f46b9 100644 --- a/Kernel/init.cpp +++ b/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(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. diff --git a/LibC/syscall.h b/LibC/syscall.h deleted file mode 100644 index f702dbbc4e..0000000000 --- a/LibC/syscall.h +++ /dev/null @@ -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; -} - -} - diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp index ed32499059..113a9a56c1 100644 --- a/VirtualFileSystem/FileHandle.cpp +++ b/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()); diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 4f5b11aa2b..c4c831b9c1 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/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 VirtualFileSystem::open(const String& path) { + Locker locker(VirtualFileSystem::lock()); + auto inode = resolvePath(path); if (!inode.isValid()) return nullptr; @@ -355,6 +368,8 @@ OwnPtr VirtualFileSystem::open(const String& path) OwnPtr 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 VirtualFileSystem::create(const String& path) OwnPtr 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); diff --git a/VirtualFileSystem/VirtualFileSystem.h b/VirtualFileSystem/VirtualFileSystem.h index c16efa130f..2fa31b51b9 100644 --- a/VirtualFileSystem/VirtualFileSystem.h +++ b/VirtualFileSystem/VirtualFileSystem.h @@ -5,6 +5,7 @@ #include #include #include +#include #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; diff --git a/VirtualFileSystem/test.cpp b/VirtualFileSystem/test.cpp index 9ad43f3470..a883155a3d 100644 --- a/VirtualFileSystem/test.cpp +++ b/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();