executable memory. Based on Thomas Hellstrom's patch. TODO: glapi.c also needs this, but cannot access this code.tags/mesa_20060201
@@ -4,7 +4,6 @@ MESA_MODULES = $(TOP)/src/mesa/libmesa.a | |||
COMMON_SOURCES = \ | |||
../../common/driverfuncs.c \ | |||
../common/mm.c \ | |||
../common/utils.c \ | |||
../common/texmem.c \ | |||
../common/vblank.c \ |
@@ -1172,7 +1172,7 @@ static void free_funcs( struct dynfn *l ) | |||
struct dynfn *f, *tmp; | |||
foreach_s (f, tmp, l) { | |||
remove_from_list( f ); | |||
ALIGN_FREE( f->code ); | |||
_mesa_exec_free( f->code ); | |||
FREE( f ); | |||
} | |||
} |
@@ -59,7 +59,7 @@ do { \ | |||
insert_at_head( &CACHE, dfn ); \ | |||
dfn->key[0] = key[0]; \ | |||
dfn->key[1] = key[1]; \ | |||
dfn->code = ALIGN_MALLOC( end - start, 16 ); \ | |||
dfn->code = _mesa_exec_malloc( end - start ); \ | |||
memcpy (dfn->code, start, end - start); \ | |||
} \ | |||
while ( 0 ) |
@@ -1038,7 +1038,7 @@ static void free_funcs( struct dynfn *l ) | |||
struct dynfn *f, *tmp; | |||
foreach_s (f, tmp, l) { | |||
remove_from_list( f ); | |||
ALIGN_FREE( f->code ); | |||
_mesa_exec_free( f->code ); | |||
FREE( f ); | |||
} | |||
} |
@@ -56,7 +56,7 @@ do { \ | |||
char *end = (char *)&FUNC##_end; \ | |||
insert_at_head( &CACHE, dfn ); \ | |||
dfn->key = key; \ | |||
dfn->code = ALIGN_MALLOC( end - start, 16 ); \ | |||
dfn->code = _mesa_exec_malloc( end - start ); \ | |||
memcpy (dfn->code, start, end - start); \ | |||
} \ | |||
while ( 0 ) |
@@ -0,0 +1,83 @@ | |||
#include "imports.h" | |||
#include "glthread.h" | |||
#ifdef __linux__ | |||
#include <unistd.h> | |||
#include <sys/mman.h> | |||
#include <mm.h> | |||
#define EXEC_HEAP_SIZE (128*1024) | |||
_glthread_DECLARE_STATIC_MUTEX(exec_mutex); | |||
static memHeap_t *exec_heap = NULL; | |||
static unsigned char *exec_mem = NULL; | |||
static void init_heap( void ) | |||
{ | |||
if (!exec_heap) | |||
exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); | |||
if (!exec_mem) | |||
exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, | |||
PROT_EXEC | PROT_READ | PROT_WRITE, | |||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | |||
} | |||
void * | |||
_mesa_exec_malloc( GLuint size ) | |||
{ | |||
PMemBlock block = NULL; | |||
void *addr = NULL; | |||
_glthread_LOCK_MUTEX(exec_mutex); | |||
init_heap(); | |||
if (exec_heap) { | |||
size = (size + 31) & ~31; | |||
block = mmAllocMem( exec_heap, size, 32, 0 ); | |||
} | |||
if (block) | |||
addr = exec_mem + block->ofs; | |||
_glthread_UNLOCK_MUTEX(exec_mutex); | |||
return addr; | |||
} | |||
void | |||
_mesa_exec_free(void *addr) | |||
{ | |||
_glthread_LOCK_MUTEX(exec_mutex); | |||
if (exec_heap) { | |||
PMemBlock block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); | |||
if (block) | |||
mmFreeMem(block); | |||
} | |||
_glthread_UNLOCK_MUTEX(exec_mutex); | |||
} | |||
#else | |||
void * | |||
_mesa_exec_malloc( GLuint size ) | |||
{ | |||
return _mesa_malloc( size ); | |||
} | |||
void | |||
_mesa_exec_free(void *addr) | |||
{ | |||
_mesa_free(addr); | |||
} | |||
#endif |
@@ -723,6 +723,15 @@ _mesa_exit( int status ); | |||
extern void | |||
_mesa_init_default_imports( __GLimports *imports, void *driverCtx ); | |||
/* Allocate executable memory for codegen: | |||
*/ | |||
extern void * | |||
_mesa_exec_malloc( GLuint size ); | |||
extern void | |||
_mesa_exec_free( void *addr ); | |||
#ifdef __cplusplus | |||
} |
@@ -136,6 +136,21 @@ PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch) | |||
return p; | |||
} | |||
PMemBlock mmFindBlock( memHeap_t *heap, int start) | |||
{ | |||
TMemBlock *p = (TMemBlock *)heap; | |||
while (p) { | |||
if (p->ofs == start && p->free) | |||
return p; | |||
p = p->next; | |||
} | |||
return NULL; | |||
} | |||
static __inline__ int Join2Blocks(TMemBlock *p) | |||
{ | |||
if (p->free && p->next && p->next->free) { |
@@ -71,6 +71,13 @@ PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, | |||
*/ | |||
int mmFreeMem( PMemBlock b ); | |||
/* | |||
* Free block starts at offset | |||
* input: pointer to a heap, start offset | |||
* return: pointer to a block | |||
*/ | |||
PMemBlock mmFindBlock( memHeap_t *heap, int start); | |||
/* | |||
* destroy MM | |||
*/ |
@@ -21,6 +21,7 @@ MAIN_SOURCES = \ | |||
main/enable.c \ | |||
main/enums.c \ | |||
main/eval.c \ | |||
main/execmem.c \ | |||
main/extensions.c \ | |||
main/fbobject.c \ | |||
main/feedback.c \ | |||
@@ -36,6 +37,7 @@ MAIN_SOURCES = \ | |||
main/light.c \ | |||
main/lines.c \ | |||
main/matrix.c \ | |||
main/mm.c \ | |||
main/occlude.c \ | |||
main/pixel.c \ | |||
main/points.c \ |
@@ -971,13 +971,13 @@ struct x86_reg x86_fn_arg( struct x86_function *p, | |||
void x86_init_func( struct x86_function *p ) | |||
{ | |||
p->store = _mesa_malloc(1024); | |||
p->store = _mesa_exec_malloc(1024); | |||
p->csr = p->store; | |||
} | |||
void x86_release_func( struct x86_function *p ) | |||
{ | |||
_mesa_free(p->store); | |||
_mesa_exec_free(p->store); | |||
} | |||