Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

505 lines
12 KiB

#include "insignia.h"
#include "host_def.h"
/* INSIGNIA (SUB)MODULE SPECIFICATION
-----------------------------
THIS PROGRAM SOURCE FILE IS SUPPLIED IN CONFIDENCE TO THE
CUSTOMER, THE CONTENTS OR DETAILS OF ITS OPERATION MUST
NOT BE DISCLOSED TO ANY OTHER PARTIES WITHOUT THE EXPRESS
AUTHORISATION FROM THE DIRECTORS OF INSIGNIA SOLUTIONS LTD.
(see /vpc/1.0/Master/src/hdrREADME for help)
DOCUMENT : name and number
RELATED DOCS : include all relevant references
DESIGNER : Phil Bousfield & Jerry Kramskoy
REVISION HISTORY :
First version : 31-Aug-89, simplified Phil's idea, and
produced an interface.
SUBMODULE NAME :
SOURCE FILE NAME : idetect.c
PURPOSE : provide idle detect for SoftPC, so it goes into
hibernation on detecting consecutive time periods
of unsuccessful keyboard polling at a HIGH RATE
with no graphics activity. Idling cannot occur
if polling occurs at too low a rate.
SccsID = @(#)idetect.c 1.11 10/11/93 Copyright Insignia Solutions Ltd.
[1.INTERMODULE INTERFACE SPECIFICATION]
[1.0 INCLUDE FILE NEEDED TO ACCESS THIS INTERFACE FROM OTHER SUBMODULES]
INCLUDE FILE : idetect.gi
[1.1 INTERMODULE EXPORTS]
PROCEDURES() : idle_ctl((int)flag)
idetect((int)event)
idle_set(int)minpoll, (int)minperiod)
DATA : int idle_no_video/disk/comlpt
---------------------------------------------------------------------
[1.2 DATATYPES FOR [1.1] (if not basic C types)]
STRUCTURES/TYPEDEFS/ENUMS:
---------------------------------------------------------------------
[1.3 INTERMODULE IMPORTS]
host_release_timeslice() - block process until interesting
system activity occurs (such as
time tick, I/O etc)
---------------------------------------------------------------------
[1.4 DESCRIPTION OF INTERMODULE INTERFACE]
[1.4.1 IMPORTED OBJECTS]
none
[1.4.2 EXPORTED OBJECTS]
=====================================================================
GLOBAL int idle_no_video
PURPOSE cleared by gvi layer, and video bios ;
set by this interface every time tick.
keeps track of video activity.
GLOBAL int idle_no_disk
PURPOSE cleared by disk bios ;
set by this interface every time tick.
keeps track of video activity.
GLOBAL int idle_no_comlpt
PURPOSE cleared by com/lpt layer,
set by this interface every time tick.
keeps track of com/lpt port activity
=====================================================================
PROCEDURE : void idle_ctl((int)flag)
PURPOSE : enable/disable idle detect.
PARAMETERS
flag : 0 - disable
other - enable.
DESCRIPTION : all idetect() calls ignored if disabled ..
can't idle in this case.
ERROR INDICATIONS : none
=====================================================================
PROCEDURE : void idetect((int)event)
PURPOSE : idle detect interface.
PARAMETERS
event : IDLE_INIT - initialise (clears all
counters)
IDLE_KYBD_POLL _ report an unsucessful keyboard
poll made by application
IDLE_TICK - check activity during last
time tick
IDLE_WAITIO - application has demanded i/p
and none is available. idle.
GLOBALS : idle_no_video/disk/comlpt is read for IDLE_TICK, and
reset.
DESCRIPTION : keeps track of when application appears to be
idling.
ERROR INDICATIONS : none
ERROR RECOVERY : bad 'event' value ignored.
=====================================================================
PROCEDURE : void idle_set((int)minpoll, (int)minperiod)
PURPOSE : configure parameters for idling.
PARAMETERS
minpoll : 0 - don't change
other - specify minimum #.of unsuccessful kybd
polls to be made in 1 time tick
to qualify as an idle time period.
minperiod : 0 - don't change
other - specify minimum #.of consecutive idle
time periods to elapse before going
idle. (e.g; 3 = 3 time ticks)
DESCRIPTION : controls sensitivity for idle detection.
ERROR INDICATIONS : none
ERROR RECOVERY : bad values ignored.
=====================================================================
=====================================================================
[3.INTERMODULE INTERFACE DECLARATIONS]
=====================================================================
[3.1 INTERMODULE IMPORTS] */
/* [3.1.1 #INCLUDES] */
/* [3.1.2 DECLARATIONS] */
#include "xt.h"
#include "timer.h"
#ifdef NTVDM
/* NT configuration flag showing user request for idle support */
IMPORT BOOL IdleDisabledFromPIF;
IMPORT BOOL ExternalWaitRequest;
IMPORT BOOL VDMForWOW;
IMPORT void WaitIfIdle(void);
IMPORT VOID PrioWaitIfIdle(half_word);
#endif /* NTVDM */
/* [3.2 INTERMODULE EXPORTS] */
#include "idetect.h"
/*
5.MODULE INTERNALS : (not visible externally, global internally)]
[5.1 LOCAL DECLARATIONS] */
/* [5.1.1 #DEFINES] */
/* [5.1.2 TYPEDEF, STRUCTURE, ENUM DECLARATIONS] */
/* [5.1.3 PROCEDURE() DECLARATIONS] */
#ifdef NTVDM
void idle_kybd_poll();
void idle_tick();
#else
LOCAL void idle_kybd_poll();
LOCAL void idle_tick();
#endif
/* -------------------------------------------------------------------
[5.2 LOCAL DEFINITIONS]
[5.2.1 INTERNAL DATA DEFINITIONS */
#ifndef NTVDM
int idle_no_video;
int idle_no_comlpt;
int idle_no_disk;
static int i_counter = 0;
static int nCharPollsPerTick = 0;
static int ienabled = 0;
static int minConsecutiveTicks = 12;
static int minFailedPolls = 10;
#else
#include "..\..\..\..\inc\vdm.h"
/* NTVDM
* Some of our static global variables are located in 16 bit memory area
* so we reference as pointers, inititializaed by kb_setup_vectors
*/
word minFailedPolls = 8;
word ienabled = 0;
word ShortIdle=0;
word IdleNoActivity = 0;
word *pICounter;
#define i_counter (*pICounter)
word *pCharPollsPerTick;
#define nCharPollsPerTick (*pCharPollsPerTick)
word *pMinConsecutiveTicks;
#define minConsecutiveTicks (*pMinConsecutiveTicks)
#endif /* NTVDM */
/* [5.2.2 INTERNAL PROCEDURE DEFINITIONS] */
/*
======================================================================
FUNCTION : idle_kybd_poll()
PURPOSE : called from keyboard BIOS as result of
application polling kybd unsuccessfully.
======================================================================
*/
#ifndef NTVDM
#ifdef SMEG
#include "smeg_head.h"
GLOBAL LONG dummy_long_1, dummy_long_2;
GLOBAL BOOL system_has_idled = FALSE;
#endif
LOCAL void my_host_release_timeslice()
{
#ifdef SMEG
/*
* Set marker and waste time (SIGPROF screws up
* host_release_timeslice)
*/
LONG i;
smeg_set(SMEG_IN_IDLE);
system_has_idled = TRUE;
for (i = 0; i < 100000; i++)
dummy_long_1 += dummy_long_2;
smeg_clear(SMEG_IN_IDLE);
#else
host_release_timeslice();
#endif
/* re-count polls in next tick */
nCharPollsPerTick = 0;
}
#endif /* NTVDM */
#ifdef NTVDM
/*
* NT uses a slightly modified algorithum to attempt to catch screen updating
* apps. It also supports Idling calls from VDDs and thus must test which
* thread requests the idle.
*/
void idle_kybd_poll(void)
{
/*
* We don't support wow apps reading the kbd
* if a wow app comes here we must prevent them
* from hogging the CPU, so we will always do
* and idle no matter what.
*/
if (VDMForWOW) {
host_release_timeslice();
return;
}
/* go idle if enough consecutive PC timer interrupts
* have elapsed during which time unsuccessful polling has
* occurred at a large enough rate for each tick.
*/
if (i_counter >= minConsecutiveTicks)
{
host_release_timeslice();
}
/* another unsuccessful poll ! */
nCharPollsPerTick++;
}
#else
LOCAL void idle_kybd_poll()
{
/* go idle if enough consecutive PC timer interrupts
* have elapsed during which time unsuccessful polling has
* occurred at a large enough rate for each tick.
*/
if (i_counter >= minConsecutiveTicks)
{
my_host_release_timeslice();
}
/* another unsuccessful poll ! */
nCharPollsPerTick++;
}
#endif
/*
======================================================================
FUNCTION : idle_tick()
PURPOSE : check polling activity and graphics activity
that's occurred during last tick. If no video
memory writes, and high enough keyboard poll
rate (when no i/p available) increment counter
for triggering going idle. Otherwise reset
counter.
======================================================================
*/
#ifdef NTVDM
void idle_tick(void)
{
/* Has another thread asked us to idle? */
if (ExternalWaitRequest)
{
WaitIfIdle();
ExternalWaitRequest = FALSE;
}
#ifdef MONITOR
if(*pNtVDMState & VDM_IDLEACTIVITY)
{
*pNtVDMState &= ~ VDM_IDLEACTIVITY;
IdleNoActivity = 0;
}
#endif
if (IdleNoActivity)
{
/* no graphics or comms/lpt activity has occurred...
* see whether enough polling of kybd has occurred
* to kick off the idling counter.
*/
if (nCharPollsPerTick >= minFailedPolls) {
i_counter++;
if (ShortIdle) {
PrioWaitIfIdle(94);
}
}
}
else
{
/*
* Check for apps which cheat idle detection by updating
* clocks on the screen causing video activity.
*/
ShortIdle = nCharPollsPerTick >= minFailedPolls && i_counter >= 8;
/* invalidate all accumulated ticks */
i_counter = 0;
IdleNoActivity = 1;
}
nCharPollsPerTick = 0;
}
#else /* NTVDM */
LOCAL void idle_tick()
{
if (idle_no_video && idle_no_disk && idle_no_comlpt)
{
/* no graphics or comms/lpt activity has occurred...
* see whether enough polling of kybd has occurred
* to kick off the idling counter.
*/
if (nCharPollsPerTick >= minFailedPolls)
i_counter++;
}
else
{
i_counter = 0;
}
/* set flags and zero poll counter for next time period
*/
idle_no_video = 1;
idle_no_disk = 1;
idle_no_comlpt = 1;
nCharPollsPerTick = 0;
}
#endif
/*
7.INTERMODULE INTERFACE IMPLEMENTATION :
[7.1 INTERMODULE DATA DEFINITIONS] */
/*
[7.2 INTERMODULE PROCEDURE DEFINITIONS] */
void idetect (event)
int event;
{
#ifndef NTVDM
if (!ienabled)
return;
#endif
switch (event)
{
/* application waiting for input - go idle */
case IDLE_WAITIO:
#ifdef NTVDM
#ifdef MONITOR
*pNtVDMState &= ~VDM_IDLEACTIVITY;
#endif
IdleNoActivity = 1;
PrioWaitIfIdle(10);
break;
#else
my_host_release_timeslice();
#endif
/* fall thru to idle init */
/* initialise flags and counter */
case IDLE_INIT:
nCharPollsPerTick = 0;
i_counter = 0;
#ifdef NTVDM
IdleNoActivity = 1;
#else
idle_no_video = 1;
idle_no_disk = 1;
idle_no_comlpt = 1;
#endif
break;
/* application polling for keyboard input */
case IDLE_KYBD_POLL:
idle_kybd_poll();
break;
case IDLE_TIME_TICK:
idle_tick();
break;
}
}
void idle_set (minpoll, minperiod)
int minpoll, minperiod;
{
if (minperiod > 0)
minConsecutiveTicks = minperiod;
if (minpoll > 0)
minFailedPolls = minpoll;
}
void idle_ctl (flag)
int flag;
{
#ifdef NTVDM
#ifdef PIG
ienabled = 0;
#else
if (IdleDisabledFromPIF) /* configured setting overrides normal control*/
ienabled = 0;
else
ienabled = flag;
#endif /* PIG */
#else
ienabled = flag;
#endif /* NTVDM */
}