+ movl %esp,%ebp
+ pushl %esi
+ pushl %ebx
+
+0:
+ movl _COMM_PAGE_NT_GENERATION,%esi /* get generation (0 if being changed) */
+ testl %esi,%esi /* if being updated, loop until stable */
+ jz 0b
+
+ lfence
+ rdtsc /* get TSC in %edx:%eax */
+ lfence
+
+ subl _COMM_PAGE_NT_TSC_BASE,%eax
+ sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx
+
+ movl _COMM_PAGE_NT_SCALE,%ecx
+
+ movl %edx,%ebx
+ mull %ecx
+ movl %ebx,%eax
+ movl %edx,%ebx
+ mull %ecx
+ addl %ebx,%eax
+ adcl $0,%edx
+
+ addl _COMM_PAGE_NT_NS_BASE,%eax
+ adcl _COMM_PAGE_NT_NS_BASE+4,%edx
+
+ cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */
+ jne 0b /* yes, loop until stable */
+
+ popl %ebx
+ popl %esi
+ popl %ebp
+ ret
+
+ COMMPAGE_DESCRIPTOR(nanotime,_COMM_PAGE_NANOTIME,0,kSlow)
+
+
+/* nanotime routine for machines slower than ~1Gz (SLOW_TSC_THRESHOLD) */
+Lnanotime_slow:
+ push %ebp
+ mov %esp,%ebp
+ push %esi
+ push %edi
+ push %ebx
+
+0:
+ movl _COMM_PAGE_NT_GENERATION,%esi
+ testl %esi,%esi /* if generation is 0, data being changed */
+ jz 0b /* so loop until stable */
+
+ lfence
+ rdtsc /* get TSC in %edx:%eax */
+ lfence
+ subl _COMM_PAGE_NT_TSC_BASE,%eax
+ sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx