Split timer code into separate source file.
Stop using SIGALRM for timers.
This commit is contained in:
parent
03e0a49649
commit
b2844d2c3a
|
@ -48,6 +48,7 @@ C_SRCS = \
|
|||
module.c \
|
||||
relay.c \
|
||||
soundblaster.c \
|
||||
timer.c \
|
||||
vga.c \
|
||||
vxd.c \
|
||||
xms.c
|
||||
|
|
|
@ -374,6 +374,8 @@ DWORD WINAPI DOSVM_Loop( HANDLE hThread )
|
|||
SetEvent( (HANDLE)msg.wParam );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,13 +425,6 @@ static WINE_EXCEPTION_FILTER(exception_handler)
|
|||
IF_SET(context);
|
||||
EnterCriticalSection(&qcrit);
|
||||
sig_sent++;
|
||||
while (NtCurrentTeb()->alarms) {
|
||||
DOSVM_QueueEvent(0,DOS_PRIORITY_REALTIME,NULL,NULL);
|
||||
/* hmm, instead of relying on this signal counter, we should
|
||||
* probably check how many ticks have *really* passed, probably using
|
||||
* QueryPerformanceCounter() or something like that */
|
||||
InterlockedDecrement(&(NtCurrentTeb()->alarms));
|
||||
}
|
||||
TRACE_(int)("context=%p\n", context);
|
||||
TRACE_(int)("cs:ip=%04lx:%04lx, ss:sp=%04lx:%04lx\n", context->SegCs, context->Eip, context->SegSs, context->Esp);
|
||||
if (!ISV86(context)) {
|
||||
|
@ -493,40 +488,6 @@ void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val)
|
|||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetTimer (WINEDOS.@)
|
||||
*/
|
||||
void WINAPI DOSVM_SetTimer( UINT ticks )
|
||||
{
|
||||
struct itimerval tim;
|
||||
|
||||
if (dosvm_pid) {
|
||||
/* the PC clocks ticks at 1193180 Hz */
|
||||
tim.it_interval.tv_sec=0;
|
||||
tim.it_interval.tv_usec=MulDiv(ticks,1000000,1193180);
|
||||
/* sanity check */
|
||||
if (!tim.it_interval.tv_usec) tim.it_interval.tv_usec=1;
|
||||
/* first tick value */
|
||||
tim.it_value = tim.it_interval;
|
||||
TRACE_(int)("setting timer tick delay to %ld us\n", tim.it_interval.tv_usec);
|
||||
setitimer(ITIMER_REAL, &tim, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetTimer (WINEDOS.@)
|
||||
*/
|
||||
UINT WINAPI DOSVM_GetTimer( void )
|
||||
{
|
||||
struct itimerval tim;
|
||||
|
||||
if (dosvm_pid) {
|
||||
getitimer(ITIMER_REAL, &tim);
|
||||
return MulDiv(tim.it_value.tv_usec,1193180,1000000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !MZ_SUPPORTED */
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -548,16 +509,6 @@ void WINAPI DOSVM_Wait( CONTEXT86 *waitctx ) { }
|
|||
*/
|
||||
void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val) {}
|
||||
|
||||
/***********************************************************************
|
||||
* SetTimer (WINEDOS.@)
|
||||
*/
|
||||
void WINAPI DOSVM_SetTimer( UINT ticks ) {}
|
||||
|
||||
/***********************************************************************
|
||||
* GetTimer (WINEDOS.@)
|
||||
*/
|
||||
UINT WINAPI DOSVM_GetTimer( void ) { return 0; }
|
||||
|
||||
/***********************************************************************
|
||||
* QueueEvent (WINEDOS.@)
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 8253/8254 Programmable Interval Timer (PIT) emulation
|
||||
*
|
||||
* Copyright 2003 Jukka Heinonen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dosexe.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(int);
|
||||
|
||||
/*
|
||||
* FIXME: Move timer ioport handling here and remove
|
||||
* Dosvm.GetTimer/Dosvm.SetTimer.
|
||||
* FIXME: Use QueryPerformanceCounter for
|
||||
* more precise GetTimer implementation.
|
||||
* FIXME: Use QueryPerformanceCounter (or GetTimer implementation)
|
||||
* in timer tick routine to compensate for lost ticks.
|
||||
* This should also make it possible to
|
||||
* emulate really fast timers.
|
||||
* FIXME: Support special timer modes in addition to periodic mode.
|
||||
* FIXME: Make sure that there are only limited number
|
||||
* of pending timer IRQ events queued. This makes sure that
|
||||
* timer handling does not eat all available memory even
|
||||
* if IRQ handling stops for some reason (suspended process?).
|
||||
* This is easy to do by using DOSRELAY parameter.
|
||||
* FIXME: Use timeSetEvent, NtSetEvent or timer thread for more precise
|
||||
* timing.
|
||||
* FIXME: Move Win16 timer emulation code here.
|
||||
*/
|
||||
|
||||
/* The PC clocks ticks at 1193180 Hz. */
|
||||
#define TIMER_FREQ 1193180
|
||||
|
||||
/* Unique system timer identifier. */
|
||||
static UINT_PTR TIMER_id = 0;
|
||||
|
||||
/* Time when timer IRQ was last queued. */
|
||||
static DWORD TIMER_stamp = 0;
|
||||
|
||||
/* Timer ticks between timer IRQs. */
|
||||
static UINT TIMER_ticks = 0;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TIMER_TimerProc
|
||||
*/
|
||||
static void CALLBACK TIMER_TimerProc( HWND hwnd,
|
||||
UINT uMsg,
|
||||
UINT_PTR idEvent,
|
||||
DWORD dwTime )
|
||||
{
|
||||
TIMER_stamp = dwTime;
|
||||
DOSVM_QueueEvent( 0, DOS_PRIORITY_REALTIME, NULL, NULL );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TIMER_DoSetTimer
|
||||
*/
|
||||
static void WINAPI TIMER_DoSetTimer( ULONG_PTR arg )
|
||||
{
|
||||
INT millis = MulDiv( arg, 1000, TIMER_FREQ );
|
||||
|
||||
/* sanity check - too fast timer */
|
||||
if (millis < 1)
|
||||
millis = 1;
|
||||
|
||||
TRACE_(int)( "setting timer tick delay to %d ms\n", millis );
|
||||
|
||||
if (TIMER_id)
|
||||
KillTimer( NULL, TIMER_id );
|
||||
|
||||
TIMER_id = SetTimer( NULL, 0, millis, TIMER_TimerProc );
|
||||
TIMER_stamp = GetTickCount();
|
||||
TIMER_ticks = arg;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTimer (WINEDOS.@)
|
||||
*/
|
||||
UINT WINAPI DOSVM_GetTimer( void )
|
||||
{
|
||||
if (!DOSVM_IsWin16())
|
||||
{
|
||||
DWORD millis = GetTickCount() - TIMER_stamp;
|
||||
INT ticks = MulDiv( millis, TIMER_FREQ, 1000 );
|
||||
|
||||
/* sanity check - tick wrap or suspended process or update race */
|
||||
if (ticks < 0 || ticks >= TIMER_ticks)
|
||||
ticks = 0;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetTimer (WINEDOS.@)
|
||||
*/
|
||||
void WINAPI DOSVM_SetTimer( UINT ticks )
|
||||
{
|
||||
if (!DOSVM_IsWin16())
|
||||
MZ_RunInThread( TIMER_DoSetTimer, ticks );
|
||||
}
|
Loading…
Reference in New Issue