mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
Kernel: When a lock is busy, donate remaining process ticks to lock holder.
Since we know who's holding the lock, and we're gonna have to yield anyway, we can just ask the scheduler to donate any remaining ticks to that process.
This commit is contained in:
parent
4df92709c8
commit
5582a0a254
Notes:
sideshowbarker
2024-07-19 15:50:20 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/5582a0a254c
15 changed files with 51 additions and 15 deletions
|
@ -27,16 +27,19 @@ static inline dword CAS(volatile dword* mem, dword newval, dword oldval)
|
|||
|
||||
class Lock {
|
||||
public:
|
||||
Lock() { }
|
||||
Lock(const char* name = nullptr) : m_name(name) { }
|
||||
~Lock() { }
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
const char* name() const { return m_name; }
|
||||
|
||||
private:
|
||||
volatile dword m_lock { 0 };
|
||||
dword m_level { 0 };
|
||||
Process* m_holder { nullptr };
|
||||
const char* m_name { nullptr };
|
||||
};
|
||||
|
||||
class Locker {
|
||||
|
@ -65,7 +68,7 @@ inline void Lock::lock()
|
|||
}
|
||||
m_lock = 0;
|
||||
}
|
||||
Scheduler::yield();
|
||||
Scheduler::donate_to(m_holder, m_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +89,7 @@ inline void Lock::unlock()
|
|||
m_lock = 0;
|
||||
return;
|
||||
}
|
||||
Scheduler::yield();
|
||||
Scheduler::donate_to(m_holder, m_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ public:
|
|||
DoubleBuffer()
|
||||
: m_write_buffer(&m_buffer1)
|
||||
, m_read_buffer(&m_buffer2)
|
||||
, m_lock("DoubleBuffer")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,8 @@ FS::DirectoryEntry::DirectoryEntry(const char* n, size_t nl, InodeIdentifier i,
|
|||
}
|
||||
|
||||
Inode::Inode(FS& fs, unsigned index)
|
||||
: m_fs(fs)
|
||||
: m_lock("Inode")
|
||||
, m_fs(fs)
|
||||
, m_index(index)
|
||||
{
|
||||
all_inodes().set(this);
|
||||
|
|
|
@ -39,6 +39,7 @@ RetainPtr<IDEDiskDevice> IDEDiskDevice::create()
|
|||
|
||||
IDEDiskDevice::IDEDiskDevice()
|
||||
: IRQHandler(IRQ_FIXED_DISK)
|
||||
, m_lock("IDEDiskDevice")
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ PTYMultiplexer& PTYMultiplexer::the()
|
|||
|
||||
PTYMultiplexer::PTYMultiplexer()
|
||||
: CharacterDevice(5, 2)
|
||||
, m_lock("PTYMultiplexer")
|
||||
{
|
||||
s_the = this;
|
||||
m_freelist.ensure_capacity(s_max_pty_pairs);
|
||||
|
|
|
@ -496,7 +496,7 @@ ByteBuffer procfs$all(InodeIdentifier)
|
|||
auto processes = Process::all_processes();
|
||||
StringBuilder builder;
|
||||
auto build_process_line = [&builder] (Process* process) {
|
||||
builder.appendf("%u,%u,%u,%u,%u,%u,%u,%s,%u,%u,%s,%s,%u,%u,%u,%u\n",
|
||||
builder.appendf("%u,%u,%u,%u,%u,%u,%u,%s,%u,%u,%s,%s,%u,%u,%u,%u,%u\n",
|
||||
process->pid(),
|
||||
process->times_scheduled(),
|
||||
process->tty() ? process->tty()->pgid() : 0,
|
||||
|
@ -512,7 +512,8 @@ ByteBuffer procfs$all(InodeIdentifier)
|
|||
process->amount_virtual(),
|
||||
process->amount_resident(),
|
||||
process->amount_shared(),
|
||||
process->amount_in_bitmaps()
|
||||
process->amount_in_bitmaps(),
|
||||
process->ticks()
|
||||
);
|
||||
};
|
||||
build_process_line(Scheduler::colonel());
|
||||
|
|
|
@ -2192,3 +2192,13 @@ void Process::finalize_dying_processes()
|
|||
for (auto* process : dying_processes)
|
||||
process->finalize();
|
||||
}
|
||||
|
||||
bool Process::tick()
|
||||
{
|
||||
++m_ticks;
|
||||
if (tss().cs & 3)
|
||||
++m_ticks_in_user;
|
||||
else
|
||||
++m_ticks_in_kernel;
|
||||
return --m_ticks_left;
|
||||
}
|
||||
|
|
|
@ -131,8 +131,9 @@ public:
|
|||
template<typename Callback> static void for_each_living(Callback);
|
||||
template<typename Callback> void for_each_child(Callback);
|
||||
|
||||
bool tick() { ++m_ticks; return --m_ticks_left; }
|
||||
bool tick();
|
||||
void set_ticks_left(dword t) { m_ticks_left = t; }
|
||||
dword ticks_left() const { return m_ticks_left; }
|
||||
|
||||
void set_selector(word s) { m_far_ptr.selector = s; }
|
||||
void set_state(State s) { m_state = s; }
|
||||
|
|
|
@ -192,6 +192,24 @@ bool Scheduler::pick_next()
|
|||
}
|
||||
}
|
||||
|
||||
bool Scheduler::donate_to(Process* beneficiary, const char* reason)
|
||||
{
|
||||
(void)reason;
|
||||
unsigned ticks_left = current->ticks_left();
|
||||
if (!beneficiary || beneficiary->state() != Process::Runnable || ticks_left <= 1) {
|
||||
return yield();
|
||||
}
|
||||
|
||||
unsigned ticks_to_donate = ticks_left - 1;
|
||||
#ifdef SCHEDULER_DEBUG
|
||||
dbgprintf("%s(%u) donating %u ticks to %s(%u), reason=%s\n", current->name().characters(), current->pid(), ticks_to_donate, beneficiary->name().characters(), beneficiary->pid(), reason);
|
||||
#endif
|
||||
context_switch(*beneficiary);
|
||||
beneficiary->set_ticks_left(ticks_to_donate);
|
||||
switch_now();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Scheduler::yield()
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
|
@ -229,12 +247,6 @@ bool Scheduler::context_switch(Process& process)
|
|||
process.set_ticks_left(time_slice);
|
||||
process.did_schedule();
|
||||
|
||||
if (process.tss().cs & 3) {
|
||||
++process.m_ticks_in_user;
|
||||
} else {
|
||||
++process.m_ticks_in_kernel;
|
||||
}
|
||||
|
||||
if (current == &process)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ public:
|
|||
static void pick_next_and_switch_now();
|
||||
static void switch_now();
|
||||
static bool yield();
|
||||
static bool donate_to(Process*, const char* reason);
|
||||
static bool context_switch(Process&);
|
||||
static void prepare_to_modify_tss(Process&);
|
||||
static Process* colonel();
|
||||
|
|
|
@ -11,6 +11,7 @@ RetainPtr<SynthFS> SynthFS::create()
|
|||
}
|
||||
|
||||
SynthFS::SynthFS()
|
||||
: m_lock("SynthFS")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ static Snapshot get_snapshot()
|
|||
if (!ptr)
|
||||
break;
|
||||
auto parts = String(buf, Chomp).split(',');
|
||||
if (parts.size() < 16)
|
||||
if (parts.size() < 17)
|
||||
break;
|
||||
bool ok;
|
||||
pid_t pid = parts[0].to_uint(ok);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
static WSMessageLoop* s_the;
|
||||
|
||||
WSMessageLoop::WSMessageLoop()
|
||||
: m_lock("WSMessageLoop")
|
||||
{
|
||||
if (!s_the)
|
||||
s_the = this;
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
#include "Process.h"
|
||||
|
||||
WSWindow::WSWindow(Process& process, int window_id)
|
||||
: m_process(&process)
|
||||
: m_lock("WSWindow")
|
||||
, m_process(&process)
|
||||
, m_window_id(window_id)
|
||||
, m_pid(process.pid())
|
||||
{
|
||||
|
|
|
@ -130,6 +130,7 @@ void WSWindowManager::flip_buffers()
|
|||
WSWindowManager::WSWindowManager()
|
||||
: m_screen(WSScreen::the())
|
||||
, m_screen_rect(m_screen.rect())
|
||||
, m_lock("WSWindowManager")
|
||||
{
|
||||
#ifndef DEBUG_COUNTERS
|
||||
(void)m_compose_count;
|
||||
|
|
Loading…
Reference in a new issue