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:
Ingo Weinhold
2009-12-07 21:43:19 +00:00
parent db905187d5
commit 34a48c70ef
13 changed files with 155 additions and 15 deletions
+2 -1
View File
@@ -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 */
+1
View File
@@ -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;
+2 -1
View File
@@ -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);
+13 -1
View File
@@ -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;
} }
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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)
; ;
+4
View File
@@ -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
; ;
+4
View File
@@ -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)
+16 -2
View File
@@ -1,4 +1,4 @@
/* /*
* Copyright 2004, Axel Dörfler, [email protected]. * Copyright 2004, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -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);
}
} }