DIRECTORY YggEnvironment, YggInternal, BasicTime, YggLock; YggLockInternal: CEDAR DEFINITIONS = BEGIN LockID: TYPE = YggLock.LockID; LockMode: TYPE = YggLock.LockMode; Lock: TYPE = REF LockRep; Header: TYPE = REF LockRep.header; Request: TYPE = REF LockRep.request; GrantedRequest: TYPE = REF LockRep.request.granted; WaitingRequest: TYPE = REF LockRep.request.waiting; LockTransHeader: TYPE = REF LockRep.request.transHeader; LockType: TYPE = {header, request}; RequestLockType: TYPE = {granted, waiting, transHeader}; LockRep: TYPE = RECORD [ requestList: Lock _ NIL, body: SELECT type: LockType FROM header => [ lockID: LockID _ YggLock.nullLockID, next: Header _ NIL -- link field for hash table package ], request => [ trans: YggInternal.TransHandle, transList: Request, lockID: LockID _ YggLock.nullLockID, mode: LockMode, rest: SELECT type: RequestLockType FROM granted => [ count: NAT ], waiting => [ somethingChanged: CONDITION, giveUp: BOOL _ FALSE, whyGivingUp: WhyGivingUp _ TRASH, -- meaningful only if giveUp isConversion: BOOL _ FALSE, startTime: BasicTime.GMT ], transHeader => [ -- requestList = NIL nLocks: INT ], ENDCASE ], ENDCASE ]; WhyGivingUp: TYPE = { abort, timeout }; GetInfo: PROC [ generalInfoProc: GeneralInfoProc _ NIL, lockEnumProc: LockEnumProc _ NIL, waitingRequestEnumProc: WaitingRequestEnumProc _ NIL, waitingRequestEnumProc2: WaitingRequestEnumProc _ NIL]; GeneralInfoProc: TYPE = PROC [nLocks, nRequests, nSetCalls, nSetCallsWaited: INT]; LockEnumProc: TYPE = PROC [h: Header] RETURNS [stop: BOOL]; WaitingRequestEnumProc: TYPE = PROC [wr: WaitingRequest] RETURNS [stop: BOOL]; TimeoutWaitingRequest: PROC [wr: WaitingRequest]; LockIDFromRH: PROC [r: Request] RETURNS [LockID] = INLINE { hCopy: Lock; h: Lock _ r.requestList; DO IF h = r THEN ERROR; hCopy _ h; WITH hCopy^ SELECT FROM hh: LockRep.header => RETURN [hh.lockID]; rr: LockRep.request => h _ hCopy.requestList; ENDCASE => ERROR; ENDLOOP; }; END. CHANGE LOG. ŠYggLockInternal.mesa Copyright Σ 1985, 1988 by Xerox Corporation. All rights reserved. Last edited by MBrown on January 30, 1984 12:19:25 pm PST Kupfer, February 14, 1985 4:49:41 pm PST Bob Hagmann May 3, 1988 10:05:42 am PDT Carl Hauser, March 16, 1987 1:43:06 pm PST circular list consisting of one LockRep.header, one or more LockRep.requests with granted or waiting variant. circular list consisting of one LockRep.request.transHeader, zero or more LockRep.request.granted, all with same value of trans. all waiting requests are linked into a single list, through this field. Enters YggLock monitor. If generalInfoProc # NIL, calls it with current values of its parameters. On return, if lockEnumProc # NIL, enumerates the locks calling lockEnumProc until it returns quit: TRUE or all locks have been enumerated. Then if waitingRequestEnumProc # NIL, enumerates the waiting requests in the same fashion. Then if waitingRequestEnumProc2 # NIL, enumerates the waiting requests again, in the same fashion. Finally returns, releasing the YggLock monitor. None of the proc parameters should not call into monitors that may be held while calling into the YggLock monitor (including the YggLock monitor itself). Cause the YggLock.Set call to raise YggLock.Failed[timeout]. Chases down pointers until it finds the header (which holds the LockID that "wr" is waiting for). You should have the YggLock monitor lock before calling this routine. Edited on February 14, 1985 2:54:19 pm PST, by Kupfer Added LockIDFromWRH. This is INLINE so that it can be defined in LockInternal, where anybody inside Alpine can use it (assuming they have the monitor lock for Lock). Κh˜Icodešœ™KšœB™Bšœ™Kšœ*™*J™(K™'K™*—K˜šΟk ˜ K˜K˜ K˜ K˜K˜—šœœ˜*Kšœœ˜Kšœ œ˜"K˜Kšœœœ ˜Kšœœœ˜"Kšœ œœ˜$Kšœœœ˜3Kšœœœ˜3Kšœœœ˜8K˜Kšœ œ˜#Kšœœ#˜8K˜šœ œœ˜šœœ˜Kšœm™m—šœœ˜ ˜ Kšœ$˜$KšœœΟc$˜7K˜—˜ K˜˜KšœΘ™Θ—Kšœ$˜$K˜šœœ˜'˜ Kšœ˜ K˜—˜ Kšœ œ˜Kšœœœ˜Kšœœž˜>Kšœœœ˜Kšœ˜K˜—šœž˜%Kšœ˜ K˜—Kš˜—K˜—Kš˜—K˜K˜—Kšœ œ˜'K˜šΟnœœ˜Kšœ#œ˜'Kšœœ˜!Kšœ1œ˜5Kšœ2œ˜7Kšœω™ωK˜—KšŸœœœ1œ˜RK˜š Ÿ œœœ œœ˜;K˜—š Ÿœœœœœ˜NK˜—šŸœœ˜1Kšœ<™