mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 14:35:07 +00:00
Kernel: Do timekeeping manually instead of asking the RTC all the time.
This introduces a tiny amount of timer drift which I will have to fix somehow eventually, but it's a huge improvement in timing consistency as we no longer suddenly jump from e.g 10:45:49.123 to 10:45:50.000.
This commit is contained in:
parent
20f7d7ec67
commit
ab11f42094
5 changed files with 34 additions and 21 deletions
|
@ -317,7 +317,9 @@ void Ext2FS::free_inode(Ext2FSInode& inode)
|
||||||
ASSERT(inode.m_raw_inode.i_links_count == 0);
|
ASSERT(inode.m_raw_inode.i_links_count == 0);
|
||||||
dbgprintf("Ext2FS: inode %u has no more links, time to delete!\n", inode.index());
|
dbgprintf("Ext2FS: inode %u has no more links, time to delete!\n", inode.index());
|
||||||
|
|
||||||
inode.m_raw_inode.i_dtime = RTC::now();
|
struct timeval now;
|
||||||
|
kgettimeofday(now);
|
||||||
|
inode.m_raw_inode.i_dtime = now.tv_sec;
|
||||||
write_ext2_inode(inode.index(), inode.m_raw_inode);
|
write_ext2_inode(inode.index(), inode.m_raw_inode);
|
||||||
|
|
||||||
auto block_list = block_list_for_inode(inode.m_raw_inode, true);
|
auto block_list = block_list_for_inode(inode.m_raw_inode, true);
|
||||||
|
@ -1178,16 +1180,17 @@ RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& n
|
||||||
else
|
else
|
||||||
initial_links_count = 1;
|
initial_links_count = 1;
|
||||||
|
|
||||||
auto timestamp = RTC::now();
|
struct timeval now;
|
||||||
|
kgettimeofday(now);
|
||||||
ext2_inode e2inode;
|
ext2_inode e2inode;
|
||||||
memset(&e2inode, 0, sizeof(ext2_inode));
|
memset(&e2inode, 0, sizeof(ext2_inode));
|
||||||
e2inode.i_mode = mode;
|
e2inode.i_mode = mode;
|
||||||
e2inode.i_uid = current->process().euid();
|
e2inode.i_uid = current->process().euid();
|
||||||
e2inode.i_gid = current->process().egid();
|
e2inode.i_gid = current->process().egid();
|
||||||
e2inode.i_size = size;
|
e2inode.i_size = size;
|
||||||
e2inode.i_atime = timestamp;
|
e2inode.i_atime = now.tv_sec;
|
||||||
e2inode.i_ctime = timestamp;
|
e2inode.i_ctime = now.tv_sec;
|
||||||
e2inode.i_mtime = timestamp;
|
e2inode.i_mtime = now.tv_sec;
|
||||||
e2inode.i_dtime = 0;
|
e2inode.i_dtime = 0;
|
||||||
e2inode.i_links_count = initial_links_count;
|
e2inode.i_links_count = initial_links_count;
|
||||||
|
|
||||||
|
|
|
@ -915,9 +915,10 @@ int Process::sys$utime(const char* pathname, const utimbuf* buf)
|
||||||
atime = buf->actime;
|
atime = buf->actime;
|
||||||
mtime = buf->modtime;
|
mtime = buf->modtime;
|
||||||
} else {
|
} else {
|
||||||
auto now = RTC::now();
|
struct timeval now;
|
||||||
mtime = now;
|
kgettimeofday(now);
|
||||||
atime = now;
|
mtime = now.tv_sec;
|
||||||
|
atime = now.tv_sec;
|
||||||
}
|
}
|
||||||
return VFS::the().utime(String(pathname), cwd_inode(), atime, mtime);
|
return VFS::the().utime(String(pathname), cwd_inode(), atime, mtime);
|
||||||
}
|
}
|
||||||
|
@ -1238,8 +1239,8 @@ int Process::sys$sleep(unsigned seconds)
|
||||||
|
|
||||||
void kgettimeofday(timeval& tv)
|
void kgettimeofday(timeval& tv)
|
||||||
{
|
{
|
||||||
tv.tv_sec = RTC::now();
|
tv.tv_sec = RTC::boot_time() + PIT::seconds_since_boot();
|
||||||
tv.tv_usec = (PIT::ticks_since_boot() % 1000) * 1000;
|
tv.tv_usec = PIT::ticks_this_second() * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$gettimeofday(timeval* tv)
|
int Process::sys$gettimeofday(timeval* tv)
|
||||||
|
|
|
@ -55,15 +55,15 @@ bool Scheduler::pick_next()
|
||||||
return context_switch(s_colonel_process->main_thread());
|
return context_switch(s_colonel_process->main_thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now_sec = RTC::now();
|
struct timeval now;
|
||||||
auto now_usec = (suseconds_t)((PIT::ticks_since_boot() % 1000) * 1000);
|
kgettimeofday(now);
|
||||||
|
auto now_sec = now.tv_sec;
|
||||||
|
auto now_usec = now.tv_usec;
|
||||||
|
|
||||||
// Check and unblock threads whose wait conditions have been met.
|
// Check and unblock threads whose wait conditions have been met.
|
||||||
Thread::for_each([&] (Thread& thread) {
|
Thread::for_each([&] (Thread& thread) {
|
||||||
auto& process = thread.process();
|
auto& process = thread.process();
|
||||||
|
|
||||||
// dbgprintf("pick_next, checking on %s(%u:%u) in state %s\n", process.name().impl()->characters(), process.pid(), thread.tid(), to_string(thread.state()));
|
|
||||||
|
|
||||||
if (thread.state() == Thread::BlockedSleep) {
|
if (thread.state() == Thread::BlockedSleep) {
|
||||||
if (thread.wakeup_time() <= system.uptime)
|
if (thread.wakeup_time() <= system.uptime)
|
||||||
thread.unblock();
|
thread.unblock();
|
||||||
|
|
|
@ -57,26 +57,34 @@ asm(
|
||||||
|
|
||||||
#define BASE_FREQUENCY 1193182
|
#define BASE_FREQUENCY 1193182
|
||||||
|
|
||||||
static dword s_ticks_since_boot;
|
static dword s_ticks_this_second;
|
||||||
|
static dword s_seconds_since_boot;
|
||||||
|
|
||||||
void timer_interrupt_handler(RegisterDump& regs)
|
void timer_interrupt_handler(RegisterDump& regs)
|
||||||
{
|
{
|
||||||
IRQHandlerScope scope(IRQ_TIMER);
|
IRQHandlerScope scope(IRQ_TIMER);
|
||||||
++s_ticks_since_boot;
|
if (++s_ticks_this_second >= TICKS_PER_SECOND) {
|
||||||
|
// FIXME: Synchronize with the RTC somehow to prevent drifting apart.
|
||||||
|
++s_seconds_since_boot;
|
||||||
|
s_ticks_this_second = 0;
|
||||||
|
}
|
||||||
Scheduler::timer_tick(regs);
|
Scheduler::timer_tick(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace PIT {
|
namespace PIT {
|
||||||
|
|
||||||
dword ticks_since_boot()
|
dword ticks_this_second()
|
||||||
{
|
{
|
||||||
return s_ticks_since_boot;
|
return s_ticks_this_second;
|
||||||
|
}
|
||||||
|
|
||||||
|
dword seconds_since_boot()
|
||||||
|
{
|
||||||
|
return s_seconds_since_boot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
s_ticks_since_boot = 0;
|
|
||||||
|
|
||||||
word timer_reload;
|
word timer_reload;
|
||||||
|
|
||||||
IO::out8(PIT_CTL, TIMER0_SELECT | WRITE_WORD | MODE_SQUARE_WAVE);
|
IO::out8(PIT_CTL, TIMER0_SELECT | WRITE_WORD | MODE_SQUARE_WAVE);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace PIT {
|
namespace PIT {
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
dword ticks_since_boot();
|
dword ticks_this_second();
|
||||||
|
dword seconds_since_boot();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue