DIRECTORY Process, RPCLupineExtras, VM, VMInternal; LupineRuntimeExtrasExtrasImpl: MONITOR LOCKS PacketBufferLock IMPORTS Process, VM, VMInternal EXPORTS RPCLupineExtras = { PacketBufferLock: PUBLIC MONITORLOCK; MaxPacketBufferListSize: INT = RPCLupineExtras.MaxPacketBufferListSize; -- Maximum size kept in the cache cacheAllocCount: INT _ 0 ; allocRover: VM.PageNumber _ 0; MaxPacketBufferIntervalInRec: INT = RPCLupineExtras.MaxPacketBufferIntervalInRec; PacketBufferCacheListRec: TYPE = RPCLupineExtras.PacketBufferCacheListRec; PacketBufferCacheList: PUBLIC ARRAY [1..MaxPacketBufferListSize] OF REF PacketBufferCacheListRec _ ALL[NIL]; Alloc: PUBLIC PROC [nWords: CARDINAL] RETURNS [address: LONG POINTER TO WORD] = { nPages: VM.PageCount = MAX[1, VM.PagesForWords[nWords]]; interval: VM.Interval _ VM.nullInterval; IF nPages > MaxPacketBufferListSize THEN { DO interval _ VM.Allocate[count: nPages ! VM.CantAllocate => CONTINUE;]; IF interval.page # 0 THEN EXIT; Process.Pause[1]; ENDLOOP; address _ VM.AddressForPageNumber[interval.page]; RETURN; } ELSE { found: BOOL; [found, address] _ getFromCache[nPages]; IF ~found THEN { IF cacheAllocCount > 10 THEN cacheAllocCount _ 0; IF cacheAllocCount = 0 THEN allocRover _ VMInternal.partitions[normalVM].page; cacheAllocCount _ cacheAllocCount + 1; DO interval _ VM.Allocate[count: nPages, start: allocRover ! VM.CantAllocate => CONTINUE;]; IF interval.page # 0 THEN EXIT; Process.Pause[1]; ENDLOOP; allocRover _ interval.page; address _ VM.AddressForPageNumber[interval.page]; }; }; }; DeAlloc: PUBLIC PROC[address: LONG POINTER TO WORD, nWords: CARDINAL] = { nPages: VM.PageCount = MAX[1, VM.PagesForWords[nWords]]; interval: VM.Interval _ [page: VM.PageNumberForAddress[address], count: nPages]; IF LOOPHOLE[address, INT] # 0 THEN { IF nPages > MaxPacketBufferListSize THEN { VM.Free[interval]; RETURN; } ELSE { putIntoCache[interval]; }; }; }; getFromCache: ENTRY PROC [nPages: VM.PageCount] RETURNS [found: BOOL, address: LONG POINTER TO WORD] = INLINE { putIndex: INT _ PacketBufferCacheList[nPages].putIndex; IF putIndex > 1 THEN { putIndex_ putIndex - 1; address _ VM.AddressForPageNumber[PacketBufferCacheList[nPages].intervalStarts[putIndex]]; PacketBufferCacheList[nPages].putIndex _ putIndex; found _ TRUE; } ELSE { IF PacketBufferCacheList[nPages].prev = NIL THEN found _ FALSE ELSE { PacketBufferCacheList[nPages] _ PacketBufferCacheList[nPages].prev; address _ VM.AddressForPageNumber[ PacketBufferCacheList[nPages].intervalStarts[MaxPacketBufferIntervalInRec]]; PacketBufferCacheList[nPages].putIndex _ MaxPacketBufferIntervalInRec; found _ TRUE; }; }; }; putIntoCache: ENTRY PROC [interval: VM.Interval] = INLINE { count: INT = interval.count; putIndex: INT _ PacketBufferCacheList[count].putIndex; VM.MakeUnchanged[interval]; -- by making the pages "unchanged", we retain the physical memory associated with this interval (decreases page faults); however we also make the page "clean" in that if it is reclaimed it will not be written to the backing file IF putIndex > MaxPacketBufferIntervalInRec THEN { putIndex _ 1; IF PacketBufferCacheList[count].next = NIL THEN { PacketBufferCacheList[count].next _ NEW [PacketBufferCacheListRec _ [prev: PacketBufferCacheList[count]]]; PacketBufferCacheList[count].next.prev _ PacketBufferCacheList[count]; }; PacketBufferCacheList[count] _ PacketBufferCacheList[count].next; PacketBufferCacheList[count].putIndex _ 1; }; PacketBufferCacheList[count].intervalStarts[putIndex] _ interval.page; PacketBufferCacheList[count].putIndex _ putIndex + 1; }; FOR i: INT IN [1..MaxPacketBufferListSize] DO PacketBufferCacheList[i] _ NEW[PacketBufferCacheListRec _ [prev: NIL]]; ENDLOOP; }. ζLupineRuntimeExtrasExtrasImpl.mesa Last Edited by: Bob Hagmann, October 26, 1984 8:31:28 am PDT Note: Make LupineRuntime a Monitor when this is folded in Declarations Exported Procedures Internal Procedures Initialization Κp˜J™"J™šœœ˜JšœC˜CJšœ œc˜oJšœF˜FJšœœ˜ J˜—J˜—J˜—J˜š   œœœ œ œ˜;Jšœœ˜Jšœ œ)˜6Jšœžδ˜€šœ)œ˜1Jšœ ˜ šœ%œœ˜1Jšœ$œC˜jJšœF˜FJ˜—JšœA˜AJšœ*˜*J˜—JšœF˜FJšœ5˜5J˜——™šœœœ˜-Jšœœ#œ˜GJšœ˜——J˜J˜—…—~Τ