bool SoundContext::MapSource(Source &source) { RAD_ASSERT(!source.mapped); RAD_ASSERT(source.channel >= SC_First && source.channel < SC_Max); WriteLock L(m_m); if (m_numSources >= kMaxSimultaneousSounds) { if (!Evict(source.priority)) return false; } ++m_numSources; Source::List *list = &m_channels[source.channel].sources[source.priority]; list->push_back(&source); source.it[0] = list->end(); --source.it[0]; list = &m_sources[source.priority]; list->push_back(&source); source.it[1] = list->end(); --source.it[1]; source.mapped = true; if (source.stream) { m_streams.push_back(&source); source.it[2] = m_streams.end(); --source.it[2]; } return true; }
void CRepositoryCacheManager::RunL() { TTime now; now.UniversalTime(); // Try to evict all the repositories which have expired. There might be more than one repository // destined to expire at the same time, or there are more than one repository with expiry times // between the scheduled expiry time and now (which theoretically should have been the same, but maybe // because of other procesor activity, the timer Active Object just got late a bit) while((iIdleRepositories.Count()) && (iIdleRepositories[0].iCacheTime<=now)) { __CENTREP_TRACE1("CENTREP: Normal Eviction of repository %x", iIdleRepositories[0].iSharedRepository->Uid().iUid); // Always remove from the top of the sorted list iTotalCacheUsage -= iIdleRepositories[0].iSharedRepository->Size(); Evict(0); iIdleRepositories.Remove(0); }; // reschedule to run again at the expiry date of next repository on the list, if any if (iIdleRepositories.Count()) { AtUTC(iIdleRepositories[0].iCacheTime); } else { __CENTREP_TRACE("CENTREP: Cache Empty/Timer Disabled"); } }
void Building::destroy() { while(occupier.size() > 0) Evict(&g_unit[*occupier.begin()]); while(worker.size() > 0) ResetMode(&g_unit[*worker.begin()]); on = false; }
void VDFilterFrameCache::InvalidateAllFrames() { for(int htidx = 0; htidx < kBufferHashTableSize; ++htidx) { HashNodes& hblist = mHashTable[htidx]; while(!hblist.empty()) { VDFilterFrameBufferCacheNode *hnode = static_cast<VDFilterFrameBufferCacheNode *>(hblist.back()); Evict(hnode); } } }
void VDMPEGCache::Write(const void *pData, int64 bytepos, int len) { VDASSERTPTR(this); VDASSERTPTR(pData); VDASSERT(bytepos != 0); VDASSERT(len > 0); if (!mpCacheMemory || (size_t)len > mCacheBlocks.size()*mBlockSize) return; // VDDEBUG2("Cache store: %16I64x + (%5d)\n", bytepos, len); ++mNextAgeValue; int victim = Evict(), next_victim; while(len > 0) { int blen = mBlockSize>len ? mBlockSize : len; len -= blen; // Age must be set before next evict to avoid getting the same block // twice mCacheBlocks[victim].age = mNextAgeValue; next_victim = -1; if (len) next_victim = Evict(); memcpy(mpCacheMemory + mBlockSize*victim, pData, blen); mCacheBlocks[victim].pos = bytepos; mCacheBlocks[victim].len = blen; mCacheBlocks[victim].next = next_victim; // Only write out a non-zero byte position for the first block. bytepos = 0; pData = (char *)pData + blen; victim = next_victim; } }
void CRepositoryCacheManager::RunL() { TTime now; now.UniversalTime(); TInt count = iIdleRepositories.Count(); // repositories that are involved in active transactions are not idle. // this checks to make sure that we're not trying to reclaim memory that // is actually still currently in use. for (TInt i = 0;i < count;i++) { if (iIdleRepositories[i].iCacheTime > now) { break; } if (iIdleRepositories[i].iSharedRepository->IsTransactionActive()) { __CENTREP_TRACE1("CRepositoryCacheManager::RunL - rescheduling UID 0x%x, in active transaction", iIdleRepositories[i].iSharedRepository->Uid().iUid); StartEviction(iIdleRepositories[i].iSharedRepository); return; } } // Try to evict all the repositories which have expired. There might be more than one repository // destined to expire at the same time, or there are more than one repository with expiry times // between the scheduled expiry time and now (which theoretically should have been the same, but maybe // because of other procesor activity, the timer Active Object just got late a bit) while((iIdleRepositories.Count()) && (iIdleRepositories[0].iCacheTime<=now)) { __CENTREP_TRACE1("CENTREP: Normal Eviction of repository %x", iIdleRepositories[0].iSharedRepository->Uid().iUid); // Always remove from the top of the sorted list iTotalCacheUsage -= iIdleRepositories[0].iSharedRepository->Size(); Evict(0); iIdleRepositories.Remove(0); }; // reschedule to run again at the expiry date of next repository on the list, if any if (iIdleRepositories.Count()) { RescheduleTimer(iIdleRepositories[0].iCacheTime); } else { __CENTREP_TRACE("CENTREP: Cache Empty/Timer Disabled"); } }
void CRepositoryCacheManager::FlushCache() { // cancel any outstanding timer Cancel(); TInt idleRepCount = iIdleRepositories.Count(); for(TInt repCount = idleRepCount - 1; repCount >= 0 ; repCount--) { Evict(repCount); } // empty the list iIdleRepositories.Reset(); iTotalCacheUsage = 0; __CENTREP_TRACE1("CENTREP: Cache Flush: %d repositories flushed", idleRepCount); }
void CRepositoryCacheManager::FlushCache(TBool aFullFlush) { // iterate through idle repositories (loaded in memory, scheduled to be evicted) TInt idleRepCount = iIdleRepositories.Count(); for(TInt repCount = idleRepCount - 1; repCount >= 0 ; repCount--) { // check if there are any observers listening (to see if any client is connected to this repository) if (aFullFlush || (TServerResources::iObserver->FindConnectedRepository(iIdleRepositories[repCount].iSharedRepository->Uid())==KErrNotFound)) { // if the client has already been disconnected, unload from memory Evict(repCount); } } // this whole iteration and search above can be replaced by a simple reference counter variable check, // if the server is redesigned using a resource manager type pattern with CSharedRepository object as a resource // empty the list iIdleRepositories.Reset(); iTotalCacheUsage = 0; __CENTREP_TRACE1("CENTREP: Cache Flush: %d repositories flushed", idleRepCount); }
/// Load given page into memory char* TPgBlob::LoadPage(const TPgBlobPgPt& Pt, const bool& LoadData) { int Pg; if (LoadedPagesH.IsKeyGetDat(Pt, Pg)) { // is page in cache MoveToStartLru(Pg); return GetPageBf(Pg); } if ((uint64)LoadedPages.Len() == MxLoadedPages) { // evict last page + load new page Pg = Evict(); LoadedPage& a = LoadedPages[Pg]; if (LoadData) { Files[Pt.GetFIx()]->LoadPage(Pt.GetPg(), GetPageBf(Pg)); } a.Pt = Pt; EnlistToStartLru(Pg); LoadedPagesH.AddDat(Pt, Pg); } else { // simply load the page LastExtentCnt++; if (LastExtentCnt >= PG_EXTENT_PCOUNT) { Extents.Add(); Extents.Last() = TMemBase(PG_EXTENT_SIZE); LastExtentCnt = 0; } Pg = LoadedPages.Add(); LoadedPage& a = LoadedPages[Pg]; if (LoadData) { Files[Pt.GetFIx()]->LoadPage(Pt.GetPg(), GetPageBf(Pg)); } a.Pt = Pt; EnlistToStartLru(Pg); LoadedPagesH.AddDat(Pt, Pg); } char* PgPt = GetPageBf(Pg); ((TPgHeader*)PgPt)->SetDirty(false); return PgPt; }
R3DResource::~R3DResource() { Evict(); }
TBool CRepositoryCacheManager::StartEviction(CSharedRepository*& aRepository) { // find the item in the cache and remove it if it exists to reset the timer RemoveIdleRepository(aRepository); TInt64 lastTop = 0; if (iIdleRepositories.Count()) { lastTop = iIdleRepositories[0].iCacheTime.Int64(); } // Execute the forced eviction algorithm only if it will make sense // The eviction makes sense if: // - there's anything in the cache to evict // - the repository we're trying to cache can fit in the cache after evictions if (iIdleRepositories.Count() && (aRepository->Size() < iCacheSize)) { // Check to see if current cache size + the current repository size is overshooting the limit if (iTotalCacheUsage + aRepository->Size() > iCacheSize) { // Forced eviction __CENTREP_TRACE3("CENTREP: Cache Size Exceeded: Current(%d)+Size(%d)>Cache(%d)", iTotalCacheUsage, aRepository->Size(), iCacheSize); // Sort in the forced eviction order TLinearOrder<TRepositoryCacheInfo> forcedSortOrder(CRepositoryCacheManager::ForcedEvictionSortOrder); iIdleRepositories.Sort(forcedSortOrder); // Evict one by one until there's enough cache space or we run out of idle reps do { __CENTREP_TRACE1("CENTREP: Forced Eviction of repository %x", iIdleRepositories[0].iSharedRepository->Uid().iUid); iTotalCacheUsage -= iIdleRepositories[0].iSharedRepository->Size(); Evict(0); iIdleRepositories.Remove(0); } while (iIdleRepositories.Count() && (iTotalCacheUsage + aRepository->Size() > iCacheSize)); #ifdef CENTREP_TRACE if (!iIdleRepositories.Count()) { __CENTREP_TRACE("CENREP: Cache Emptied by Forced Eviction"); } #endif // Re-sort to timer order for normal operation TLinearOrder<TRepositoryCacheInfo> timerSortOrder(CRepositoryCacheManager::TimerEvictionSortOrder); iIdleRepositories.Sort(timerSortOrder); }; } // See if there's enough space now if (iTotalCacheUsage + aRepository->Size() > iCacheSize) { return EFalse; } // Create new item for the cache and insert it in the list TRepositoryCacheInfo repInfo; repInfo.iCacheTime.UniversalTime(); repInfo.iCacheTime += TTimeIntervalMicroSeconds32(iDefaultTimeout); repInfo.iSharedRepository = aRepository; TLinearOrder<TRepositoryCacheInfo> timerSortOrder(CRepositoryCacheManager::TimerEvictionSortOrder); // With the same timeout value assigned to all repositories, no two repositories can have the same // timeout theoretically, so InsertInOrder is sufficient. But in practice, because of the poor // resolution of the NTickCount() function used by TTime::UniversalTime(), InsertInOrderAllowRepeats // should be used instead of InsertInOrder to allow for duplicate timer values caused by two // repositories cached in quick succession (<1ms) TInt err = iIdleRepositories.InsertInOrderAllowRepeats(repInfo, timerSortOrder); #ifdef CACHE_OOM_TESTABILITY // This code is only for tesing and doesn't go into MCL if (err == KErrNoMemory) { TServerResources::iObserver->RemoveOpenRepository(aRepository); aRepository = NULL; // Should Leave here for the OOM tests to successfully complete. TEST_CODE_LEAVE(err); } #endif if (err!=KErrNone) { return EFalse; } iTotalCacheUsage += repInfo.iSharedRepository->Size(); // Only reset timer if necessary. This operation takes time and doing it every time reduces performance considerably if (lastTop != iIdleRepositories[0].iCacheTime.Int64()) { // reset timer to the new top-of-the-list Cancel(); RescheduleTimer(iIdleRepositories[0].iCacheTime); } return ETrue; }
void VDFilterFrameCache::Remove(VDFilterFrameBuffer *buf) { VDFilterFrameBufferCacheNode *hnode = static_cast<VDFilterFrameBufferCacheNode *>(buf->GetCacheReference(this)); if (hnode) Evict(hnode); }