*/
errval_t sys_print(const char *string, size_t length);
+/**
+ * \brief get time elapsed since system boot.
+ */
+uint64_t sys_get_absolute_time(void);
__END_DECLS
#endif //LIBBARRELFISH_SYSCALL_H
#define SYSCALL_X86_RELOAD_LDT 8 ///< Reload the LDT register (x86_64)
#define SYSCALL_SUSPEND 9 ///< Suspend the CPU
+#define SYSCALL_GET_ABS_TIME 10 ///< Get time elapsed since boot
-#define SYSCALL_COUNT 10 ///< Number of syscalls [0..SYSCALL_COUNT - 1]
+#define SYSCALL_COUNT 11 ///< Number of syscalls [0..SYSCALL_COUNT - 1]
/*
* To understand system calls it might be helpful to know that there
TRACE(KERNEL, SC_SUSPEND, 1);
break;
+ case SYSCALL_GET_ABS_TIME:
+ retval = sys_get_absolute_time();
+ break;
+
case SYSCALL_DEBUG:
switch(arg0) {
case DEBUG_CONTEXT_COUNTER_RESET:
struct sysret sys_kernel_remove_kcb(struct kcb* kcb_addr);
struct sysret sys_kernel_suspend_kcb_sched(bool toggle);
struct sysret sys_handle_kcb_identify(struct capability* to);
+struct sysret sys_get_absolute_time(void);
/*
* Monitor syscalls
.value = mem_to_local_phys(vkcb) | OBJBITS_KCB,
};
}
+
+struct sysret sys_get_absolute_time(void)
+{
+ // Return kernel_now.
+ // XXX: this may not provide all the properties of absolute time we want,
+ // but should be sufficient to implement stuff that needs timing with 1/10
+ // of a second accuracy range.
+ return (struct sysret) {
+ .error = SYS_ERR_OK,
+ .value = kernel_now + kcb_current->kernel_off,
+ };
+}
{
return syscall3(SYSCALL_PRINT, (uintptr_t)string, length).error;
}
+
+uint64_t sys_get_absolute_time(void)
+{
+ struct sysret r = syscall1(SYSCALL_GET_ABS_TIME);
+ assert(err_is_ok(r.error));
+ return r.value;
+}
return time_point(duration(fp()));
}
+#elif defined (BARRELFISH)
+#include <barrelfish/syscalls.h>
+// For BF we're doing something similar to the Mach code above where we use
+// the number of milliseconds elapsed since boot for steady_clock.
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
+ auto t = static_cast<steady_clock::rep>(sys_get_absolute_time() * 1000 * 1000);
+ return time_point(duration(t));
+}
+
#else // __APPLE__
// FIXME: We assume that clock_gettime(CLOCK_MONOTONIC) works on
// non-apple systems. Instead, we should check _POSIX_TIMERS and
"stl_templates.cpp",
"stl_threads.cpp",
"stl_io.cpp",
+ "stl_chrono.cpp",
"cxx11.cpp"
],
--addLibraries = [
void stl_exception_test(void);
void stl_thread_test(void);
void cx11_test(void);
+void stl_chrono_test(void);
#endif /* CXXTEST_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <iostream>
+#include <chrono>
+#include <thread>
+#include <string>
+
+#include "cxxtest.hpp"
+
+static void func(int d)
+{
+ using namespace std::chrono;
+ steady_clock::time_point start = steady_clock::now();
+ steady_clock::time_point current, notified;
+ while (true) {
+ current = steady_clock::now();
+ if (duration_cast<std::chrono::duration<double>>
+ (current - start).count() >= d){
+ break;
+ }
+ else {
+ // notify user how much time of the experiment has passed
+ long diff = duration_cast<std::chrono::duration
+ <double>>(current - notified).count();
+ if (diff >= (d/100.0)) {
+ notified = high_resolution_clock::now();
+ diff = duration_cast<std::chrono::duration
+ <double>>(notified - start).count();
+ std::cout << (int) (100.0 * diff / d)
+ << "% completed." << std::endl;
+ }
+ // sleep for a while
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ }
+ }
+}
+
+static void timeout_test(void) {
+ auto s = std::chrono::steady_clock::now();
+ std::thread t(func, 10);
+ t.join();
+ auto d = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - s);
+ std::cout << ((d.count() >= 10) ? "PASS" : "FAIL") << std::endl;
+}
+
+void stl_chrono_test(void)
+{
+ timeout_test();
+}
cx11_test();
stl_thread_test();
+ stl_chrono_test();
+
std::cout << "Tests done: SUCCESS" << std::endl;
return 0;
}