tlsf_rtt.c
Go to the documentation of this file.
00001 
00002 #include <stddef.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 
00006 #include "tlsf.h"
00007 #include "tlsf_rtt.h"
00008 
00009 #define RTL_TLSF_DEBUG          1
00010 
00011 #define DEBUG_TLSF_ALLOC        (1<<0)
00012 #define DEBUG_TLSF_FREE         (1<<1)
00013 #define DEBUG_TLSF_TRACE        (1<<20)
00014 
00015 #ifdef RTL_TLSF_DEBUG
00016 # define _DBG(x, mask, fmt, args...) do{ if (mask & x) printf("%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
00017 #else
00018 # define _DBG(x, mask, fmt, args...) do { } while(0);
00019 #endif
00020 
00021 #define TLSF_POOL_MIN_SIZE      1*1014*1024
00022 
00023 /* create a memory pool of sz and initialize it for use with TLSF */
00024 int tlsf_rtt_init_mp(struct lua_tlsf_info *tlsf_inf, size_t sz)
00025 {
00026         tlsf_inf->L = NULL;
00027         tlsf_inf->mask = 0;
00028         tlsf_inf->pool2 = NULL;
00029         tlsf_inf->total_mem = 0;
00030 
00031         if(sz < TLSF_POOL_MIN_SIZE) {
00032                 fprintf(stderr, "error: requested tlsf pool size (0x%lx) too small\n", (unsigned long) sz);
00033                 goto fail;
00034         }
00035 
00036         tlsf_inf->pool = malloc(sz);
00037 
00038         if(!tlsf_inf->pool) {
00039                 fprintf(stderr, "error failed to allocate: 0x%lx bytes\n", (unsigned long) sz);
00040                 goto fail;
00041         }
00042 
00043         tlsf_inf->total_mem = rtl_init_memory_pool(sz, tlsf_inf->pool);
00044         return 0;
00045  fail:
00046         return -1;
00047 }
00048 
00049 /* cleanup mempool */
00050 void tlsf_rtt_free_mp(struct lua_tlsf_info *tlsf_inf)
00051 {
00052          rtl_destroy_memory_pool(tlsf_inf->pool);
00053          free(tlsf_inf->pool);
00054 
00055          if(tlsf_inf->pool2)
00056                  free(tlsf_inf->pool2);
00057 }
00058 
00059 /* this hook will print a backtrace and reset itself */
00060 static void tlsf_trace_hook(lua_State *L, lua_Debug *ar)
00061 {
00062         (void)ar;
00063         lua_sethook(L, tlsf_trace_hook, 0, 0);
00064         luaL_error(L, "memory allocation in TLSF trace mode");
00065 }
00066 
00067 /* tlsf based Lua allocator */
00068 void* tlsf_alloc (void *ud, void *ptr, size_t osize, size_t nsize)
00069 {
00070         (void)osize;
00071         struct lua_tlsf_info *tlsf_inf = (struct lua_tlsf_info*) ud;
00072 
00073         if (nsize == 0) {
00074                 _DBG(DEBUG_TLSF_FREE, tlsf_inf->mask, "freeing 0x%lx, osize=%lu, nsize=%lu",
00075                      (unsigned long) ptr, (unsigned long) osize, (unsigned long) nsize);
00076                 rtl_free_ex(ptr, tlsf_inf->pool);
00077                 return NULL;
00078         } else {
00079                 if(DEBUG_TLSF_TRACE & tlsf_inf->mask) {
00080                         lua_sethook(tlsf_inf->L, tlsf_trace_hook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT, 1);
00081                 }
00082                 _DBG(DEBUG_TLSF_ALLOC, tlsf_inf->mask, "allocating 0x%lx, osize=%lu, nsize=%lu",
00083                      (unsigned long) ptr, (unsigned long) osize, (unsigned long) nsize);
00084                 return rtl_realloc_ex(ptr, nsize, tlsf_inf->pool);
00085         }
00086 }
00087 
00088 int tlsf_rtt_incmem(struct lua_tlsf_info *tlsf_inf, size_t sz)
00089 {
00090         if(tlsf_inf->pool2 != NULL)
00091                 luaL_error(tlsf_inf->L, "tlsf_rtt_incmem: region already increased, (increasing cur. only possible once)");
00092 
00093         if((tlsf_inf->pool2 = malloc(sz)) == NULL)
00094                 luaL_error(tlsf_inf->L, "tlsf_rtt_incmem: failed to increase memory by %d bytes. Out of mem.");
00095 
00096         tlsf_inf->total_mem += rtl_add_new_area(tlsf_inf->pool2, sz, tlsf_inf->pool);
00097 
00098         return 0;
00099 }
00100 
00101 /* store and retrieve the tlsf_info in the registry
00102  * this is required for the enabling and disabling
00103  * trace functions
00104  */
00105 void set_context_tlsf_info(struct lua_tlsf_info* tlsf_inf)
00106 {
00107         lua_pushstring(tlsf_inf->L, "tlsf_info");
00108         lua_pushlightuserdata(tlsf_inf->L, tlsf_inf);
00109         lua_rawset(tlsf_inf->L, LUA_REGISTRYINDEX);
00110 }
00111 
00112 struct lua_tlsf_info* get_context_tlsf_info(lua_State *L)
00113 {
00114         lua_pushstring(L, "tlsf_info");
00115         lua_rawget(L, LUA_REGISTRYINDEX);
00116         return (struct lua_tlsf_info*) lua_touserdata(L, -1);
00117 }
00118 
00119 static int tlsf_trace(lua_State *L)
00120 {
00121         int argc, enable, ret;
00122         struct lua_tlsf_info *tlsf_inf = get_context_tlsf_info(L);
00123         ret = 0;
00124         argc = lua_gettop(L);
00125 
00126         if(argc == 0) {
00127                 lua_pushboolean(L, tlsf_inf->mask & DEBUG_TLSF_TRACE);
00128                 ret = 1;
00129                 goto out;
00130         }
00131 
00132         enable = lua_toboolean(L, 1);
00133 
00134         if(enable) {
00135                 tlsf_inf->mask |= DEBUG_TLSF_TRACE;
00136         } else {
00137                 lua_sethook(L, tlsf_trace_hook, 0, 1);
00138                 tlsf_inf->mask &= ~DEBUG_TLSF_TRACE;
00139         }
00140 
00141 out:
00142         return ret;
00143 }
00144 
00145 static int tlsf_warn(lua_State *L)
00146 {
00147         int argc, enable, ret;
00148         struct lua_tlsf_info *tlsf_inf = get_context_tlsf_info(L);
00149         ret = 0;
00150         argc = lua_gettop(L);
00151 
00152         if(argc == 0) {
00153                 lua_pushboolean(L, tlsf_inf->mask & (DEBUG_TLSF_ALLOC | DEBUG_TLSF_FREE));
00154                 ret = 1;
00155                 goto out;
00156         }
00157 
00158         enable = lua_toboolean(L, 1);
00159 
00160         if(enable)
00161                 tlsf_inf->mask |= DEBUG_TLSF_ALLOC | DEBUG_TLSF_FREE;
00162         else
00163                 tlsf_inf->mask &= ~(DEBUG_TLSF_ALLOC | DEBUG_TLSF_FREE);
00164  out:
00165         return ret;
00166 }
00167 
00168 static int tlsf_stats(lua_State *L)
00169 {
00170         struct lua_tlsf_info *tlsf_inf = get_context_tlsf_info(L);
00171 
00172         lua_pushinteger(L, rtl_get_used_size(tlsf_inf->pool));
00173         lua_pushinteger(L, rtl_get_max_size(tlsf_inf->pool));
00174         lua_pushinteger(L, tlsf_inf->total_mem);
00175         return 3;
00176 }
00177 
00178 static const struct luaL_Reg tlsf_f [] = {
00179         {"stats", tlsf_stats },
00180         {"warn", tlsf_warn },
00181         {"trace", tlsf_trace },
00182         {NULL, NULL}
00183 };
00184 
00185 void register_tlsf_api(lua_State *L)
00186 {
00187         luaL_register(L, "tlsf", tlsf_f);
00188 }


ocl
Author(s): OCL Development Team
autogenerated on Thu Jan 2 2014 11:38:08