Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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");			
		}
	}
Ejemplo n.º 3
0
void Building::destroy()
{
	while(occupier.size() > 0)
		Evict(&g_unit[*occupier.begin()]);

	while(worker.size() > 0)
		ResetMode(&g_unit[*worker.begin()]);

	on = false;
}
Ejemplo n.º 4
0
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);
		}
	}
}
Ejemplo n.º 5
0
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;
	}
}
Ejemplo n.º 6
0
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");			
		}
	}
Ejemplo n.º 7
0
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);
	}
Ejemplo n.º 8
0
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);
	}
Ejemplo n.º 9
0
/// 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;
}
Ejemplo n.º 10
0
R3DResource::~R3DResource()
{
    Evict();
}
Ejemplo n.º 11
0
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;
	}
Ejemplo n.º 12
0
void VDFilterFrameCache::Remove(VDFilterFrameBuffer *buf) {
	VDFilterFrameBufferCacheNode *hnode = static_cast<VDFilterFrameBufferCacheNode *>(buf->GetCacheReference(this));

	if (hnode)
		Evict(hnode);
}