engine/zone.c
/*
============
Cache_TryAlloc

Looks for a free block of memory between the high and low hunk marks
Size should already include the header and padding
============
*/
Cache_TryAlloc
Looks for a free block of memory between the high and low hunk marks
Size should already include the header and padding
Cache_TryAlloc Looks for a free block of memory between the high and low hunk marks Size should already include the header and padding
cache_system_t *Cache_TryAlloc (int size, bool nobottom)
{
	cache_system_t	*cs, *newc;
	if (!nobottom && cache_head.prev == &cache_head)
	{
		if (hunk_size - hunk_high_used - hunk_low_used < size)
			Sys_Error ("Cache_TryAlloc: %i is greater than free hunk", size);
		newc = (cache_system_t *)(hunk_base + hunk_low_used);
		memset(newc, 0, sizeof(*newc));
		newc->size = size;
		cache_head.prev = cache_head.next = newc;
		newc->prev = newc->next = &cache_head;
		Cache_MakeLRU(newc);
		return newc;
	}
	newc = (cache_system_t *)(hunk_base + hunk_low_used);
	cs = cache_head.next;
	do
	{
		if (!nobottom || cs != cache_head.next)
		{
			if ((byte *)cs - (byte *)newc >= size)
			{	
				memset(newc, 0, sizeof(*newc));
				newc->size = size;
				newc->next = cs;
				newc->prev = cs->prev;
				cs->prev->next = newc;
				cs->prev = newc;
				Cache_MakeLRU(newc);
				return newc;
			}
		}
		newc = (cache_system_t *)((byte *)cs + cs->size);
		cs = cs->next;
	} while (cs != &cache_head);
	if (hunk_base + hunk_size - hunk_high_used - (byte *)newc >= size)
	{
		memset(newc, 0, sizeof(*newc));
		newc->size = size;
		newc->next = &cache_head;
		newc->prev = cache_head.prev;
		cache_head.prev->next = newc;
		cache_head.prev = newc;
		Cache_MakeLRU(newc);
		return newc;
	}
	return NULL;		
}
cache_system_t * Cache_TryAlloc ( int size , bool nobottom ) { cache_system_t * cs , * newc ; if ( ! nobottom && cache_head . prev == & cache_head ) { if ( hunk_size - hunk_high_used - hunk_low_used < size ) Sys_Error ( " " , size ) ; newc = ( cache_system_t * ) ( hunk_base + hunk_low_used ) ; memset ( newc , 0 , sizeof ( * newc ) ) ; newc -> size = size ; cache_head . prev = cache_head . next = newc ; newc -> prev = newc -> next = & cache_head ; Cache_MakeLRU ( newc ) ; return newc ; } newc = ( cache_system_t * ) ( hunk_base + hunk_low_used ) ; cs = cache_head . next ; do { if ( ! nobottom || cs != cache_head . next ) { if ( ( byte * ) cs - ( byte * ) newc >= size ) { memset ( newc , 0 , sizeof ( * newc ) ) ; newc -> size = size ; newc -> next = cs ; newc -> prev = cs -> prev ; cs -> prev -> next = newc ; cs -> prev = newc ; Cache_MakeLRU ( newc ) ; return newc ; } } newc = ( cache_system_t * ) ( ( byte * ) cs + cs -> size ) ; cs = cs -> next ; } while ( cs != & cache_head ) ; if ( hunk_base + hunk_size - hunk_high_used - ( byte * ) newc >= size ) { memset ( newc , 0 , sizeof ( * newc ) ) ; newc -> size = size ; newc -> next = & cache_head ; newc -> prev = cache_head . prev ; cache_head . prev -> next = newc ; cache_head . prev = newc ; Cache_MakeLRU ( newc ) ; return newc ; } return NULL ; }
Cache_TryAlloc
Looks for a free block of memory between the high and low hunk marks
Size should already include the header and padding
Cache_TryAlloc Looks for a free block of memory between the high and low hunk marks Size should already include the header and padding
// is the cache completely empty? // search from the bottom up for space // found space // continue looking // try to allocate one at the very end // couldn't allocate