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.
180 lines
8.1 KiB
180 lines
8.1 KiB
/****************************************************************************/
|
|
/* nschapi.cpp */
|
|
/* */
|
|
/* Scheduling component API */
|
|
/* */
|
|
/* Copyright(c) Microsoft Corporation 1996-1999 */
|
|
/****************************************************************************/
|
|
|
|
#include <precomp.h>
|
|
#pragma hdrstop
|
|
|
|
#define TRC_FILE "nschapi"
|
|
#include <as_conf.hpp>
|
|
|
|
#include <nprcount.h>
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: SCH_Init */
|
|
/* */
|
|
/* Purpose: Scheduler initialization function. */
|
|
/****************************************************************************/
|
|
void RDPCALL SHCLASS SCH_Init(void)
|
|
{
|
|
DC_BEGIN_FN("SCH_Init");
|
|
|
|
#define DC_INIT_DATA
|
|
#include <nschdata.c>
|
|
#undef DC_INIT_DATA
|
|
|
|
// ASLEEP mode gets no timer.
|
|
schPeriods[SCH_MODE_ASLEEP] = SCH_NO_TIMER;
|
|
|
|
// Get scheduling periods that were saved in WD_Open.
|
|
schPeriods[SCH_MODE_NORMAL] = m_pTSWd->outBufDelay;
|
|
|
|
// If compression is enabled (ie it's a slow link) then crank up the
|
|
// turbo period to improve responsiveness.
|
|
if (m_pTSWd->bCompress) {
|
|
TRC_ALT((TB, "Slow link"));
|
|
schPeriods[SCH_MODE_TURBO] = SCH_TURBO_PERIOD_SLOW_LINK_DELAY;
|
|
schTurboModeDuration = SCH_TURBO_MODE_SLOW_LINK_DURATION;
|
|
|
|
m_pShm->sch.MPPCCompressionEst = SCH_MPPC_INIT_EST;
|
|
}
|
|
else {
|
|
TRC_ALT((TB, "Fast link"));
|
|
schPeriods[SCH_MODE_TURBO] = m_pTSWd->interactiveDelay;
|
|
schTurboModeDuration = SCH_TURBO_MODE_FAST_LINK_DURATION;
|
|
|
|
// To avoid branching, we set the compression ratio for non-compressed
|
|
// to the same size as the divisor to create a 1:1 calculation.
|
|
m_pShm->sch.MPPCCompressionEst = SCH_UNCOMP_BYTES;
|
|
}
|
|
|
|
TRC_ALT((TB, "Normal period=%u ms, turbo period=%u ms, turbo duration=%u ms",
|
|
schPeriods[SCH_MODE_NORMAL], schPeriods[SCH_MODE_TURBO],
|
|
schTurboModeDuration / 10000));
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
// Updates the SHM
|
|
/****************************************************************************/
|
|
void RDPCALL SHCLASS SCH_UpdateShm(void)
|
|
{
|
|
DC_BEGIN_FN("SCH_UpdateShm");
|
|
|
|
m_pShm->sch.schSlowLink = m_pTSWd->bCompress;
|
|
|
|
// Set up packing sizes based on link speed.
|
|
if (m_pTSWd->bCompress) {
|
|
m_pShm->sch.SmallPackingSize = SMALL_SLOWLINK_PAYLOAD_SIZE;
|
|
m_pShm->sch.LargePackingSize = LARGE_SLOWLINK_PAYLOAD_SIZE;
|
|
}
|
|
else {
|
|
m_pShm->sch.SmallPackingSize = SMALL_LAN_PAYLOAD_SIZE;
|
|
m_pShm->sch.LargePackingSize = LARGE_LAN_PAYLOAD_SIZE;
|
|
}
|
|
|
|
SET_INCOUNTER(IN_SCH_SMALL_PAYLOAD, m_pShm->sch.SmallPackingSize);
|
|
SET_INCOUNTER(IN_SCH_LARGE_PAYLOAD, m_pShm->sch.LargePackingSize);
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: SCH_ContinueScheduling */
|
|
/* */
|
|
/* Purpose: Called by components when they want periodic scheduling to */
|
|
/* continue. They are guaranteed to get at least one more */
|
|
/* periodic callback following a call to this function. */
|
|
/* If they want further callbacks then they must call this */
|
|
/* function again during their periodic processing. */
|
|
/* */
|
|
/* Params: schedulingMode - either SCH_MODE_NORMAL or SCH_MODE_TURBO */
|
|
/* */
|
|
/* Operation: - */
|
|
/* SCH_MODE_NORMAL triggers periodic processing at 200ms */
|
|
/* intervals (5 times a second) */
|
|
/* */
|
|
/* SCH_MODE_TURBO triggers periodic processing at 100ms */
|
|
/* intervals (10 times a second) */
|
|
/* */
|
|
/* The scheduler automatically drops from SCH_MODE_TURBO back */
|
|
/* to SCH_MODE_NORMAL after 1 second of turbo mode processing. */
|
|
/* */
|
|
/* SCH_MODE_TURBO overrides SCH_MODE_NORMAL, so if calls to */
|
|
/* this function are made with SCH_MODE_NORMAL when the */
|
|
/* scheduler is in TURBO mode, TURBO mode continues. */
|
|
/* */
|
|
/* If this function is not called during one pass through */
|
|
/* DCS_TimeToDoStuff then the scheduler enters */
|
|
/* SLEEP mode - and will not generate any more periodic */
|
|
/* callbacks until it is woken by another call to */
|
|
/* this function, or until the output accumulation code */
|
|
/* IOCtls into the WD again. */
|
|
/****************************************************************************/
|
|
void RDPCALL SHCLASS SCH_ContinueScheduling(unsigned schedulingMode)
|
|
{
|
|
BOOL restart = FALSE;
|
|
|
|
DC_BEGIN_FN("SCH_ContinueScheduling");
|
|
|
|
TRC_ASSERT( ((schedulingMode == SCH_MODE_NORMAL) ||
|
|
(schedulingMode == SCH_MODE_TURBO)),
|
|
(TB, "Invalid scheduling state: %u", schedulingMode) );
|
|
|
|
if (schedulingMode == SCH_MODE_TURBO)
|
|
{
|
|
// TURBO mode is often turned off because of packets that need to
|
|
// be sent out IMMEDIATELY. This makes it very difficult to actually
|
|
// ask the question, "has input come accross in the last n milliseconds.
|
|
// This is what we use schInputKickMode for!
|
|
schInputKickMode = TRUE;
|
|
}
|
|
|
|
TRC_DBG((TB, "Continue scheduling (%s) -> (%s), InTTDS(%d)",
|
|
schCurrentMode == SCH_MODE_TURBO ? "Turbo" :
|
|
schCurrentMode == SCH_MODE_NORMAL ? "Normal" : "Asleep",
|
|
schedulingMode == SCH_MODE_TURBO ? "Turbo" :
|
|
schedulingMode == SCH_MODE_NORMAL ? "Normal" : "Asleep",
|
|
schInTTDS));
|
|
|
|
if (schCurrentMode == SCH_MODE_TURBO) {
|
|
// If we're in TURBO mode, then the only interesting event is a
|
|
// requirement to stay there longer than currently planned.
|
|
if (schedulingMode == SCH_MODE_TURBO) {
|
|
COM_GETTICKCOUNT(schLastTurboModeSwitch);
|
|
TRC_DBG((TB, "New Turbo switch time %lu",
|
|
schLastTurboModeSwitch));
|
|
}
|
|
}
|
|
else {
|
|
if (schedulingMode == SCH_MODE_TURBO) {
|
|
COM_GETTICKCOUNT(schLastTurboModeSwitch);
|
|
restart = TRUE;
|
|
TRC_DBG((TB, "New Turbo switch time %lu",
|
|
schLastTurboModeSwitch));
|
|
}
|
|
|
|
/********************************************************************/
|
|
/* We're waking up. If we're not in the middle of a TTDS pass, */
|
|
/* then start the new timer straight away. */
|
|
/********************************************************************/
|
|
if (!schInTTDS && ((schCurrentMode == SCH_MODE_ASLEEP) || restart)) {
|
|
TRC_DBG((TB, "Starting a timer for %lu ms",
|
|
schPeriods[schedulingMode]));
|
|
WDW_StartRITTimer(m_pTSWd, schPeriods[schedulingMode]);
|
|
}
|
|
|
|
schCurrentMode = schedulingMode;
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|