DIRECTORY Process USING [GetCurrent], ProcessProps USING [], List USING [AList]; ProcessPropsImpl: CEDAR MONITOR IMPORTS Process EXPORTS ProcessProps = BEGIN OPEN List; AddPropList: PUBLIC PROC [propList: AList, inner: PROC] = TRUSTED { entry: ProcessEntry = GetProcessEntry[]; old: AList = entry.current; IF old # NIL THEN { tail: AList _ NIL; FOR each: AList _ propList, each.rest WHILE each # NIL DO new: AList = LIST[each.first]; IF tail = NIL THEN propList _ new ELSE tail.rest _ new; tail _ new; ENDLOOP; IF tail = NIL THEN propList _ old ELSE tail.rest _ old; }; entry.current _ propList; inner[! UNWIND => entry.current _ old]; entry.current _ old; }; PushPropList: PUBLIC PROC [propList: AList, inner: PROC] = { entry: ProcessEntry = GetProcessEntry[]; old: AList = entry.current; entry.current _ propList; inner[! UNWIND => entry.current _ old]; entry.current _ old; }; GetPropList: PUBLIC PROC RETURNS [propList: AList _ NIL] = TRUSTED { entry: ProcessEntry = GetProcessEntry[]; propList _ entry.current; }; GetProp: PUBLIC PROC [key: REF] RETURNS [prop: REF _ NIL] = TRUSTED { entry: ProcessEntry = GetProcessEntry[]; propList: AList _ entry.current; WHILE propList # NIL DO IF propList.first.key = key THEN RETURN [propList.first.val]; propList _ propList.rest; ENDLOOP; }; GetSpecificPropList: PUBLIC PROC [process: PROCESS] RETURNS [propList: AList _ NIL] = TRUSTED { entry: ProcessEntry = GetProcessEntry[process]; IF entry # NIL THEN propList _ entry.current; }; GetNextPropList: PUBLIC ENTRY PROC [process: PROCESS _ NIL] RETURNS [next: PROCESS _ NIL, propList: AList _ NIL] = { ENABLE UNWIND => NULL; DO best: ProcessEntry _ NIL; FOR i: NAT IN [0..16) DO FOR each: ProcessEntry _ processVector[i], each.next UNTIL each = NIL DO eachProcess: CARDINAL = LOOPHOLE[each.process]; IF each.current = NIL THEN LOOP; IF eachProcess <= LOOPHOLE[process, CARDINAL] THEN LOOP; IF best = NIL OR eachProcess < LOOPHOLE[best.process, CARDINAL] THEN best _ each; ENDLOOP; ENDLOOP; IF best = NIL THEN EXIT; propList _ best.current; IF propList = NIL THEN {races _ races + 1; LOOP}; -- rats! a race occurred next _ best.process; EXIT; ENDLOOP; }; ProcessBits: TYPE = MACHINE DEPENDENT RECORD [ lead: [0..1024), hash: [0..16), spare: [0..4) ]; processVector: ProcessVector _ NEW[ProcessVectorRep _ ALL[NIL]]; entries: NAT _ 0; races: INT _ 0; -- I am curious, Jello ProcessVector: TYPE = REF ProcessVectorRep; ProcessVectorRep: TYPE = ARRAY [0..16) OF ProcessEntry; ProcessEntry: TYPE = REF ProcessEntryRep; ProcessEntryRep: TYPE = RECORD [ next: ProcessEntry _ NIL, process: PROCESS _ NIL, current: AList _ NIL ]; GetProcessEntry: PROC [process: PROCESS _ NIL] RETURNS [entry: ProcessEntry _ NIL] = TRUSTED { bits: ProcessBits; findEntry: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; FOR each: ProcessEntry _ processVector[bits.hash], each.next UNTIL each = NIL DO IF each.process = process THEN {entry _ each; RETURN}; ENDLOOP; }; makeEntry: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; first: ProcessEntry = processVector[bits.hash]; FOR each: ProcessEntry _ first, each.next UNTIL each = NIL DO IF each.process = process THEN {entry _ each; RETURN}; ENDLOOP; entry.next _ first; entry.process _ process; processVector[bits.hash] _ entry; entries _ entries + 1; }; IF process = NIL THEN process _ LOOPHOLE[Process.GetCurrent[]]; bits _ LOOPHOLE[process]; findEntry[]; IF entry # NIL THEN RETURN; entry _ NEW[ProcessEntryRep _ []]; makeEntry[]; }; END. vProcessPropsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Russ Atkinson, February 1, 1985 3:53:26 pm PST ... adds the given properties to the current process for the duration of the call of inner. The old property list for the process will not be altered, but will be found at the end of the propety list during the call to inner. The old property list will be restored after the call has completed. The new propList will be copied if an old property list exists. ... sets the property list for the current process for the duration of the call of inner. The old property list will be restored after the call has completed. The new propList will not be copied. Most applications should use AddPropList to properly inherit properties. ... returns the current property list for the current process. Although there is no prohibition from altering the returned list, users are encouraged to follow the style of adding new properties, rather than changing old associations. ... returns the current property associated with the given key for the current process. This procedure is preferred to GetPropList for most applications. The following two operations are safe, but operations on PROCESS values are, in general, not safe, since processes are reused. These operations should be regarded as instantaneous samples, where the results are likely to change without notice. However, statistics-style applications and may find these operations useful despite these caveats. It is also OK to ask whether a process still has some property if that property will not be reused. ... returns the current property list for the specified process ... returns the next process with a non-NIL propList. Use GetNextPropList[NIL] to start the iteration. [NIL, NIL] will be returned if no more processes exist. The processes are produced in increasing order. There is a very small probability of a race with AddPropList and PushPropList, but it must result in a bounded number of retries. ... returns a non-NIL ProcessEntry for the specified process. We are only locked out for short bursts of time, and NOT while allocating! .. sets entry to be an existing ProcessEntry object (if any), for the process. .. sets entry to be an existing ProcessEntry object (if any), for the process. If there is no such entry, then the fields of entry are filled in, and the entry is placed in the hash table. Κ˜codešœ™Kšœ Οmœ1™Kšœ?™?Kšœ/˜/Kšžœ žœžœ˜-K˜K˜—šŸœžœžœžœ žœžœžœžœžœžœ˜tKšœΤ™ΤKšžœžœžœ˜šž˜Kšœžœ˜šžœžœžœ ž˜šžœ2žœžœž˜HKšœ žœžœ˜/Kšžœžœžœžœ˜ Kš žœžœ žœžœžœ˜8š žœžœžœžœžœ˜?Kšžœ ˜—Kšžœ˜—Kšžœ˜—Kšžœžœžœžœ˜Kšœ˜Kš žœ žœžœžœΟc˜KKšœ˜Kšžœ˜Kšžœ˜—K˜K˜—š œ žœžœž œžœ˜.K˜-K˜K˜—Kšœžœžœžœ˜@Kšœ žœ˜šœžœ ˜'K˜—Kšœžœžœ˜+šœžœžœ žœ˜7K˜—Kšœžœžœ˜)šœžœžœ˜ Kšœžœ˜Kšœ žœžœ˜Kšœž˜K˜K˜—šŸœž˜Kš œ žœžœžœžœžœ˜HKšœžœ_žœ™‰Kšœ˜šœ žœžœžœ˜!KšœN™NKšžœžœžœ˜šžœ:žœžœž˜PKšžœžœžœ˜6Kšžœ˜—K˜—šœ žœžœžœ˜!Kšœ½™½Kšžœžœžœ˜Kšœ/˜/šžœ'žœžœž˜=Kšžœžœžœ˜6Kšžœ˜—K˜K˜Kšœ!˜!Kšœ˜K˜—Kšžœ žœžœ žœ˜?Kšœžœ ˜K˜ Kšžœ žœžœžœ˜Kšœžœ˜"K˜ K˜K˜—Kšžœ˜K˜—…— ”)