1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 11:18:13 +00:00

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.
This commit is contained in:
Andreas Kling 2018-10-23 23:32:53 +02:00
parent e4bfcd2346
commit 018da1be11
11 changed files with 88 additions and 203 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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()

View file

@ -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)

View file

@ -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.