windows-nt/Source/XPSP1/NT/termsrv/remdsk/rds/as/as16/shm.c
2020-09-26 16:20:57 +08:00

219 lines
4.9 KiB
C

//
// SHM.C
// Shared Memory Manager
//
// Copyright(c) Microsoft 1997-
//
#include <as16.h>
//
// SHM_StartAccess
//
LPVOID SHM_StartAccess(int block)
{
LPBUFFER_CONTROL pControl;
LPVOID pMemBlock;
DebugEntry(SHM_StartAccess);
//
// Test for shared memory present
//
ASSERT(g_asSharedMemory != NULL);
//
// Determine which data block we are handling...
//
switch (block)
{
case SHM_OA_DATA:
pControl = &g_asSharedMemory->displayToCore;
break;
case SHM_OA_FAST:
case SHM_BA_FAST:
case SHM_CM_FAST:
pControl = &g_asSharedMemory->fastPath;
break;
default:
ERROR_OUT(("Unknown type %d", block));
break;
}
//
// Mark the double-buffer as busy.
//
pControl->busyFlag = TRUE;
//
// Set up the current buffer pointer if this is the first access to the
// shared memory.
//
pControl->indexCount++;
if (pControl->indexCount == 1)
{
//
// Set up the 'in use' buffer pointer
//
pControl->currentBuffer = pControl->newBuffer;
//
// Mark the buffer as busy so that the Share Core knows where we
// are.
//
pControl->bufferBusy[pControl->currentBuffer] = 1;
}
//
// Get the pointer to the block to return
//
switch (block)
{
case SHM_OA_DATA:
pMemBlock = g_poaData[pControl->currentBuffer];
break;
case SHM_OA_FAST:
pMemBlock = &(g_asSharedMemory->oaFast[pControl->currentBuffer]);
break;
case SHM_BA_FAST:
pMemBlock = &(g_asSharedMemory->baFast[pControl->currentBuffer]);
break;
case SHM_CM_FAST:
pMemBlock = &(g_asSharedMemory->cmFast[pControl->currentBuffer]);
break;
default:
ERROR_OUT(("Unknown type %d", block));
break;
}
DebugExitDWORD(SHM_StartAccess, (DWORD)pMemBlock);
return(pMemBlock);
}
//
// SHM_StopAccess
//
void SHM_StopAccess(int block)
{
LPBUFFER_CONTROL pControl;
DebugEntry(SHM_StopAccess);
ASSERT(g_asSharedMemory != NULL);
//
// Determine which data block we are handling...
//
switch (block)
{
case SHM_OA_DATA:
pControl = &g_asSharedMemory->displayToCore;
break;
case SHM_OA_FAST:
case SHM_BA_FAST:
case SHM_CM_FAST:
pControl = &g_asSharedMemory->fastPath;
break;
default:
ERROR_OUT(("Unknown type %d", block));
break;
}
//
// Decrement usage count - if we have finally finished with the memory,
// clear the busy flags so that the Share Core knows it won't tread on
// the display driver's toes.
//
pControl->indexCount--;
if (pControl->indexCount == 0)
{
BOOL fPulseLock;
//
// If this is the order heap, and it is more than half full,
// strobe the win16lock so the core has a chance to run and pick up
// the pending orders. This will NOT cause interthread sends to
// get received on this guy.
//
fPulseLock = FALSE;
if (block == SHM_OA_DATA)
{
LPOA_SHARED_DATA pMemBlock = g_poaData[pControl->currentBuffer];
ASSERT(pMemBlock);
if (pMemBlock->totalOrderBytes >=
((g_oaFlow == OAFLOW_FAST ? OA_FAST_HEAP : OA_SLOW_HEAP) / 2))
{
fPulseLock = TRUE;
TRACE_OUT(("Pulsing Win16lock since order heap size %08ld is getting full",
pMemBlock->totalOrderBytes));
}
}
pControl->bufferBusy[pControl->currentBuffer] = 0;
pControl->busyFlag = 0;
if (fPulseLock)
{
_LeaveWin16Lock();
_EnterWin16Lock();
TRACE_OUT(("Done pulsing Win16lock to flush order heap"));
}
}
DebugExitVOID(SHM_StopAccess);
}
#ifdef _DEBUG
//
// SHM_CheckPointer - see shm.h
//
void SHM_CheckPointer(LPVOID ptr)
{
DebugEntry(SHMCheckPointer);
//
// Is it even accessible?
//
ASSERT(!IsBadWritePtr(ptr, 4));
//
// Is it in the proper range? NOTE--our shared memory is not one
// contiguous block. Therefore we need to determine which chunk it
// is in. Since each chunk already has a limit built in, we just
// need to make sure the selector is cool.
//
ASSERT(g_asSharedMemory);
ASSERT(g_poaData[0]);
ASSERT(g_poaData[1]);
if ((SELECTOROF(ptr) != SELECTOROF(g_asSharedMemory)) &&
(SELECTOROF(ptr) != SELECTOROF(g_poaData[0])) &&
(SELECTOROF(ptr) != SELECTOROF(g_poaData[1])))
{
ERROR_OUT(("Pointer not in any shared memory block"));
}
DebugExitVOID(SHM_CheckPointer);
}
#endif // _DEBUG