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

📄 memmgr.c

📁 ati driver
💻 C
字号:
/*	Copyright (c) 2002, Thomas Kurschel	Part of Radeon kernel driver			Memory manager used for graphics mem			It has the following features	- doesn't access memory to be managed	- memory block's owner is identified by tag,	  tag is verified during free, and all memory	  belonging to one tag can be freed at once	- multi-threading save*/#include "memmgr.h"#include <malloc.h>#include "KernelExport.h"#define debug_level_flow 1#define debug_level_info 4#define debug_level_error 4#define DEBUG_MSG_PREFIX "Graphics Driver - "#include "debug_ext.h"#ifndef _KERNEL_MODEvoid    _kdprintf_(const char *format, ...);//bool    set_dprintf_enabled(bool);	/* returns old enable flag */#define dprintf _kdprintf_#endif// init manager//   start - start of address space//   len - len of address space//   block_size - granularity//   heap_entries - maximum number of blocksmem_info *mem_init( uint32 start, uint32 len, uint32 block_size, uint32 heap_entries ){	mem_block *first;	mem_info *mem;	uint i;		SHOW_FLOW( 2, "start=%lx, len=%lx, block_size=%lx, heap_entries=%ld",		start, len, block_size, heap_entries );		mem = malloc( sizeof( *mem ));	if( mem == NULL )		goto err;		mem->block_size = block_size;	mem->heap_entries = heap_entries;	mem->lock = create_sem( 1, "mem_lock" );		if( mem->lock < 0 )		goto err2;			mem->heap = malloc( heap_entries * sizeof( mem_block ));	if( mem->heap == NULL )		goto err3;			for( i = 1; i < heap_entries; ++i )		mem->heap[i].next = &mem->heap[i+1];			mem->heap[heap_entries - 1].next = NULL;	mem->unused = &mem->heap[1];	first = &mem->heap[0];	mem->first = first;		first->base = start;	first->size = len;	first->prev = first->next = NULL;	first->alloced = false;		return mem;err3:	delete_sem( mem->lock );	err2:	free( mem );err:	return NULL;}// destroy heapvoid mem_destroy( mem_info *mem ){		SHOW_FLOW0( 2, "" );		free( mem->heap );	delete_sem( mem->lock );	free( mem );}// allocate memory block// in://   mem - heap handle//   size - size in bytes//   tag - owner tag// out://   block_id - block id//   offset - start address of blockstatus_t mem_alloc( mem_info *mem, uint32 size, void *tag, uint32 *block_id, uint32 *offset ){	mem_block *cur, *new_entry;		SHOW_FLOW( 2, "size=%ld, tag=%p", size, tag );		acquire_sem( mem->lock );	// we assume block_size is power of two		size = (size + mem->block_size - 1) & ~(mem->block_size - 1);	// simple first fit		for( cur = mem->first; cur; cur = cur->next ) {		if( !cur->alloced && cur->size >= size )			break;	}		if( cur == NULL ) {		SHOW_FLOW0( 2, "out of memory" );		goto err;	}		if( size != cur->size ) {		new_entry = mem->unused;				if( new_entry == NULL ) {			SHOW_FLOW0( 2, "out of blocks" );			goto err;		}				mem->unused = new_entry->next;			new_entry->next = cur->next;		new_entry->prev = cur;			new_entry->alloced = false;		new_entry->base = cur->base + size;		new_entry->size = cur->size - size;				if( cur->next )			cur->next->prev = new_entry;					cur->next = new_entry;		cur->size = size;	}	cur->alloced = true;	cur->tag = tag;		*block_id = cur - mem->heap + 1;	*offset = cur->base;	release_sem( mem->lock );		SHOW_FLOW( 2, "block_id=%ld, offset=%lx", *block_id, *offset );		return B_OK;	err:	release_sem( mem->lock );	return B_NO_MEMORY;}// merge "block" with successorstatic void merge( mem_info *mem, mem_block *block ){	mem_block *next;		next = block->next;		block->size += next->size;		if( next->next )		next->next->prev = block;		block->next = next->next;	next->next = mem->unused;	mem->unused = next;}// internal: free memory block including mergestatic mem_block *freeblock( mem_info *mem, mem_block *block ){	mem_block *prev, *next;	block->alloced = false;		prev = block->prev;		if( prev && !prev->alloced ) {		block = prev;		merge( mem, prev );	}	next = block->next;			if( next && !next->alloced )		merge( mem, block );			return block;}// free memory//   mem - heap handle//   block_id - block id//   tag - owner tag (must match tag passed to mem_alloc)status_t mem_free( mem_info *mem, uint32 block_id, void *tag ){		mem_block *block;		SHOW_FLOW( 2, "block_id=%ld, tag=%p", block_id, tag );		acquire_sem( mem->lock );		--block_id;		if( block_id >= mem->heap_entries ) {		SHOW_ERROR0( 2, "invalid id" );		goto err;	}			block = &mem->heap[block_id];	if( !block->alloced || block->tag != tag ) {		SHOW_ERROR0( 2, "not owner" );		goto err;	}		freeblock( mem, block );			release_sem( mem->lock );		SHOW_FLOW0( 2, "success" );	return B_OK;	err:	release_sem( mem->lock );	return B_BAD_VALUE;}// free all memory belonging to owner "tag"void mem_freetag( mem_info *mem, void *tag ){	mem_block *cur;		SHOW_FLOW( 2, "tag=%p", tag );		acquire_sem( mem->lock );		for( cur = mem->first; cur; cur = cur->next ) {		if( cur->alloced && cur->tag == tag )			cur = freeblock( mem, cur );	}		release_sem( mem->lock );		SHOW_FLOW0( 2, "done" );}

⌨️ 快捷键说明

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