diff --git a/Kernel/Ext2FileSystem.cpp b/Kernel/Ext2FileSystem.cpp index 7ae1bb65a6..7c990a87ee 100644 --- a/Kernel/Ext2FileSystem.cpp +++ b/Kernel/Ext2FileSystem.cpp @@ -317,7 +317,9 @@ void Ext2FS::free_inode(Ext2FSInode& inode) ASSERT(inode.m_raw_inode.i_links_count == 0); 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); auto block_list = block_list_for_inode(inode.m_raw_inode, true); @@ -1178,16 +1180,17 @@ RetainPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& n else initial_links_count = 1; - auto timestamp = RTC::now(); + struct timeval now; + kgettimeofday(now); ext2_inode e2inode; memset(&e2inode, 0, sizeof(ext2_inode)); e2inode.i_mode = mode; e2inode.i_uid = current->process().euid(); e2inode.i_gid = current->process().egid(); e2inode.i_size = size; - e2inode.i_atime = timestamp; - e2inode.i_ctime = timestamp; - e2inode.i_mtime = timestamp; + e2inode.i_atime = now.tv_sec; + e2inode.i_ctime = now.tv_sec; + e2inode.i_mtime = now.tv_sec; e2inode.i_dtime = 0; e2inode.i_links_count = initial_links_count; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 9cbe0fc673..363487ebd5 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -915,9 +915,10 @@ int Process::sys$utime(const char* pathname, const utimbuf* buf) atime = buf->actime; mtime = buf->modtime; } else { - auto now = RTC::now(); - mtime = now; - atime = now; + struct timeval now; + kgettimeofday(now); + mtime = now.tv_sec; + atime = now.tv_sec; } return VFS::the().utime(String(pathname), cwd_inode(), atime, mtime); } @@ -1238,8 +1239,8 @@ int Process::sys$sleep(unsigned seconds) void kgettimeofday(timeval& tv) { - tv.tv_sec = RTC::now(); - tv.tv_usec = (PIT::ticks_since_boot() % 1000) * 1000; + tv.tv_sec = RTC::boot_time() + PIT::seconds_since_boot(); + tv.tv_usec = PIT::ticks_this_second() * 1000; } int Process::sys$gettimeofday(timeval* tv) diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 898bd0d9cd..8acf886e5a 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -55,15 +55,15 @@ bool Scheduler::pick_next() return context_switch(s_colonel_process->main_thread()); } - auto now_sec = RTC::now(); - auto now_usec = (suseconds_t)((PIT::ticks_since_boot() % 1000) * 1000); + struct timeval now; + kgettimeofday(now); + auto now_sec = now.tv_sec; + auto now_usec = now.tv_usec; // Check and unblock threads whose wait conditions have been met. Thread::for_each([&] (Thread& thread) { 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.wakeup_time() <= system.uptime) thread.unblock(); diff --git a/Kernel/i8253.cpp b/Kernel/i8253.cpp index 4de7378964..56d49ca0fa 100644 --- a/Kernel/i8253.cpp +++ b/Kernel/i8253.cpp @@ -57,26 +57,34 @@ asm( #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) { 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); } 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() { - s_ticks_since_boot = 0; - word timer_reload; IO::out8(PIT_CTL, TIMER0_SELECT | WRITE_WORD | MODE_SQUARE_WAVE); diff --git a/Kernel/i8253.h b/Kernel/i8253.h index 8f2878ca31..737880c00d 100644 --- a/Kernel/i8253.h +++ b/Kernel/i8253.h @@ -7,6 +7,7 @@ namespace PIT { void initialize(); -dword ticks_since_boot(); +dword ticks_this_second(); +dword seconds_since_boot(); }