<<>> <> <> <> <> <<>> <<"Template module" to handle free-lists of client data blocks. >> <<>> <> <> <<>> <> <<>> <> <<>> <> <> <> <<};>> <<>> <> <> <<};>> <<>> <> <<>> UnsafeFreeList: CEDAR DEFINITIONS LOCKS ct USING ct: Context ~ BEGIN Context: TYPE = REF ContextRep; <> <> << >> ContextRep: PRIVATE TYPE = MONITORED RECORD [ lim: INT ¬ 0, --counter for how many more elements can be include in list. first: POINTER TO Block ¬ NIL, --front of list; where elements are removed last: POINTER TO Block ¬ NIL --tail of list; where new free elements are queued ]; <> Block: PRIVATE TYPE = RECORD [next: POINTER TO Block <>]; NewContext: PUBLIC PROC [capacity: INT ¬ 20] RETURNS [Context] = INLINE { <> RETURN [NEW[ContextRep ¬ [lim: capacity]]]; }; <<>> Free: PUBLIC UNSAFE PROC [ct: Context, ptr: POINTER] = TRUSTED INLINE { <> IF ptr#NIL AND ct.lim>0 THEN EntryFree[ct, LOOPHOLE[ptr]] }; EntryFree: PRIVATE ENTRY PROC [ct: Context, d: POINTER TO Block] = TRUSTED INLINE { ct.lim ¬ ct.lim-1; d.next ¬ NIL; IF ct.last#NIL THEN ct.last.next ¬ d ELSE ct.first ¬ d; ct.last ¬ d }; Get: PUBLIC PROC [ct: Context] RETURNS [POINTER ¬ NIL] = TRUSTED INLINE { <> <> IF ct.first#NIL THEN RETURN [LOOPHOLE[EntryGet[ct]]]; }; EntryGet: PRIVATE ENTRY PROC [ct: Context] RETURNS [d: POINTER TO Block] = TRUSTED INLINE { IF (d ¬ ct.first)#NIL THEN { ct.lim ¬ ct.lim+1; ct.first ¬ d.next; IF ct.first=NIL THEN ct.last ¬ NIL; d.next ¬ NIL; }; }; FreeCapacity: PUBLIC PROC [ct: Context] RETURNS [INT] = INLINE { <> <> RETURN [ct.lim]; }; END.