X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/13fec9890cf095cc781fdf7b8917cb03bf32dd4c..c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1:/osfmk/i386/commpage/commpage_gettimeofday.s diff --git a/osfmk/i386/commpage/commpage_gettimeofday.s b/osfmk/i386/commpage/commpage_gettimeofday.s index 6e84e601c..55bfd27ba 100644 --- a/osfmk/i386/commpage/commpage_gettimeofday.s +++ b/osfmk/i386/commpage/commpage_gettimeofday.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,11 +24,106 @@ #include #include +#define NSEC_PER_SEC 1000*1000*1000 +#define NSEC_PER_USEC 1000 + .text .align 2, 0x90 Lgettimeofday: - int $0x3 + push %ebp + mov %esp,%ebp + push %esi + push %edi + push %ebx + +0: + cmp $0,_COMM_PAGE_TIMEENABLE + je 4f + mov _COMM_PAGE_TIMEBASE,%esi + mov _COMM_PAGE_TIMEBASE+4,%edi + mov _COMM_PAGE_TIMESTAMP,%ebx + + mov $ _COMM_PAGE_NANOTIME,%eax + call *%eax /* get ns in %edx:%eax */ + + cmp _COMM_PAGE_TIMEBASE,%esi + jne 0b + cmp _COMM_PAGE_TIMEBASE+4,%edi + jne 0b + cmp $0,_COMM_PAGE_TIMEENABLE + je 4f + + mov $ NSEC_PER_SEC,%ecx + sub %esi,%eax + sbb %edi,%edx + div %ecx + add %eax,%ebx + + mov $ NSEC_PER_USEC,%ecx + mov %edx,%eax + xor %edx,%edx + div %ecx + + mov 8(%ebp),%ecx + mov %ebx,(%ecx) + mov %eax,4(%ecx) + xor %eax,%eax + +3: + pop %ebx + pop %edi + pop %esi + pop %ebp ret +4: /* fail */ + movl $1,%eax + jmp 3b COMMPAGE_DESCRIPTOR(gettimeofday,_COMM_PAGE_GETTIMEOFDAY,0,0) + + + .code64 + .text + .align 2, 0x90 + +Lgettimeofday_64: // %rdi = ptr to timeval + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq %rdi,%r9 // save ptr to timeval + movq $_COMM_PAGE_32_TO_64(_COMM_PAGE_TIMEBASE),%r10 +0: + cmpl $0,_TIMEENABLE(%r10) // is data valid? (test _COMM_PAGE_TIMEENABLE) + jz 4f // no + movq _TIMEBASE(%r10),%r11 // get _COMM_PAGE_TIMEBASE + movq $_COMM_PAGE_32_TO_64(_COMM_PAGE_NANOTIME),%rax + call *%rax // get %rax <- nanotime(), preserving %r9, %r10 and %r11 + movl _TIMESTAMP(%r10),%r8d // get _COMM_PAGE_TIMESTAMP + cmpq _TIMEBASE(%r10),%r11 // has _COMM_PAGE_TIMEBASE changed? + jne 0b // loop until we have consistent data + cmpl $0,_TIMEENABLE(%r10) // is data valid? (test _COMM_PAGE_TIMEENABLE) + jz 4f // no + + movl $ NSEC_PER_SEC,%ecx + subq %r11,%rax // generate nanoseconds since timestamp + movq %rax,%rdx + shrq $32,%rdx // get high half of delta in %edx + divl %ecx // %eax <- seconds since timestamp, %edx <- nanoseconds + addl %eax,%r8d // add seconds elapsed to timestamp seconds + + movl $ NSEC_PER_USEC,%ecx + movl %edx,%eax + xorl %edx,%edx + divl %ecx // divide residual ns by 1000 to get residual us in %eax + + movq %r8,(%r9) // store 64-bit seconds into timeval + movl %eax,8(%r9) // store 32-bit useconds into timeval + xorl %eax,%eax // return 0 for success +3: + popq %rbp + ret +4: // fail + movl $1,%eax + jmp 3b + + COMMPAGE_DESCRIPTOR(gettimeofday_64,_COMM_PAGE_GETTIMEOFDAY,0,0)