rtasm_execmem.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a
00006  * copy of this software and associated documentation files (the "Software"),
00007  * to deal in the Software without restriction, including without limitation
00008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00009  * and/or sell copies of the Software, and to permit persons to whom the
00010  * Software is furnished to do so, subject to the following conditions:
00011  *
00012  * The above copyright notice and this permission notice shall be included
00013  * in all copies or substantial portions of the Software.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00018  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00019  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00020  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  **************************************************************************/
00023 
00024 
00033 #include "pipe/p_compiler.h"
00034 #include "pipe/p_debug.h"
00035 #include "pipe/p_thread.h"
00036 #include "util/u_memory.h"
00037 
00038 #include "rtasm_execmem.h"
00039 
00040 
00041 #if defined(__linux__)
00042 
00043 /*
00044  * Allocate a large block of memory which can hold code then dole it out
00045  * in pieces by means of the generic memory manager code.
00046 */
00047 
00048 #include <unistd.h>
00049 #include <sys/mman.h>
00050 #include "pipe/p_thread.h"
00051 #include "util/u_mm.h"
00052 
00053 #define EXEC_HEAP_SIZE (10*1024*1024)
00054 
00055 pipe_static_mutex(exec_mutex);
00056 
00057 static struct mem_block *exec_heap = NULL;
00058 static unsigned char *exec_mem = NULL;
00059 
00060 
00061 static void
00062 init_heap(void)
00063 {
00064    if (!exec_heap)
00065       exec_heap = mmInit( 0, EXEC_HEAP_SIZE );
00066    
00067    if (!exec_mem)
00068       exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, 
00069                                         PROT_EXEC | PROT_READ | PROT_WRITE, 
00070                                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
00071 }
00072 
00073 
00074 void *
00075 rtasm_exec_malloc(size_t size)
00076 {
00077    struct mem_block *block = NULL;
00078    void *addr = NULL;
00079 
00080    pipe_mutex_lock(exec_mutex);
00081 
00082    init_heap();
00083 
00084    if (exec_heap) {
00085       size = (size + 31) & ~31;  /* next multiple of 32 bytes */
00086       block = mmAllocMem( exec_heap, size, 5, 0 ); /* 5 -> 32-byte alignment */
00087    }
00088 
00089    if (block)
00090       addr = exec_mem + block->ofs;
00091    else 
00092       debug_printf("rtasm_exec_malloc failed\n");
00093    
00094    pipe_mutex_unlock(exec_mutex);
00095    
00096    return addr;
00097 }
00098 
00099  
00100 void 
00101 rtasm_exec_free(void *addr)
00102 {
00103    pipe_mutex_lock(exec_mutex);
00104 
00105    if (exec_heap) {
00106       struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
00107    
00108       if (block)
00109          mmFreeMem(block);
00110    }
00111 
00112    pipe_mutex_unlock(exec_mutex);
00113 }
00114 
00115 
00116 #else
00117 
00118 /*
00119  * Just use regular memory.
00120  */
00121 
00122 void *
00123 rtasm_exec_malloc(size_t size)
00124 {
00125    return MALLOC( size );
00126 }
00127 
00128  
00129 void 
00130 rtasm_exec_free(void *addr)
00131 {
00132    FREE(addr);
00133 }
00134 
00135 
00136 #endif

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4