/// <summary> /// This TBS returns a random handle value in the desired handle range (ugh). /// </summary> /// <param name="owner"></param> /// <param name="tpmHandle"></param> /// <returns></returns> private uint GetFreeHandle(Tbs.TbsContext owner, TpmHandle tpmHandle) { Tbs.SlotType neededType = Tbs.SlotTypeFromHandle(tpmHandle); if (neededType == Tbs.SlotType.NoSlot) { return(tpmHandle.handle); } int numTries = 0; while (true) { Ht handleType = tpmHandle.GetType(); var randomPos = (uint)Globs.GetRandomInt((int)TpmHandle.GetRangeLength(tpmHandle.GetType())); uint candidateHandle = ((uint)handleType << 24) + randomPos; if (!OwnerHandleInUse(owner, candidateHandle)) { return(candidateHandle); } numTries++; if (numTries >= 1000) { break; } } throw new Exception("Too many TBS contexts"); }
internal int NumFreeSlots(Tbs.SlotType neededSlot) { int numUsedSlotsOfType = ObjectContexts.Sum(item => (item.Loaded && (item.TheSlotType == neededSlot)) ? 1 : 0); switch (neededSlot) { case Tbs.SlotType.ObjectSlot: return(NumObjectSlots - numUsedSlotsOfType); case Tbs.SlotType.SessionSlot: return(NumSessionSlots - numUsedSlotsOfType); default: throw new Exception("should not be here"); } }
internal ObjectContext CreateObjectContext(Tbs.TbsContext owner, TpmHandle tpmHandle) { Tbs.SlotType newSlotType = Tbs.SlotTypeFromHandle(tpmHandle); if (newSlotType == Tbs.SlotType.NoSlot) { throw new Exception("should not be here"); } // Make a new slot context of the requisite type uint tbsHandle = GetFreeHandle(owner, tpmHandle); var newContext = new ObjectContext { OwnerHandle = new TpmHandle(tbsHandle), TheTpmHandle = tpmHandle, TheSlotType = newSlotType, LastUseCount = GetUseCount(), Loaded = true, Owner = owner }; ObjectContexts.Add(newContext); return(newContext); }
/// <summary> /// Gets the best eviction candidate for entities of given type. May return NULL. /// Pinned entities are the ones used by the current command. /// </summary> /// <param name="type"></param> /// <param name="pinnedEntities"></param> /// <returns></returns> internal ObjectContext GetEntityToEvict(Tbs.SlotType type, ObjectContext[] pinnedEntities) { ObjectContext candidate = null; foreach (ObjectContext c in ObjectContexts) { // See if this context is a candidate for eviction if (c.TheSlotType != type || !c.Loaded || pinnedEntities.Contains(c)) { continue; } // ObjectContext c is a candidate for removal. If we don't already // have a candidate then see if the new candidate is staler. if (candidate == null || c.LastUseCount < candidate.LastUseCount) { candidate = c; } } return(candidate); }
/// <summary> /// Gets the best eviction candidate for entities of given type. May return NULL. /// </summary> /// <param name="neededSlot"></param> /// <param name="neededEntities"></param> /// <returns></returns> internal ObjectContext GetBestEvictionCandidate(Tbs.SlotType neededSlot, ObjectContext[] neededEntities) { ObjectContext candidate = null; foreach (ObjectContext c in ObjectContexts) { // See if this context is a candidate for eviction if (!c.Loaded) { continue; } if (c.TheSlotType != neededSlot) { continue; } // Currently loaded entity of correct type, but is it referenced in this operation? if (neededEntities.Contains(c)) { continue; } // ObjectContext c is a candidate for removal. If we don't already // have a candidate then see if the new candidate is staler than the old. if (candidate == null) { candidate = c; } else { if (c.LastUseCount < candidate.LastUseCount) { candidate = c; } } } return(candidate); }
void ProcessTpmClear(TbsContext caller, Tbs.SlotType excluded = Tbs.SlotType.NoSlot) { ContextManager.ObjectContexts.RemoveAll(ctx => ctx.Owner == caller && ctx.TheSlotType != excluded); Debug.Assert(excluded != Tbs.SlotType.NoSlot || ContextManager.ObjectContexts.Count == 0); }