Brendan wrote:
The problem isn't one thread running on one CPU that asks for time delays that are too close together. The problem is thousands of threads running in hundreds of processes on tens of CPUs all wanting time delays that happen to result in "not enough time between IRQs", that leads to an IRQ being missed and the new count never being set, and thousands of threads locking up because they're waiting for something that will never happen; followed by a bug report for "unpredictable lock up under load" that's impossible to debug.
I don't support that environment, so no problem. Thousands of threads in hundreds of processes would use-up GDT, so I don't support that.
Brendan wrote:
rdos wrote:
Here is how I read real time (no overhead or IRQs involved):
Code:
get_time PROC far
GetSystemTime
add eax,cs:time_diff
adc edx,cs:time_diff+4
retf32
get_time ENDP
Erm.
Here's the source code for the best kernel that anyone could ever possibly write:
Code:
someUnknownMacro
ret
GetSystemTime is a syscall. It reads elapsed time. You saw it above in the timer code.
Anyhow, here is how it looks like with PIT, channel 0:
Code:
get_system_time Proc
push ds
;
mov ax,SEG data
mov ds,ax
gstSpinLock:
mov ax,ds:time_spinlock
or ax,ax
je gstGet
;
sti
pause
jmp gstSpinLock
gstGet:
cli
inc ax
xchg ax,ds:time_spinlock
or ax,ax
jne gstSpinLock
;
mov al,0
out TIMER_CONTROL,al ; latch count
jmp short $+2
in al,TIMER0 ; read lsb
mov ah,al
jmp short $+2
in al,TIMER0 ; read msb
xchg al,ah
mov dx,ax
xchg ax,ds:clock_tics
sub ax,dx
movzx eax,ax
add ds:system_time,eax
adc ds:system_time+4,0
;
mov eax,ds:system_time
mov edx,ds:system_time+4
;
mov ds:time_spinlock,0
sti
pop ds
retf32
get_system_time Endp
For HPET counter it looks like:
Code:
get_system_time Proc
push ds
push es
push ecx
;
mov ax,SEG data
mov ds,ax
ghtSpinLock:
mov ax,ds:time_spinlock
or ax,ax
je ghtGet
;
sti
pause
jmp ghtSpinLock
ghtGet:
cli
inc ax
xchg ax,ds:time_spinlock
or ax,ax
jne ghtSpinLock
;
mov es,ds:hpet_sel
mov eax,es:hpet_count
mov edx,eax
xchg edx,ds:prev_hpet
sub eax,edx
mul ds:hpet_factor ; HPET rate
add eax,ds:hpet_guard ; 32-bit guard (could be use to increase resolution)
adc edx,0
;
mov ecx,31F5C4EDh ; conversion factor to tics
div ecx
mov ds:hpet_guard,edx
add ds:system_time,eax
adc ds:system_time+4,0
;
mov eax,ds:system_time
mov edx,ds:system_time+4
;
mov ds:time_spinlock,0
sti
;
pop ecx
pop es
pop ds
retf32
get_system_time Endp
But, just maybe, you wanted to know what the GetSystemTime macro is?
Code:
get_system_time_nr = 76
UserGate16 MACRO gate_nr
db 67h
db 66h
db 9Ah
dd gate_nr
dw 1
ENDM
UserGate32 MACRO gate_nr
db 3Eh
db 67h
db 9Ah
dd gate_nr
dw 3
ENDM
UserGate MACRO gate_nr
IF (size $) EQ 0FF02h
UserGate16 gate_nr
ELSE
UserGate32 gate_nr
ENDIF
ENDM
; OUT EDX:EAX System time
GetSystemTime MACRO
UserGate get_system_time_nr
ENDM