MMU is can now be locked with RecursiveSpinLock.
Scheduler now has get_current_tid() that works before the Scheduler
is initialized. This allows RecursiveSpinLock usage early on.
We now assign every (userspace) process its own MMU which we load
in scheduler. This allows every process to have separate virtual
address space.
This is very hackish implementations but it works for now
Now after each interrupt we will ask the scheduler to reschedule
if the current thread is the idle thread. This allows semaphore
unblocking to be practically instant when there is only one thread
executing.
Now disk reading is back to ~3 MB/s for single threaded process
This disables interrupts for the current scope and restores them
after the scope. This is used in kmalloc, since scheduler might
call into kmalloc/kfree, but deadlock if some thread is currently
trying to allocate. This allows us to use kmalloc in Scheduler.
We can now use arbitary BAN::function<void(...)> as the Thread.
I also implemented multithreading for i386 since it was not done
on the initial multithreading commit.
This still uses only a single cpu, but we can now have 'parallelization'
This seems to work fine in qemu and bochs, but my own computer did not
like this when I last tried.
I have absolutely no idea how multithreading should actually be
implmemented and I just thought and implemented the most simple one I
could think of. This might not be in any way correct :D