Added type nanotime_t (an int64 storing a nanoseconds value) and function
system_time_nsecs(), returning the system time in nanoseconds. The function is only really implemented for x86. For the other architectures system_time() * 1000 is returned. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34543 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -367,7 +367,8 @@ extern bigtime_t real_time_clock_usecs(void);
|
|||||||
extern status_t set_timezone(const char *timezone);
|
extern status_t set_timezone(const char *timezone);
|
||||||
extern bigtime_t system_time(void);
|
extern bigtime_t system_time(void);
|
||||||
/* time since booting in microseconds */
|
/* time since booting in microseconds */
|
||||||
|
extern nanotime_t system_time_nsecs();
|
||||||
|
/* time since booting in nanoseconds */
|
||||||
|
|
||||||
/* Alarm */
|
/* Alarm */
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ typedef unsigned short unichar;
|
|||||||
/* descriptive types */
|
/* descriptive types */
|
||||||
typedef int32 status_t;
|
typedef int32 status_t;
|
||||||
typedef int64 bigtime_t;
|
typedef int64 bigtime_t;
|
||||||
|
typedef int64 nanotime_t;
|
||||||
typedef uint32 type_code;
|
typedef uint32 type_code;
|
||||||
typedef uint32 perform_code;
|
typedef uint32 perform_code;
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,8 @@ extern "C" {
|
|||||||
|
|
||||||
struct arch_thread;
|
struct arch_thread;
|
||||||
|
|
||||||
void __x86_setup_system_time(uint32 conversionFactor);
|
void __x86_setup_system_time(uint32 conversionFactor,
|
||||||
|
uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
|
||||||
void i386_context_switch(struct arch_thread* oldState,
|
void i386_context_switch(struct arch_thread* oldState,
|
||||||
struct arch_thread* newState, addr_t newPageDir);
|
struct arch_thread* newState, addr_t newPageDir);
|
||||||
void x86_userspace_thread_exit(void);
|
void x86_userspace_thread_exit(void);
|
||||||
|
|||||||
@@ -626,7 +626,19 @@ arch_cpu_init_percpu(kernel_args *args, int cpu)
|
|||||||
status_t
|
status_t
|
||||||
arch_cpu_init(kernel_args *args)
|
arch_cpu_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
__x86_setup_system_time(args->arch_args.system_time_cv_factor);
|
// init the TSC -> system_time() conversion factors
|
||||||
|
|
||||||
|
uint32 conversionFactor = args->arch_args.system_time_cv_factor;
|
||||||
|
uint64 conversionFactorNsecs = (uint64)conversionFactor * 1000;
|
||||||
|
|
||||||
|
if (conversionFactorNsecs >> 32 != 0) {
|
||||||
|
// the TSC frequency is < 1 GHz, which forces us to shift the factor
|
||||||
|
__x86_setup_system_time(conversionFactor, conversionFactorNsecs >> 16,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
// the TSC frequency is >= 1 GHz
|
||||||
|
__x86_setup_system_time(conversionFactor, conversionFactorNsecs, false);
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ;
|
|||||||
local posixSources = [ FDirName $(librootSources) posix ] ;
|
local posixSources = [ FDirName $(librootSources) posix ] ;
|
||||||
|
|
||||||
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
@@ -13,6 +14,8 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
|||||||
# system_time_asm.S
|
# system_time_asm.S
|
||||||
system_time.c
|
system_time.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
|
|
||||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ;
|
|||||||
local posixSources = [ FDirName $(librootSources) posix ] ;
|
local posixSources = [ FDirName $(librootSources) posix ] ;
|
||||||
|
|
||||||
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
@@ -13,6 +14,8 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
|||||||
system_time_asm.S
|
system_time_asm.S
|
||||||
system_time.c
|
system_time.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
|
|
||||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ;
|
|||||||
local posixSources = [ FDirName $(librootSources) posix ] ;
|
local posixSources = [ FDirName $(librootSources) posix ] ;
|
||||||
|
|
||||||
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
@@ -13,6 +14,8 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
|||||||
system_time_asm.S
|
system_time_asm.S
|
||||||
system_time.c
|
system_time.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
|
|
||||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ;
|
|||||||
local posixSources = [ FDirName $(librootSources) posix ] ;
|
local posixSources = [ FDirName $(librootSources) posix ] ;
|
||||||
|
|
||||||
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
@@ -13,6 +14,8 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
|||||||
system_time_asm.S
|
system_time_asm.S
|
||||||
system_time.c
|
system_time.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
|
|
||||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ SubDir HAIKU_TOP src system libroot os arch m68k ;
|
|||||||
UsePrivateKernelHeaders ;
|
UsePrivateKernelHeaders ;
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||||
|
|
||||||
MergeObject os_arch_$(TARGET_ARCH).o :
|
MergeObject os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
byteorder.S
|
byteorder.S
|
||||||
@@ -15,4 +17,6 @@ MergeObject os_arch_$(TARGET_ARCH).o :
|
|||||||
thread.c
|
thread.c
|
||||||
time.c
|
time.c
|
||||||
tls.c
|
tls.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ UsePrivateKernelHeaders ;
|
|||||||
# time.c!
|
# time.c!
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||||
|
|
||||||
MergeObject os_arch_$(TARGET_ARCH).o :
|
MergeObject os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
byteorder.S
|
byteorder.S
|
||||||
@@ -17,4 +19,6 @@ MergeObject os_arch_$(TARGET_ARCH).o :
|
|||||||
thread.c
|
thread.c
|
||||||
time.c
|
time.c
|
||||||
tls.c
|
tls.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ UsePrivateKernelHeaders ;
|
|||||||
# time.c!
|
# time.c!
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||||
|
|
||||||
MergeObject os_arch_$(TARGET_ARCH).o :
|
MergeObject os_arch_$(TARGET_ARCH).o :
|
||||||
atomic.S
|
atomic.S
|
||||||
byteorder.S
|
byteorder.S
|
||||||
@@ -17,4 +19,6 @@ MergeObject os_arch_$(TARGET_ARCH).o :
|
|||||||
thread.c
|
thread.c
|
||||||
time.c
|
time.c
|
||||||
tls.c
|
tls.c
|
||||||
|
|
||||||
|
generic_system_time_nsecs.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,31 +1,43 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
** Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*
|
||||||
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <asm_defs.h>
|
#include <asm_defs.h>
|
||||||
|
|
||||||
|
|
||||||
/* saves the conversion factor needed for system_time */
|
/* saves the conversion factor needed for system_time */
|
||||||
.lcomm cv_factor 4
|
.lcomm cv_factor 4
|
||||||
|
.lcomm cv_factor_nsecs 4
|
||||||
|
.lcomm cv_factor_nsecs_shift 1
|
||||||
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
||||||
FUNCTION(__x86_setup_system_time):
|
FUNCTION(__x86_setup_system_time):
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp), %eax
|
||||||
movl %eax,cv_factor
|
movl %eax, cv_factor
|
||||||
|
movl 8(%esp), %eax
|
||||||
|
movl %eax, cv_factor_nsecs
|
||||||
|
movb 12(%esp), %al
|
||||||
|
movb %al, cv_factor_nsecs_shift
|
||||||
ret
|
ret
|
||||||
FUNCTION_END(__x86_setup_system_time)
|
FUNCTION_END(__x86_setup_system_time)
|
||||||
|
|
||||||
/* long long system_time(); */
|
|
||||||
FUNCTION(system_time):
|
|
||||||
/* load 64-bit factor into %eax (low), %edx (high) */
|
|
||||||
rdtsc /* time in %edx,%eax */
|
|
||||||
|
|
||||||
|
/* int64 system_time(); */
|
||||||
|
FUNCTION(system_time):
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
movl cv_factor, %ebx
|
movl cv_factor, %ebx
|
||||||
|
|
||||||
|
/* load 64-bit factor into %eax (low), %edx (high) */
|
||||||
|
rdtsc /* time in %edx,%eax */
|
||||||
|
|
||||||
movl %edx, %ecx /* save high half */
|
movl %edx, %ecx /* save high half */
|
||||||
mull %ebx /* truncate %eax, but keep %edx */
|
mull %ebx /* truncate %eax, but keep %edx */
|
||||||
movl %ecx, %eax
|
movl %ecx, %eax
|
||||||
@@ -39,3 +51,78 @@ FUNCTION(system_time):
|
|||||||
popl %ebx
|
popl %ebx
|
||||||
ret
|
ret
|
||||||
FUNCTION_END(system_time)
|
FUNCTION_END(system_time)
|
||||||
|
|
||||||
|
|
||||||
|
/* int64 system_time_nsecs(); */
|
||||||
|
FUNCTION(system_time_nsecs):
|
||||||
|
testb $0, cv_factor_nsecs_shift
|
||||||
|
jne 1f
|
||||||
|
|
||||||
|
/* same algorithm as system_time(), just with a different factor */
|
||||||
|
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
movl cv_factor_nsecs, %ebx
|
||||||
|
|
||||||
|
/* load 64-bit factor into %eax (low), %edx (high) */
|
||||||
|
rdtsc /* time in %edx,%eax */
|
||||||
|
|
||||||
|
movl %edx, %ecx /* save high half */
|
||||||
|
mull %ebx /* truncate %eax, but keep %edx */
|
||||||
|
movl %ecx, %eax
|
||||||
|
movl %edx, %ecx /* save high half of low */
|
||||||
|
mull %ebx /*, %eax*/
|
||||||
|
/* now compute [%edx, %eax] + [%ecx], propagating carry */
|
||||||
|
subl %ebx, %ebx /* need zero to propagate carry */
|
||||||
|
addl %ecx, %eax
|
||||||
|
adc %ebx, %edx
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* TSC frequency is less than 1 GHz -- we shift everything up 16 bit */
|
||||||
|
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %esi
|
||||||
|
movl cv_factor_nsecs, %ebx
|
||||||
|
|
||||||
|
/* load 64-bit factor into %eax (low), %edx (high) */
|
||||||
|
rdtsc /* time in %edx,%eax */
|
||||||
|
|
||||||
|
/* save high half */
|
||||||
|
movl %edx, %ecx
|
||||||
|
|
||||||
|
/* multiply low half by conversion factor */
|
||||||
|
mull %ebx
|
||||||
|
|
||||||
|
/* save result */
|
||||||
|
movl %eax, %esi /* low half -> %esi */
|
||||||
|
movl %ecx, %eax
|
||||||
|
movl %edx, %ecx /* high half -> %ecx */
|
||||||
|
|
||||||
|
/* multiply high half by conversion factor */
|
||||||
|
mull %ebx
|
||||||
|
|
||||||
|
/* now compute [%edx, %eax] + [%ecx], propagating carry */
|
||||||
|
xorl %ebx, %ebx /* need zero to propagate carry */
|
||||||
|
addl %ecx, %eax
|
||||||
|
adc %ebx, %edx
|
||||||
|
|
||||||
|
/* shift the result left 16 bit */
|
||||||
|
shl $16, %edx
|
||||||
|
movl %eax, %ebx
|
||||||
|
shr $16, %ebx
|
||||||
|
orw %bx, %dx
|
||||||
|
shl $16, %eax
|
||||||
|
|
||||||
|
/* add the high 16 bit of the low half of the low product */
|
||||||
|
shr $16, %esi
|
||||||
|
orw %si, %ax
|
||||||
|
|
||||||
|
popl %esi
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
FUNCTION_END(system_time_nsecs)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
void
|
void
|
||||||
__arch_init_time(struct real_time_data *data, bool setDefaults)
|
__arch_init_time(struct real_time_data *data, bool setDefaults)
|
||||||
{
|
{
|
||||||
|
uint32 conversionFactor;
|
||||||
|
uint64 conversionFactorNsecs;
|
||||||
|
|
||||||
if (setDefaults) {
|
if (setDefaults) {
|
||||||
data->arch_data.system_time_offset = 0;
|
data->arch_data.system_time_offset = 0;
|
||||||
data->arch_data.system_time_conversion_factor = 100000;
|
data->arch_data.system_time_conversion_factor = 100000;
|
||||||
@@ -19,7 +22,18 @@ __arch_init_time(struct real_time_data *data, bool setDefaults)
|
|||||||
|
|
||||||
// TODO: this should only store a pointer to that value
|
// TODO: this should only store a pointer to that value
|
||||||
// When resolving this TODO, also resolve the one in the Jamfile.
|
// When resolving this TODO, also resolve the one in the Jamfile.
|
||||||
__x86_setup_system_time(data->arch_data.system_time_conversion_factor);
|
|
||||||
|
conversionFactor = data->arch_data.system_time_conversion_factor;
|
||||||
|
conversionFactorNsecs = (uint64)conversionFactor * 1000;
|
||||||
|
|
||||||
|
if (conversionFactorNsecs >> 32 != 0) {
|
||||||
|
// the TSC frequency is < 1 GHz, which forces us to shift the factor
|
||||||
|
__x86_setup_system_time(conversionFactor, conversionFactorNsecs >> 16,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
// the TSC frequency is >= 1 GHz
|
||||||
|
__x86_setup_system_time(conversionFactor, conversionFactorNsecs, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user