supermario/base/SuperMarioProj.1994-02-09/OS/PPC/PPCUtilities.c
2019-06-29 23:17:50 +08:00

282 lines
8.3 KiB
C

/*
File: PPCUtilities.c
Contains: General routines for supporting PPC.
Written by: Eric M. Trehus
Copyright: © 1990-1993 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<SM5> 3/9/93 PN Remove ReQueueInformPB,Insert, Push,InitQueue, TraverseQueue
which is no longer used
<10> 4/14/92 BBM <JSM>: Remove unfinished PPC code that is under the contitional
“TheFutute”, and remove the conditional “CubeE” since that is
reality. Remove conditionals, since all they do is confuse.
<9> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
<8> 9/29/91 DTY Conditionalize out <6> and <7> for CubeE.
<7> 6/12/91 EMT Remove code that references the number of pending messages
<6> 6/4/91 EMT Roll in StoreAndForward Revisions
<5> 11/6/90 EMT use STATIC in place of static for link maps
<4> 10/18/90 EMT Remove some un-referenced/ifdefed out procedures.
<3> 10/11/90 EMT remove #define DEBUG
<2> 9/5/90 EMT Make this file C3.0 Friendly
*/
#include "PPCCommon.h"
#include <AppleTalk.h>
#include <ADSP.h>
#include <String.h>
#include <stdarg.h>
/*---------------------------------------------------------------------------------------------------
Prototypes of functions used only in this file.
---------------------------------------------------------------------------------------------------*/
STATIC void AddNew(QUEUE *theQueue,int number,int len);
STATIC void RemOld(QUEUE *theQueue,int number);
/*---------------------------------------------------------------------------------------------------
Pointer Compare is a utility SearchFunc for use with many QUEUE routines.
---------------------------------------------------------------------------------------------------*/
Boolean PointerCompare(void *ptr,unsigned long Value)
{
return((unsigned long)ptr == Value);
}
#ifdef DEBUG
Boolean InQueue(void *PB,QUEUE *Queue)
{
return (PB == SearchQueue(Queue,(unsigned long)PB,PointerCompare,1));
}
#endif
/*---------------------------------------------------------------------------------------------------
EnQueue places Element at the end of the Queue.
---------------------------------------------------------------------------------------------------*/
void EnQueue(void *Element,QUEUE *Queue)
ELEMENT *Element;
{
short p;
#ifdef DEBUG
if(!Element)
DebugStr("\pElement is NULL");
if(!Queue)
DebugStr("\pQueue is NULL");
if(InQueue(Element,Queue))
DebugStr("\pElement already in Queue");
#endif
p = spl(kNoInterrupts);
Element->Next = NULL; /* Make our list NULL ended */
if(Queue->qSize)
{
Queue->Tail->Next = Element; /* Link in the new Element */
Queue->Tail = Element; /* Update Tail */
}
else /* The Queue is empty */
{
Queue->Head = Element; /* Head and Tail is the same Element */
Queue->Tail = Element;
}
Queue->qSize++; /* Show that the Queue has grown */
spl(p);
}
/*---------------------------------------------------------------------------------------------------
ServeQueue removes an element from the from of the Queue, otherwise returns NULL.
---------------------------------------------------------------------------------------------------*/
void *ServeQueue(QUEUE *Queue)
{
ELEMENT *ptr;
short p;
#ifdef DEBUG
if(!Queue)
DebugStr("\pQueue is NULL");
#endif
p = spl(kNoInterrupts);
if(Queue->qSize)
{
ptr = Queue->Head; /* FIFO */
Queue->Head = ptr->Next; /* Update Head to point to Next Element */
Queue->qSize--; /* show that the Queue has shrunken */
}
else
ptr = NULL; /* No Elements in the Queue */
spl(p);
return(ptr);
}
/*---------------------------------------------------------------------------------------------------
SearchQueue looks for Value using SearchFunc to compare Value with each element
in the queue. When the Nth element is found a pointer to that queue element is
returned.
---------------------------------------------------------------------------------------------------*/
void *SearchQueue(QUEUE *Queue,unsigned long Value,SearchFuncPtr SearchFunc,int Nth)
{
ELEMENT *ptr;
int i;
unsigned short p;
#ifdef DEBUG
if(!Queue)
DebugStr("\pQueue is NULL");
#endif
p = spl(kNoInterrupts);
ptr = Queue->Head;
for(i=0;i<Queue->qSize;i++)
{
if((*SearchFunc)(ptr,Value))
{
--Nth;
if(!Nth)
goto Done;
}
ptr = ptr->Next;
}
ptr = NULL;
Done:
spl(p);
return(ptr);
}
/*---------------------------------------------------------------------------------------------------
DeleteFromQueue removes an Element from the Queue
---------------------------------------------------------------------------------------------------*/
void *DeleteFromQueue(QUEUE *Queue,unsigned long Value,SearchFuncPtr SearchFunc)
{
ELEMENT *ptr;
int i;
ELEMENT *RemElm;
short p;
#ifdef DEBUG
if(!Queue)
DebugStr("\pQueue is NULL");
#endif
p = spl(kNoInterrupts);
RemElm = NULL;
ptr = (ELEMENT *)&Queue->Head; /* The Head may change */
for(i=0;i<Queue->qSize;i++)
{
if((*SearchFunc)(ptr->Next,Value))
{
RemElm = ptr->Next;
ptr->Next = ptr->Next->Next;
if(RemElm == Queue->Tail)
Queue->Tail = ptr;
Queue->qSize--;
break;
}
ptr = ptr->Next;
}
spl(p);
return(RemElm); /* Client must free the memory itself */
}
/*---------------------------------------------------------------------------------------------------
DeleteMultiple removes multiple Element from the Queue.
NOTE: DeleteMultiple removes each element from the Queue before calling DoProc.
If DoProc returns false, DeleteMultiple places the element back into the Queue,
otherwise it assumes that the element is no longer needed. This algorithm may
create little windows of oppertunity for bugs to appear since elements that are
not to be deleted are temporarily out of their queue.
---------------------------------------------------------------------------------------------------*/
void DeleteMultiple(QUEUE *Queue,unsigned long Value,SearchFuncPtr DoProc)
{
int i;
ELEMENT *theElement;
#ifdef DEBUG
if(!Queue)
DebugStr("\pQueue is NULL");
#endif
for(i=Queue->qSize;i;i--)
{
if(theElement = ServeQueue(Queue))
{
if(!(*DoProc)(theElement,Value))
EnQueue(theElement,Queue);
}
}
}
void *NewMem(long len)
{
return NewPtrSysClear(len);
}
void DisposeMem(void *Mem)
{
DisposPtr(Mem);
}
STATIC void AddNew(QUEUE *theQueue,int number,int len)
{
void *Mem;
while(number--)
{
if(Mem = NewMem(len))
EnQueue(Mem,theQueue);
else
break;
}
}
STATIC void RemOld(QUEUE *theQueue,int number)
{
void *Mem;
while(number--)
{
if(Mem = ServeQueue(theQueue))
DisposeMem(Mem);
else
break;
}
}
void Replenish(PPCGlobalParamsPtr ppcglobPtr)
{
if(ppcglobPtr->freePortQueue.qSize < ppcglobPtr->configData.freePortMin)
AddNew(&ppcglobPtr->freePortQueue,ppcglobPtr->configData.freePortMin - ppcglobPtr->freePortQueue.qSize,sizeof(PPCPortEntry));
if(ppcglobPtr->freeLocationQueue.qSize < ppcglobPtr->configData.freePortMin)
AddNew(&ppcglobPtr->freeLocationQueue,ppcglobPtr->configData.freePortMin - ppcglobPtr->freeLocationQueue.qSize,sizeof(PortLocationTable));
if(ppcglobPtr->freeLocSessQueue.qSize < ppcglobPtr->configData.freeLocSessMin)
AddNew(&ppcglobPtr->freeLocSessQueue,ppcglobPtr->configData.freeLocSessMin - ppcglobPtr->freeLocSessQueue.qSize,sizeof(LocalIPCParams));
if(ppcglobPtr->freeRemSessQueue.qSize < ppcglobPtr->configData.freeRemSessMin)
AddNew(&ppcglobPtr->freeRemSessQueue,ppcglobPtr->configData.freeRemSessMin - ppcglobPtr->freeRemSessQueue.qSize,sizeof(NetIPCParams));
}
void Excess(PPCGlobalParamsPtr ppcglobPtr)
{
if(ppcglobPtr->freePortQueue.qSize > ppcglobPtr->configData.freePortMax)
RemOld(&ppcglobPtr->freePortQueue,ppcglobPtr->freePortQueue.qSize - ppcglobPtr->configData.freePortMax);
if(ppcglobPtr->freeLocationQueue.qSize > ppcglobPtr->configData.freePortMax)
RemOld(&ppcglobPtr->freeLocationQueue,ppcglobPtr->freeLocationQueue.qSize - ppcglobPtr->configData.freePortMax);
if(ppcglobPtr->freeLocSessQueue.qSize > ppcglobPtr->configData.freeLocSessMax)
RemOld(&ppcglobPtr->freeLocSessQueue,ppcglobPtr->freeLocSessQueue.qSize - ppcglobPtr->configData.freeLocSessMax);
if(ppcglobPtr->freeRemSessQueue.qSize > ppcglobPtr->configData.freeRemSessMax)
RemOld(&ppcglobPtr->freeRemSessQueue,ppcglobPtr->freeRemSessQueue.qSize - ppcglobPtr->configData.freeRemSessMax);
}