mirror of https://github.com/tongzx/nt5src
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.
347 lines
7.2 KiB
347 lines
7.2 KiB
#include "precomp.h"
|
|
|
|
|
|
//
|
|
// OA.CPP
|
|
// Order Accumulation, both cpi32 and display driver sides
|
|
//
|
|
// Copyright(c) Microsoft 1997-
|
|
//
|
|
|
|
#define MLZ_FILE_ZONE ZONE_ORDER
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// FUNCTION: OA_ResetOrderList
|
|
//
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Frees all Orders and Additional Order Data in the Order List.
|
|
// Frees up the Order Heap memory.
|
|
//
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// None.
|
|
//
|
|
//
|
|
// RETURNS:
|
|
//
|
|
// Nothing.
|
|
//
|
|
//
|
|
void ASHost::OA_ResetOrderList(void)
|
|
{
|
|
LPOA_SHARED_DATA lpoaShared;
|
|
|
|
DebugEntry(ASHost::OA_ResetOrderList);
|
|
|
|
TRACE_OUT(("Free order list"));
|
|
|
|
lpoaShared = OA_SHM_START_WRITING;
|
|
|
|
//
|
|
// First free all the orders on the list.
|
|
//
|
|
OAFreeAllOrders(lpoaShared);
|
|
|
|
//
|
|
// Ensure that the list pointers are NULL.
|
|
//
|
|
if ((lpoaShared->orderListHead.next != 0) || (lpoaShared->orderListHead.prev != 0))
|
|
{
|
|
ERROR_OUT(("Non-NULL list pointers (%lx)(%lx)",
|
|
lpoaShared->orderListHead.next,
|
|
lpoaShared->orderListHead.prev));
|
|
|
|
COM_BasedListInit(&lpoaShared->orderListHead);
|
|
}
|
|
|
|
OA_SHM_STOP_WRITING;
|
|
DebugExitVOID(ASHost::OA_ResetOrderList);
|
|
}
|
|
|
|
//
|
|
// OA_SyncOutgoing()
|
|
// Called when a share starts or somebody new joins the share.
|
|
// Resets currently accumulated orders, which were based on old obsolete
|
|
// caps and data.
|
|
//
|
|
void ASHost::OA_SyncOutgoing(void)
|
|
{
|
|
OAFreeAllOrders(g_poaData[1 - g_asSharedMemory->displayToCore.newBuffer]);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// OA_GetFirstListOrder()
|
|
//
|
|
// Returns:
|
|
// Pointer to the first order in the Order List.
|
|
//
|
|
//
|
|
LPINT_ORDER ASHost::OA_GetFirstListOrder(void)
|
|
{
|
|
LPOA_SHARED_DATA lpoaShared;
|
|
LPINT_ORDER retOrder = NULL;
|
|
|
|
DebugEntry(ASHost::OA_GetFirstListOrder);
|
|
|
|
lpoaShared = OA_SHM_START_READING;
|
|
|
|
//
|
|
// Get the first entry from the linked list.
|
|
//
|
|
retOrder = (LPINT_ORDER)COM_BasedListFirst(&lpoaShared->orderListHead,
|
|
FIELD_OFFSET(INT_ORDER, OrderHeader.list));
|
|
|
|
OA_SHM_STOP_READING;
|
|
|
|
TRACE_OUT(("First order = 0x%08x", retOrder));
|
|
|
|
DebugExitVOID(ASHost::OA_GetFirstListOrder);
|
|
return(retOrder);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// OA_RemoveListOrder(..)
|
|
//
|
|
// Removes the specified order from the Order List by marking it as spoilt.
|
|
//
|
|
// Returns:
|
|
// Pointer to the order following the removed order.
|
|
//
|
|
//
|
|
LPINT_ORDER ASHost::OA_RemoveListOrder(LPINT_ORDER pCondemnedOrder)
|
|
{
|
|
LPOA_SHARED_DATA lpoaShared;
|
|
LPINT_ORDER pSaveOrder;
|
|
|
|
DebugEntry(ASHost::OA_RemoveListOrder);
|
|
|
|
TRACE_OUT(("Remove list order 0x%08x", pCondemnedOrder));
|
|
|
|
lpoaShared = OA_SHM_START_WRITING;
|
|
|
|
//
|
|
// Check for a valid order.
|
|
//
|
|
if (pCondemnedOrder->OrderHeader.Common.fOrderFlags & OF_SPOILT)
|
|
{
|
|
TRACE_OUT(("Invalid order"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
//
|
|
// Mark the order as spoilt.
|
|
//
|
|
pCondemnedOrder->OrderHeader.Common.fOrderFlags |= OF_SPOILT;
|
|
|
|
//
|
|
// Update the count of bytes currently in the Order List.
|
|
//
|
|
lpoaShared->totalOrderBytes -= (UINT)MAX_ORDER_SIZE(pCondemnedOrder);
|
|
|
|
//
|
|
// SAve the order so we can remove it from the linked list after having
|
|
// got the next element in the chain.
|
|
//
|
|
pSaveOrder = pCondemnedOrder;
|
|
|
|
pCondemnedOrder = (LPINT_ORDER)COM_BasedListNext(&(lpoaShared->orderListHead),
|
|
pCondemnedOrder, FIELD_OFFSET(INT_ORDER, OrderHeader.list));
|
|
|
|
ASSERT(pCondemnedOrder != pSaveOrder);
|
|
|
|
//
|
|
// Delete the unwanted order from the linked list.
|
|
//
|
|
COM_BasedListRemove(&pSaveOrder->OrderHeader.list);
|
|
|
|
//
|
|
// Check that the list is still consistent with the total number of
|
|
// order bytes.
|
|
//
|
|
if ( (lpoaShared->orderListHead.next != 0) &&
|
|
(lpoaShared->orderListHead.prev != 0) &&
|
|
(lpoaShared->totalOrderBytes == 0) )
|
|
{
|
|
ERROR_OUT(("List head wrong: %ld %ld", lpoaShared->orderListHead.next,
|
|
lpoaShared->orderListHead.prev));
|
|
COM_BasedListInit(&lpoaShared->orderListHead);
|
|
pCondemnedOrder = NULL;
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
OA_SHM_STOP_WRITING;
|
|
|
|
DebugExitPVOID(ASHost::OA_RemoveListOrder, pCondemnedOrder);
|
|
return(pCondemnedOrder);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// OA_GetTotalOrderListBytes(..)
|
|
//
|
|
// Returns:
|
|
// The total number of bytes in the orders currently stored in the Order
|
|
// List.
|
|
//
|
|
//
|
|
UINT ASHost::OA_GetTotalOrderListBytes(void)
|
|
{
|
|
LPOA_SHARED_DATA lpoaShared;
|
|
UINT rc;
|
|
|
|
DebugEntry(ASHost::OA_GetTotalOrderListBytes);
|
|
|
|
lpoaShared = OA_SHM_START_READING;
|
|
|
|
rc = lpoaShared->totalOrderBytes;
|
|
|
|
OA_SHM_STOP_READING;
|
|
|
|
DebugExitDWORD(ASHost::OA_GetTotalOrderListBytes, rc);
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// OA_LocalHostReset()
|
|
//
|
|
void ASHost::OA_LocalHostReset(void)
|
|
{
|
|
OA_FLOW_CONTROL oaFlowEsc;
|
|
|
|
DebugEntry(ASHost::OA_LocalHostReset);
|
|
|
|
m_oaFlow = OAFLOW_FAST;
|
|
oaFlowEsc.oaFlow = m_oaFlow;
|
|
OSI_FunctionRequest(OA_ESC_FLOW_CONTROL, (LPOSI_ESCAPE_HEADER)&oaFlowEsc, sizeof(oaFlowEsc));
|
|
|
|
DebugExitVOID(ASHost::OA_LocalHostReset);
|
|
}
|
|
|
|
|
|
//
|
|
// OA_FlowControl()
|
|
// Sees if we've changed between fast and slow throughput, and adjusts some
|
|
// accumulation variables accordingly.
|
|
//
|
|
void ASHost::OA_FlowControl(UINT newSize)
|
|
{
|
|
OA_FLOW_CONTROL oaFlowEsc;
|
|
|
|
DebugEntry(ASHost::OA_FlowControl);
|
|
|
|
//
|
|
// Work out the new parameters.
|
|
//
|
|
if (newSize < OA_FAST_THRESHOLD)
|
|
{
|
|
//
|
|
// Throughput is slow
|
|
//
|
|
if (m_oaFlow == OAFLOW_FAST)
|
|
{
|
|
m_oaFlow = OAFLOW_SLOW;
|
|
TRACE_OUT(("OA_FlowControl: SLOW; spoil more orders and spoil by SDA"));
|
|
}
|
|
else
|
|
{
|
|
// No change
|
|
DC_QUIT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Throughput is fast
|
|
//
|
|
if (m_oaFlow == OAFLOW_SLOW)
|
|
{
|
|
m_oaFlow = OAFLOW_FAST;
|
|
TRACE_OUT(("OA_FlowControl: FAST; spoil fewer orders and don't spoil by SDA"));
|
|
}
|
|
else
|
|
{
|
|
// No change
|
|
DC_QUIT;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Tell the display driver about the new state
|
|
//
|
|
oaFlowEsc.oaFlow = m_oaFlow;
|
|
OSI_FunctionRequest(OA_ESC_FLOW_CONTROL, (LPOSI_ESCAPE_HEADER)&oaFlowEsc, sizeof(oaFlowEsc));
|
|
|
|
DC_EXIT_POINT:
|
|
DebugExitVOID(ASHost::OA_FlowControl);
|
|
}
|
|
|
|
|
|
//
|
|
// OA_QueryOrderAccum - see oa.h
|
|
//
|
|
UINT ASHost::OA_QueryOrderAccum(void)
|
|
{
|
|
LPOA_FAST_DATA lpoaFast;
|
|
UINT rc = 0;
|
|
|
|
DebugEntry(ASHost::OA_QueryOrderAccum);
|
|
|
|
lpoaFast = OA_FST_START_WRITING;
|
|
|
|
//
|
|
// Get the current value.
|
|
//
|
|
rc = lpoaFast->ordersAccumulated;
|
|
|
|
//
|
|
// Clear the value for next time we swap the buffers.
|
|
//
|
|
lpoaFast->ordersAccumulated = 0;
|
|
|
|
OA_FST_STOP_WRITING;
|
|
DebugExitDWORD(ASHost::OA_QueryOrderAccum, rc);
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// OAFreeAllOrders
|
|
//
|
|
// Free the all the individual orders on the orders list, without
|
|
// discarding the list itself.
|
|
//
|
|
void ASHost::OAFreeAllOrders(LPOA_SHARED_DATA lpoaShared)
|
|
{
|
|
DebugEntry(ASHost::OAFreeAllOrders);
|
|
|
|
//
|
|
// Simply clear the list head.
|
|
//
|
|
COM_BasedListInit(&lpoaShared->orderListHead);
|
|
|
|
lpoaShared->totalHeapOrderBytes = 0;
|
|
lpoaShared->totalOrderBytes = 0;
|
|
lpoaShared->totalAdditionalOrderBytes = 0;
|
|
lpoaShared->nextOrder = 0;
|
|
|
|
DebugExitVOID(ASHost::OAFreeAllOrders);
|
|
}
|
|
|
|
|
|
|