summaryrefslogtreecommitdiff
path: root/Libraries/LibC/time.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-15 21:29:26 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-15 21:29:26 +0100
commit77cf607cdabfdf9231767556b86e85be0f40b20b (patch)
tree84ca0b4b1ae1d1ba05721ea7407bd6be5844f594 /Libraries/LibC/time.cpp
parent931e4b7f5ec8a5ced69c3789ecdcf0772cbee7ef (diff)
downloadserenity-77cf607cdabfdf9231767556b86e85be0f40b20b.zip
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.
Diffstat (limited to 'Libraries/LibC/time.cpp')
-rw-r--r--Libraries/LibC/time.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/Libraries/LibC/time.cpp b/Libraries/LibC/time.cpp
index 4cd2e47fd9..d0d156d67e 100644
--- a/Libraries/LibC/time.cpp
+++ b/Libraries/LibC/time.cpp
@@ -1,10 +1,11 @@
+#include <Kernel/KernelInfoPage.h>
#include <Kernel/Syscall.h>
#include <assert.h>
#include <errno.h>
+#include <string.h>
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
-#include <string.h>
extern "C" {
@@ -21,8 +22,17 @@ time_t time(time_t* tloc)
int gettimeofday(struct timeval* __restrict__ tv, void* __restrict__)
{
- int rc = syscall(SC_gettimeofday, tv);
- __RETURN_WITH_ERRNO(rc, rc, -1);
+ static volatile KernelInfoPage* kernel_info;
+ if (!kernel_info)
+ kernel_info = (volatile KernelInfoPage*)syscall(SC_get_kernel_info_page);
+
+ for (;;) {
+ auto serial = kernel_info->serial;
+ *tv = const_cast<struct timeval&>(kernel_info->now);
+ if (serial == kernel_info->serial)
+ break;
+ }
+ return 0;
}
char* ctime(const time_t*)