[haiku-commits] r34543 - in haiku/trunk: headers/os/kernel headers/os/support headers/private/kernel/arch/x86 src/system/kernel/arch/x86 src/system/kernel/lib/arch/arm ...

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 7 Dec 2009 22:43:19 +0100 (CET)

Author: bonefish
Date: 2009-12-07 22:43:19 +0100 (Mon, 07 Dec 2009)
New Revision: 34543
Changeset: http://dev.haiku-os.org/changeset/34543/haiku

Modified:
   haiku/trunk/headers/os/kernel/OS.h
   haiku/trunk/headers/os/support/SupportDefs.h
   haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
   haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp
   haiku/trunk/src/system/kernel/lib/arch/arm/Jamfile
   haiku/trunk/src/system/kernel/lib/arch/m68k/Jamfile
   haiku/trunk/src/system/kernel/lib/arch/mipsel/Jamfile
   haiku/trunk/src/system/kernel/lib/arch/ppc/Jamfile
   haiku/trunk/src/system/libroot/os/arch/m68k/Jamfile
   haiku/trunk/src/system/libroot/os/arch/mipsel/Jamfile
   haiku/trunk/src/system/libroot/os/arch/ppc/Jamfile
   haiku/trunk/src/system/libroot/os/arch/x86/system_time_asm.S
   haiku/trunk/src/system/libroot/os/arch/x86/time.c
Log:
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.


Modified: haiku/trunk/headers/os/kernel/OS.h
===================================================================
--- haiku/trunk/headers/os/kernel/OS.h  2009-12-07 21:37:56 UTC (rev 34542)
+++ haiku/trunk/headers/os/kernel/OS.h  2009-12-07 21:43:19 UTC (rev 34543)
@@ -367,8 +367,9 @@
 extern status_t                set_timezone(const char *timezone);
 extern bigtime_t       system_time(void);
                                                /* time since booting in 
microseconds */
+extern nanotime_t      system_time_nsecs();
+                                               /* time since booting in 
nanoseconds */
 
-
 /* Alarm */
 
 enum {

Modified: haiku/trunk/headers/os/support/SupportDefs.h
===================================================================
--- haiku/trunk/headers/os/support/SupportDefs.h        2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/headers/os/support/SupportDefs.h        2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -52,6 +52,7 @@
 /* descriptive types */
 typedef int32                                  status_t;
 typedef int64                                  bigtime_t;
+typedef int64                                  nanotime_t;
 typedef uint32                                 type_code;
 typedef uint32                                 perform_code;
 

Modified: haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h      2009-12-07 
21:37:56 UTC (rev 34542)
+++ haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h      2009-12-07 
21:43:19 UTC (rev 34543)
@@ -262,7 +262,8 @@
 
 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,
        struct arch_thread* newState, addr_t newPageDir);
 void x86_userspace_thread_exit(void);

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp 2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp 2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -626,8 +626,20 @@
 status_t
 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;
 }
 

Modified: haiku/trunk/src/system/kernel/lib/arch/arm/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/lib/arch/arm/Jamfile  2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/kernel/lib/arch/arm/Jamfile  2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -6,6 +6,7 @@
 local posixSources = [ FDirName $(librootSources) posix ] ;
 
 SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
+SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
 
 KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
        atomic.S
@@ -13,6 +14,8 @@
 #      system_time_asm.S
        system_time.c
 
+       generic_system_time_nsecs.cpp
+
        : $(TARGET_KERNEL_PIC_CCFLAGS)
 ;
 

Modified: haiku/trunk/src/system/kernel/lib/arch/m68k/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/lib/arch/m68k/Jamfile 2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/kernel/lib/arch/m68k/Jamfile 2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -6,6 +6,7 @@
 local posixSources = [ FDirName $(librootSources) posix ] ;
 
 SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
+SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
 
 KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
        atomic.S
@@ -13,6 +14,8 @@
        system_time_asm.S
        system_time.c
 
+       generic_system_time_nsecs.cpp
+
        : $(TARGET_KERNEL_PIC_CCFLAGS)
 ;
 

Modified: haiku/trunk/src/system/kernel/lib/arch/mipsel/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/lib/arch/mipsel/Jamfile       2009-12-07 
21:37:56 UTC (rev 34542)
+++ haiku/trunk/src/system/kernel/lib/arch/mipsel/Jamfile       2009-12-07 
21:43:19 UTC (rev 34543)
@@ -6,6 +6,7 @@
 local posixSources = [ FDirName $(librootSources) posix ] ;
 
 SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
+SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
 
 KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
        atomic.S
@@ -13,6 +14,8 @@
        system_time_asm.S
        system_time.c
 
+       generic_system_time_nsecs.cpp
+
        : $(TARGET_KERNEL_PIC_CCFLAGS)
 ;
 

Modified: haiku/trunk/src/system/kernel/lib/arch/ppc/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/lib/arch/ppc/Jamfile  2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/kernel/lib/arch/ppc/Jamfile  2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -6,6 +6,7 @@
 local posixSources = [ FDirName $(librootSources) posix ] ;
 
 SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ;
+SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
 
 KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
        atomic.S
@@ -13,6 +14,8 @@
        system_time_asm.S
        system_time.c
 
+       generic_system_time_nsecs.cpp
+
        : $(TARGET_KERNEL_PIC_CCFLAGS)
 ;
 

Modified: haiku/trunk/src/system/libroot/os/arch/m68k/Jamfile
===================================================================
--- haiku/trunk/src/system/libroot/os/arch/m68k/Jamfile 2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/libroot/os/arch/m68k/Jamfile 2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -3,6 +3,8 @@
 UsePrivateKernelHeaders ;
 UsePrivateSystemHeaders ;
 
+SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
+
 MergeObject os_arch_$(TARGET_ARCH).o :
        atomic.S
        byteorder.S
@@ -15,4 +17,6 @@
        thread.c
        time.c
        tls.c
+
+       generic_system_time_nsecs.cpp
 ;

Modified: haiku/trunk/src/system/libroot/os/arch/mipsel/Jamfile
===================================================================
--- haiku/trunk/src/system/libroot/os/arch/mipsel/Jamfile       2009-12-07 
21:37:56 UTC (rev 34542)
+++ haiku/trunk/src/system/libroot/os/arch/mipsel/Jamfile       2009-12-07 
21:43:19 UTC (rev 34543)
@@ -5,6 +5,8 @@
        # time.c!
 UsePrivateSystemHeaders ;
 
+SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
+
 MergeObject os_arch_$(TARGET_ARCH).o :
        atomic.S
        byteorder.S
@@ -17,4 +19,6 @@
        thread.c
        time.c
        tls.c
+
+       generic_system_time_nsecs.cpp
 ;

Modified: haiku/trunk/src/system/libroot/os/arch/ppc/Jamfile
===================================================================
--- haiku/trunk/src/system/libroot/os/arch/ppc/Jamfile  2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/libroot/os/arch/ppc/Jamfile  2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -5,6 +5,8 @@
        # time.c!
 UsePrivateSystemHeaders ;
 
+SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
+
 MergeObject os_arch_$(TARGET_ARCH).o :
        atomic.S
        byteorder.S
@@ -17,4 +19,6 @@
        thread.c
        time.c
        tls.c
+
+       generic_system_time_nsecs.cpp
 ;

Modified: haiku/trunk/src/system/libroot/os/arch/x86/system_time_asm.S
===================================================================
--- haiku/trunk/src/system/libroot/os/arch/x86/system_time_asm.S        
2009-12-07 21:37:56 UTC (rev 34542)
+++ haiku/trunk/src/system/libroot/os/arch/x86/system_time_asm.S        
2009-12-07 21:43:19 UTC (rev 34543)
@@ -1,31 +1,72 @@
 /*
-** Copyright 2001, Travis Geiselbrecht. All rights reserved.
-** Distributed under the terms of the NewOS License.
-*/
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * 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>
 
 
 /* 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
 
+
 FUNCTION(__x86_setup_system_time):
-       movl    4(%esp),%eax
-       movl    %eax,cv_factor
+       movl    4(%esp), %eax
+       movl    %eax, cv_factor
+       movl    8(%esp), %eax
+       movl    %eax, cv_factor_nsecs
+       movb    12(%esp), %al
+       movb    %al, cv_factor_nsecs_shift
        ret
 FUNCTION_END(__x86_setup_system_time)
 
-/* long long system_time(); */
+
+/* int64 system_time(); */
 FUNCTION(system_time):
+       pushl   %ebx
+       pushl   %ecx
+       movl    cv_factor, %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
+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, %ebx
+       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
@@ -38,4 +79,50 @@
        popl    %ecx
        popl    %ebx
        ret
-FUNCTION_END(system_time)
+
+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)

Modified: haiku/trunk/src/system/libroot/os/arch/x86/time.c
===================================================================
--- haiku/trunk/src/system/libroot/os/arch/x86/time.c   2009-12-07 21:37:56 UTC 
(rev 34542)
+++ haiku/trunk/src/system/libroot/os/arch/x86/time.c   2009-12-07 21:43:19 UTC 
(rev 34543)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 2004, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
@@ -12,6 +12,9 @@
 void
 __arch_init_time(struct real_time_data *data, bool setDefaults)
 {
+       uint32 conversionFactor;
+       uint64 conversionFactorNsecs;
+
        if (setDefaults) {
                data->arch_data.system_time_offset = 0;
                data->arch_data.system_time_conversion_factor = 100000;
@@ -19,7 +22,18 @@
 
        // TODO: this should only store a pointer to that value
        // 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);
+       }
 }
 
 


Other related posts:

  • » [haiku-commits] r34543 - in haiku/trunk: headers/os/kernel headers/os/support headers/private/kernel/arch/x86 src/system/kernel/arch/x86 src/system/kernel/lib/arch/arm ... - ingo_weinhold