⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memmgr.c copy 2

📁 ati driver
💻 C COPY 2
字号:
#include "memmgr.h"#include <stdlib.h>mem_info *mem_init( void *start, int len, int block_size ){	mem_block *first;	mem_info *mem;		first = malloc( sizeof( *first ));	if( first == NULL )		return NULL;			first->base = start;	first->size = len;	first->prev = first->next = NULL;	first->inuse = false;		mem = malloc( sizeof( *mem ));	if( mem == NULL ) {		free( first );		return NULL;	}		mem->first = first;		return mem;}void mem_destroy( mem_info *info ){	mem_block *cur, *next;		for( cur = info->first; cur; cur = next ) {		next = cur->next;				free( cur );	}		free( info );}mem_client_block *mem_alloc( mem_client_info *mem_client, int size ){	mem = mem_client->server_info;		if( size == 0 ) {		SHOW_ERROR0( 1, "tried to alloc block of size zero" );		return B_INVALID_PARAMS;	}	if( mem_client->free_list == NULL ) {		SHOW_ERROR0( 1, "Out of client memory blocks" );		return B_ERROR;	}		num_blocks = (size + mem->block_size - 1) & ~(mem->block_size - 1);		for( start = 0; start < mem->num_blocks; ) {		for( left_len = num_blocks, cur_pos = start; len > 0; ) {			if( cur_pos > mem->num_blocks )				break;							cur_block = mem->blocks[cur_pos];			remaining_block_len = cur_block->len - (start - cur_block->start);						if( cur_block->state != state_locked ) {				cur_pos += remaining_block_len;				len -= remaining_block_len;			} else {				cur_pos = start = cur_pos + remaining_block_len;				len = num_blocks;			} 		}					if( len < num_blocks ) 			break;					cur_costs = mem_calc_costs( start, len );				if( cur_costs < best_costs ) {			best_start = start;			best_costs = cur_costs;						if( best_costs == 0 )				break;		}		cur_block = mem->blocks[start];		skip_head = cur_block->len - (start - cur_block->start);		cur_block = mem->blocks[start + len - 1];		skip_tail = cur_block->len - (start + len - 1 - cur_block->start);		/*if( skip_tail == 0 )			skip_tail = 1;*/					start += MAX( skip_head, skip_tail );	}	if( best_start == 0 ) {		SHOW_ERROR( 1, "Couldn't find gap of requested size (%i bytes)", size );		return B_NO_MEMORY;			for( left_blocks = num_blocks, cur_pos = best_start; left_blocks > 0; ) {		cur_block = mem->blocks[cur_pos];		remaining_block_len = cur_block->len - (start - cur_block->start);				mem_free( mem, cur_block );				cur_pos += remaining_block_len;		left_blocks -= remaining_block_len;	}			new_block = mem->block_array[best_start];	new_block->mem_client = mem_client;	new_block->client = mem_client_info;	new_block->start = best_start;	new_block->len = num_blocks;	new_block->state = state_inuse;	new_block->address = mem_server->address + num_blocks * mem_server->block_size;		client_block->server_block = new_block;	client_block->discarded = false;		for( left_blocks = num_blocks, cur_pos = best_start; 		 left_blocks > 0; 		 --left_blocks, ++cur_pos )	{		mem->blocks[cur_pos] = new_block;	}	return B_OK;	}void mem_discard( mem_server_block *server_block ){	mem_client = server_block->mem_client;	client_block = server_block->client_block;		client_block->discarded = true;	client_block->next = mem_client->discarded_list;		mem_client->discarded_list = client_block;}	void mem_markfree( mem_server_info *mem_server, int pos, int len ){	server_block = client_block->server_block;	free_block = mem_server->blocks[client_block->start];	free_block->start = start;	free_block->len = len;		if( start > 0 ) {		prev_block = mem_server->blocks[start-1];		if( prev_block->state = state_free ) {			prev_block->len += len;			free_block = prev_block;		}	}		for( cur_pos = server_block->start, blocks_left = server_block->len;		 blocks_left > 0;		 ++cur_pos, --blocks_left )	{		mem_server->blocks[cur_pos] = free_block;	}}void mem_remove_from_discarded( mem_client_info *mem_client, mem_client_block *client_block ){	if( cur_block == mem_client->discarded_list )		mem_client->discarded_list = cur_block->next;	else {		for( cur_block = mem_client->discarded_list; 			 cur_block; 			 cur_block = cur_block->next )		{			if( cur_block->next == client_block )				break;		}				if( cur_block == NULL )			SHOW_ERROR( 0, "couldn't find discarded block in list" );		else			cur_block->next = client_block->next;	}}	status_t mem_free( mem_client_info *mem_client, mem_client_block *client_block ){	mem_server_info *mem_server = mem_client->server_info;		if( client_block->discarded )		mem_remove_from_discarded( mem_client, client_block );	mem_markfree( mem_server, server_block->start, server_block->len;		client_block->next = mem_client->free_list;	mem_client->free_list = client_block;}				mem_block *cur, *new_entry;		size = (size + mem->block_size - 1) & ~(mem->block_size - 1);		for( cur = mem->first; cur; cur = cur->next ) {		if( !cur->inuse && cur->size >= size )			break;	}		if( cur == NULL )		return NULL;			cur->inuse = true;		if( size == cur->size )		return cur;			new_entry = malloc( sizeof( *new_entry ));		if( new_entry == NULL )		return NULL;		new_entry->base = cur->base;	new_entry->size = size;			cur->base += size;	cur->size -= size;			if( cur->prev )		cur->prev->next = new_entry;	else		mem->first = new_entry;			cur->prev = new_entry;	new_entry->next = cur;		return new_entry;}void mem_free( mem_info *info, mem_block *block ){	mem_block *prev, *next;		block->inuse = false;		prev = block->prev;		if( prev && !prev->inuse ) {		prev->size += block->size;		if( block->next )			block->next->prev = prev;		prev->next = block->next;		free( block );		block = prev;	}	next = block->next;			if( next && !next->inuse ) {		next->size += block->size;				if( block->prev ) {			block->prev->next = next;		} else			info->first = next;				next->prev = block->prev;				free( block );	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -