mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 04:38:11 +00:00
Kernel+LibC: Publish a "kernel info page" and use it for gettimeofday()
This patch adds a single "kernel info page" that is mappable read-only by any process and contains the current time of day. This is then used to implement a version of gettimeofday() that doesn't have to make a syscall. To protect against race condition issues, the info page also has a serial number which is incremented whenever the kernel updates the contents of the page. Make sure to verify that the serial number is the same before and after reading the information you want from the page.
This commit is contained in:
parent
931e4b7f5e
commit
77cf607cda
6 changed files with 62 additions and 9 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <Kernel/IO.h>
|
||||
#include <Kernel/KBufferBuilder.h>
|
||||
#include <Kernel/KSyms.h>
|
||||
#include <Kernel/KernelInfoPage.h>
|
||||
#include <Kernel/Module.h>
|
||||
#include <Kernel/Multiboot.h>
|
||||
#include <Kernel/Net/Socket.h>
|
||||
|
@ -51,11 +52,13 @@
|
|||
//#define SHARED_BUFFER_DEBUG
|
||||
|
||||
static void create_signal_trampolines();
|
||||
static void create_kernel_info_page();
|
||||
|
||||
static pid_t next_pid;
|
||||
InlineLinkedList<Process>* g_processes;
|
||||
static String* s_hostname;
|
||||
static Lock* s_hostname_lock;
|
||||
static VirtualAddress s_info_page_address;
|
||||
VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
||||
VirtualAddress g_return_to_ring0_from_signal_trampoline;
|
||||
HashMap<String, OwnPtr<Module>>* g_modules;
|
||||
|
@ -70,6 +73,14 @@ void Process::initialize()
|
|||
s_hostname_lock = new Lock;
|
||||
|
||||
create_signal_trampolines();
|
||||
create_kernel_info_page();
|
||||
}
|
||||
|
||||
void Process::update_info_page_timestamp(const timeval& tv)
|
||||
{
|
||||
auto* info_page = (KernelInfoPage*)s_info_page_address.as_ptr();
|
||||
info_page->serial++;
|
||||
const_cast<timeval&>(info_page->now) = tv;
|
||||
}
|
||||
|
||||
Vector<pid_t> Process::all_pids()
|
||||
|
@ -981,6 +992,13 @@ void create_signal_trampolines()
|
|||
trampoline_region->remap();
|
||||
}
|
||||
|
||||
void create_kernel_info_page()
|
||||
{
|
||||
auto* info_page_region = MM.allocate_user_accessible_kernel_region(PAGE_SIZE, "Kernel info page").leak_ptr();
|
||||
s_info_page_address = info_page_region->vaddr();
|
||||
memset(s_info_page_address.as_ptr(), 0, PAGE_SIZE);
|
||||
}
|
||||
|
||||
int Process::sys$restore_signal_mask(u32 mask)
|
||||
{
|
||||
current->m_signal_mask = mask;
|
||||
|
@ -1682,10 +1700,7 @@ int Process::sys$sleep(unsigned seconds)
|
|||
|
||||
timeval kgettimeofday()
|
||||
{
|
||||
timeval tv;
|
||||
tv.tv_sec = RTC::boot_time() + PIT::seconds_since_boot();
|
||||
tv.tv_usec = PIT::ticks_this_second() * 1000;
|
||||
return tv;
|
||||
return const_cast<const timeval&>(((KernelInfoPage*)s_info_page_address.as_ptr())->now);
|
||||
}
|
||||
|
||||
void kgettimeofday(timeval& tv)
|
||||
|
@ -1697,7 +1712,7 @@ int Process::sys$gettimeofday(timeval* tv)
|
|||
{
|
||||
if (!validate_write_typed(tv))
|
||||
return -EFAULT;
|
||||
kgettimeofday(*tv);
|
||||
*tv = kgettimeofday();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3733,3 +3748,8 @@ int Process::sys$profiling_disable(pid_t pid)
|
|||
Profiling::stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* Process::sys$get_kernel_info_page()
|
||||
{
|
||||
return s_info_page_address.as_ptr();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue