gettimeofday: gather variables into new struct
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#ifndef __HEADER_SYSCALL_H
|
#ifndef __HEADER_SYSCALL_H
|
||||||
#define __HEADER_SYSCALL_H
|
#define __HEADER_SYSCALL_H
|
||||||
|
|
||||||
|
#include <ihk/atomic.h>
|
||||||
#include <ihk/context.h>
|
#include <ihk/context.h>
|
||||||
#include <ihk/memconst.h>
|
#include <ihk/memconst.h>
|
||||||
#include <rlimit.h>
|
#include <rlimit.h>
|
||||||
@@ -288,8 +289,13 @@ struct procfs_file {
|
|||||||
|
|
||||||
extern void terminate(int, int);
|
extern void terminate(int, int);
|
||||||
|
|
||||||
/* kernel/syscall.c */
|
struct tod_data_s {
|
||||||
extern struct timespec origin_ts; /* realtime when tsc=0 */
|
int8_t do_local;
|
||||||
extern unsigned long clocks_per_sec;
|
int8_t padding[7];
|
||||||
|
ihk_atomic64_t version;
|
||||||
|
unsigned long clocks_per_sec;
|
||||||
|
struct timespec origin; /* realtime when tsc=0 */
|
||||||
|
};
|
||||||
|
extern struct tod_data_s tod_data;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -211,16 +211,20 @@ static void time_init(void)
|
|||||||
ihk_mc_get_boot_time(&tv_sec, &tv_nsec);
|
ihk_mc_get_boot_time(&tv_sec, &tv_nsec);
|
||||||
ns_per_kclock = ihk_mc_get_ns_per_tsc();
|
ns_per_kclock = ihk_mc_get_ns_per_tsc();
|
||||||
|
|
||||||
origin_ts.tv_sec = tv_sec;
|
tod_data.origin.tv_sec = tv_sec;
|
||||||
origin_ts.tv_nsec = tv_nsec;
|
tod_data.origin.tv_nsec = tv_nsec;
|
||||||
|
|
||||||
if (ns_per_kclock) {
|
if (ns_per_kclock) {
|
||||||
clocks_per_sec = (1000L * NS_PER_SEC) / ns_per_kclock;
|
tod_data.clocks_per_sec = (1000L * NS_PER_SEC) / ns_per_kclock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ns_per_kclock) {
|
if (!ns_per_kclock) {
|
||||||
gettime_local_support = 0;
|
gettime_local_support = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gettime_local_support) {
|
||||||
|
tod_data.do_local = 1;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,10 +95,11 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
|
|||||||
#undef SYSCALL_DELEGATED
|
#undef SYSCALL_DELEGATED
|
||||||
};
|
};
|
||||||
|
|
||||||
struct timespec origin_ts;
|
struct tod_data_s tod_data = {
|
||||||
static ihk_spinlock_t origin_ts_lock = SPIN_LOCK_UNLOCKED;
|
.do_local = 0,
|
||||||
ihk_atomic64_t origin_ts_version = IHK_ATOMIC64_INIT(0);
|
.version = IHK_ATOMIC64_INIT(0),
|
||||||
unsigned long clocks_per_sec;
|
};
|
||||||
|
static ihk_spinlock_t tod_data_lock = SPIN_LOCK_UNLOCKED;
|
||||||
|
|
||||||
void check_signal(unsigned long, void *, int);
|
void check_signal(unsigned long, void *, int);
|
||||||
void do_signal(long rc, void *regs, struct thread *thread, struct sig_pending *pending, int num);
|
void do_signal(long rc, void *regs, struct thread *thread, struct sig_pending *pending, int num);
|
||||||
@@ -4825,14 +4826,14 @@ static void calculate_time_from_tsc(struct timespec *ts)
|
|||||||
long ns_delta;
|
long ns_delta;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while ((ver = ihk_atomic64_read(&origin_ts_version)) & 1) {
|
while ((ver = ihk_atomic64_read(&tod_data.version)) & 1) {
|
||||||
/* settimeofday() is in progress */
|
/* settimeofday() is in progress */
|
||||||
cpu_pause();
|
cpu_pause();
|
||||||
}
|
}
|
||||||
rmb();
|
rmb();
|
||||||
*ts = origin_ts;
|
*ts = tod_data.origin;
|
||||||
rmb();
|
rmb();
|
||||||
if (ver == ihk_atomic64_read(&origin_ts_version)) {
|
if (ver == ihk_atomic64_read(&tod_data.version)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4841,9 +4842,9 @@ static void calculate_time_from_tsc(struct timespec *ts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_tsc = rdtsc();
|
current_tsc = rdtsc();
|
||||||
sec_delta = current_tsc / clocks_per_sec;
|
sec_delta = current_tsc / tod_data.clocks_per_sec;
|
||||||
ns_delta = NS_PER_SEC * (current_tsc % clocks_per_sec)
|
ns_delta = NS_PER_SEC * (current_tsc % tod_data.clocks_per_sec)
|
||||||
/ clocks_per_sec;
|
/ tod_data.clocks_per_sec;
|
||||||
/* calc. of ns_delta overflows if clocks_per_sec exceeds 18.44 GHz */
|
/* calc. of ns_delta overflows if clocks_per_sec exceeds 18.44 GHz */
|
||||||
|
|
||||||
ts->tv_sec += sec_delta;
|
ts->tv_sec += sec_delta;
|
||||||
@@ -4902,8 +4903,8 @@ SYSCALL_DECLARE(settimeofday)
|
|||||||
unsigned long tsc;
|
unsigned long tsc;
|
||||||
|
|
||||||
dkprintf("sys_settimeofday(%p,%p)\n", utv, utz);
|
dkprintf("sys_settimeofday(%p,%p)\n", utv, utz);
|
||||||
ihk_mc_spinlock_lock_noirq(&origin_ts_lock);
|
ihk_mc_spinlock_lock_noirq(&tod_data_lock);
|
||||||
if (ihk_atomic64_read(&origin_ts_version) & 1) {
|
if (ihk_atomic64_read(&tod_data.version) & 1) {
|
||||||
panic("settimeofday");
|
panic("settimeofday");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4916,9 +4917,9 @@ SYSCALL_DECLARE(settimeofday)
|
|||||||
newts.tv_nsec = (long)tv.tv_usec * 1000;
|
newts.tv_nsec = (long)tv.tv_usec * 1000;
|
||||||
|
|
||||||
tsc = rdtsc();
|
tsc = rdtsc();
|
||||||
newts.tv_sec -= tsc / clocks_per_sec;
|
newts.tv_sec -= tsc / tod_data.clocks_per_sec;
|
||||||
newts.tv_nsec -= NS_PER_SEC * (tsc % clocks_per_sec)
|
newts.tv_nsec -= NS_PER_SEC * (tsc % tod_data.clocks_per_sec)
|
||||||
/ clocks_per_sec;
|
/ tod_data.clocks_per_sec;
|
||||||
if (newts.tv_nsec < 0) {
|
if (newts.tv_nsec < 0) {
|
||||||
--newts.tv_sec;
|
--newts.tv_sec;
|
||||||
newts.tv_nsec += NS_PER_SEC;
|
newts.tv_nsec += NS_PER_SEC;
|
||||||
@@ -4928,17 +4929,17 @@ SYSCALL_DECLARE(settimeofday)
|
|||||||
error = syscall_generic_forwarding(n, ctx);
|
error = syscall_generic_forwarding(n, ctx);
|
||||||
|
|
||||||
if (!error && utv && gettime_local_support) {
|
if (!error && utv && gettime_local_support) {
|
||||||
dkprintf("sys_settimeofday(%p,%p):origin_ts <-- %ld.%ld\n",
|
dkprintf("sys_settimeofday(%p,%p):origin <-- %ld.%ld\n",
|
||||||
utv, utz, newts.tv_sec, newts.tv_nsec);
|
utv, utz, newts.tv_sec, newts.tv_nsec);
|
||||||
ihk_atomic64_inc(&origin_ts_version);
|
ihk_atomic64_inc(&tod_data.version);
|
||||||
wmb();
|
wmb();
|
||||||
origin_ts = newts;
|
tod_data.origin = newts;
|
||||||
wmb();
|
wmb();
|
||||||
ihk_atomic64_inc(&origin_ts_version);
|
ihk_atomic64_inc(&tod_data.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ihk_mc_spinlock_unlock_noirq(&origin_ts_lock);
|
ihk_mc_spinlock_unlock_noirq(&tod_data_lock);
|
||||||
dkprintf("sys_settimeofday(%p,%p): %ld\n", utv, utz, error);
|
dkprintf("sys_settimeofday(%p,%p): %ld\n", utv, utz, error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user