__sys_time_slice = 10 ;[ms]
if used TimerCreate
uglobal
__InternalTimerID dd ?
endg
initialize InitLinuxTimers
.action lnx_sigaction
.timer lnx_sigevent
.time lnx_itimerspec
begin
; set the signal handler.
mov eax, sys_sigaction
mov ebx, SIGALRM
lea ecx, [.action]
mov [ecx+lnx_sigaction.sa_handler], __TimerProc
mov [ecx+lnx_sigaction.sa_mask], 0
mov [ecx+lnx_sigaction.sa_flags], 0
xor edx, edx
int $80
stdcall OutputRegister, regEAX, 16
; create the interval timer
mov eax, sys_timer_create
mov ebx, CLOCK_REALTIME
lea ecx, [.timer]
mov [ecx+lnx_sigevent.notify], SIGEV_SIGNAL
mov [ecx+lnx_sigevent.signo], SIGALRM
mov [ecx+lnx_sigevent.value], 0 ; not used but must be set - the function fails without it...
mov edx, __InternalTimerID
int $80
stdcall OutputRegister, regEAX, 16
; start the timer
mov ebx, eax
mov eax, sys_timer_settime
lea edx, [.time]
mov [edx+lnx_itimerspec.it_interval.tv_sec], 0
mov [edx+lnx_itimerspec.it_interval.tv_nsec], __sys_time_slice*1000000
mov [edx+lnx_itimerspec.it_value.tv_sec], 0
mov [edx+lnx_itimerspec.it_value.tv_nsec], __sys_time_slice*1000000
xor esi, esi
int $80
stdcall OutputRegister, regEAX, 16
DebugMsg 'Interval timer set.'
return
endp
finalize FreeLinuxTimers
begin
mov eax, sys_timer_delete
mov ebx, [__InternalTimerID]
int $80
return
endp
end if
; This procedure is called by the system on every time quant.
;
proc __TimerProc, .signal
begin
push ebx esi edi
lea eax, [__ptrFirstTimer]
.loop:
mov eax, [eax+TTimer.next]
test eax, eax
jz .end_timers
test [eax+TTimer.flags], tmfRunning
jz .loop
mov ecx, [eax+TTimer.value]
add ecx, __sys_time_slice
mov [eax+TTimer.value], ecx
cmp ecx, [eax+TTimer.interval]
jl .loop
; call event handler
cmp [eax+TTimer.callback], 0
je .handlerok
push eax
mov ecx, [eax+TTimer.flags]
and ecx, $0f
cmp eax, tmfDoNothing
je .end_event
; run the timer event in separate thread:
stdcall ThreadCreate, [eax+TTimer.callback], eax
.end_event:
pop eax
test [eax+TTimer.flags], tmfSyncDestroy
jz .handlerok
stdcall TimerDestroy, eax
.handlerok:
; jump to loop
mov ecx, [eax+TTimer.interval]
sub [eax+TTimer.value], ecx
jmp .loop
.end_timers:
pop edi esi ebx
xor eax, eax
cret
endp