void deAlloc(MEM_ULONG address) { unsigned int sr; sr = spin_lock_irqsave(); address -= getalign(address); my_free(address); spin_unlock_irqrestore(sr); }/*end deAlloc*/
static int b_size (lua_State *L) { int native; const char *fmt = luaL_checkstring(L, 1); int align; int totalsize = 0; getendianess(&fmt, &native); align = getalign(&fmt); while (*fmt) { int opt = *fmt++; int size = optsize(opt, &fmt); int toalign = gettoalign(L, align, opt, size); if (size == 0) luaL_error(L, "options `c0' - `s' have undefined sizes"); totalsize += toalign - 1; totalsize -= totalsize&(toalign-1); totalsize += size; } lua_pushnumber(L, totalsize); return 1; }
static int b_unpack (lua_State *L) { int native; const char *fmt = luaL_checkstring(L, 1); size_t ld; int pos, align, endian; const char *data; if(lua_isuserdata(L, 2)) { data = (const char*)lua_touserdata(L, 2); ld = (size_t)luaL_checkinteger(L, 3); pos = luaL_optint(L, 4, 1) - 1; } else { data = luaL_checklstring(L, 2, &ld); pos = luaL_optint(L, 3, 1) - 1; } endian = getendianess(&fmt, &native); align = getalign(&fmt); lua_settop(L, 2); while (*fmt) { int opt = *fmt++; int size = optsize(opt, &fmt); int toalign = gettoalign(L, align, opt, size); pos += toalign - 1; pos -= pos&(toalign-1); luaL_argcheck(L, pos+size <= (int)ld, 2, "data string too short"); switch (opt) { case ' ': break; /* ignore white spaces */ case 'b': case 'B': case 'h': case 'H': case 'l': case 'L': case 'i': case 'I': { /* integer types */ int withsign = islower(opt); getinteger(L, data+pos, endian, withsign, size); break; } case 'x': { break; } case 'f': { float f; memcpy(&f, data+pos, size); if (endian != native) invertbytes((char *)&f, sizeof(f)); lua_pushnumber(L, f); break; } case 'd': { double d; memcpy(&d, data+pos, size); if (endian != native) invertbytes((char *)&d, sizeof(d)); lua_pushnumber(L, d); break; } case 'c': { if (size == 0) { if (!lua_isnumber(L, -1)) luaL_error(L, "format `c0' needs a previous size"); size = lua_tonumber(L, -1); lua_pop(L, 1); luaL_argcheck(L, pos+size <= (int)ld, 2, "data string too short"); } lua_pushlstring(L, data+pos, size); break; } case 's': { const char *e = (const char *)memchr(data+pos, '\0', ld - pos); if (e == NULL) luaL_error(L, "unfinished string in data"); size = (e - (data+pos)) + 1; lua_pushlstring(L, data+pos, size - 1); break; } case 'p': { void* p; memcpy(&p, data+pos, size); lua_pushlightuserdata(L, p); break; } default: invalidformat(L, opt); } pos += size; } lua_pushnumber(L, pos + 1); return lua_gettop(L) - 2; }
static int b_pack (lua_State *L) { luaL_Buffer b; int native; const char *fmt = luaL_checkstring(L, 1); int endian = getendianess(&fmt, &native); int align = getalign(&fmt); int arg = 2; int totalsize = 0; void *p; lua_pushnil(L); /* mark to separate arguments from string buffer */ luaL_buffinit(L, &b); for (; *fmt; arg++) { int opt = *fmt++; int size = optsize(opt, &fmt); int toalign = gettoalign(L, align, opt, size); while ((totalsize&(toalign-1)) != 0) { luaL_putchar(&b, '\0'); totalsize++; } switch (opt) { case ' ': break; /* ignore white spaces */ case 'b': case 'B': case 'h': case 'H': case 'l': case 'L': case 'i': case 'I': { /* integer types */ putinteger(L, &b, arg, endian, size); break; } case 'x': { arg--; /* undo increment */ luaL_putchar(&b, '\0'); break; } case 'f': { float f = (float)luaL_checknumber(L, arg); if (endian != native) invertbytes((char *)&f, size); luaL_addlstring(&b, (char *)&f, size); break; } case 'd': { double d = luaL_checknumber(L, arg); if (endian != native) invertbytes((char *)&d, size); luaL_addlstring(&b, (char *)&d, size); break; } case 'c': case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (size == 0) size = l; luaL_argcheck(L, l >= (size_t)size, arg, "string too short"); luaL_addlstring(&b, s, size); if (opt == 's') { luaL_putchar(&b, '\0'); /* add zero at the end */ size++; } break; } case 'p': { luaL_argcheck(L, lua_isuserdata(L, arg) || lua_isnil(L, arg), arg, "userdata, light userdata, or nil required"); p = lua_touserdata(L, arg); luaL_addlstring(&b, (char*)&p, size); break; } default: invalidformat(L, opt); } totalsize += size; } luaL_pushresult(&b); return 1; }
MEM_ULONG Drv_realloc(MEM_ULONG address,MEM_ULONG nbytes) { unsigned int sr; sr = spin_lock_irqsave(); MEM_ULONG rr,addr,oldsize; MEM_ULONG block,rblock,rrblock; MEM_ULONG bsize,rbsize,align; unsigned int len; oldsize = nbytes; nbytes = ((nbytes + MIN_FREE_BYTES - 1)/ MIN_FREE_BYTES ) * MIN_FREE_BYTES; rr = address; if (nbytes == 0) { spin_unlock_irqrestore(sr); deAlloc(rr); return 0; } if (address == 0) { addr = my_alloc(nbytes); if(addr != 0) setalign(addr,0); spin_unlock_irqrestore(sr); return addr; } align = getalign(address); len = (nbytes + align + MIN_FREE_BYTES - 1) &(~(MIN_FREE_BYTES - 1)); address -= getalign(address); address -= SIZE_HEADER; bsize = size(address); //printf("align = %d,address = %x %d %d\n",align,address,nbytes,bsize); if(nbytes <= bsize-align) { spin_unlock_irqrestore(sr); return rr; } rblock = next(address); if((rblock != 0) &&(status(rblock) == FREE) ) { //printf("rblock = %x %d %d",rblock,status(rblock),size(rblock)); bsize += size(rblock); if(bsize >= nbytes + align) { rrblock = next(rblock); next(address) = address + len + SIZE_HEADER; block = next(address); prev(block) = address; next(block) = rrblock; if(rrblock) prev(rrblock) = block; status(block) = FREE; spin_unlock_irqrestore(sr); return rr; } } addr = my_alloc(len); //printf("realloc %x %x %x %x\n",addr,rr,nbytes,bsize); if(addr == 0) { spin_unlock_irqrestore(sr); return 0; } addr += align; setalign(addr,align); memcpy(addr,rr,bsize); spin_unlock_irqrestore(sr); deAlloc(rr); return addr; }