static int CreateHostmem(lua_State *L) { size_t size; const char *ptr; hostmem_t* hostmem; if(lua_type(L, 1) == LUA_TSTRING) { ptr = lua_tolstring(L, 1, &size); } else { size = luaL_checkinteger(L, 1); ptr = (char*)checklightuserdata(L, 2); } if(size == 0) return luaL_argerror(L, 1, errstring(ERR_LENGTH)); hostmem = (hostmem_t*)MallocNoErr(L, sizeof(hostmem_t)); if(!hostmem) { Free(L, hostmem); return luaL_error(L, errstring(ERR_MEMORY)); } hostmem->ptr = (char*)ptr; hostmem->size = size; newhostmem(L, hostmem); return 1; }
static int Create(lua_State *L, int arg, size_t alignment) { const char *data = NULL; char *ptr; size_t size; if(lua_type(L, arg) == LUA_TSTRING) { if(!lua_isnoneornil(L, arg+1)) return CreatePack(L, arg, alignment); data = luaL_checklstring(L, arg, &size); if(size == 0) return luaL_argerror(L, arg, errstring(ERR_LENGTH)); } else { size = luaL_checkinteger(L, arg); if(size == 0) return luaL_argerror(L, arg, errstring(ERR_VALUE)); } ptr = (char*)AlignedAlloc(alignment, size); // (char*)Malloc(L, size); if(!ptr) return luaL_error(L, "failed to allocate page aligned memory"); if(data) memcpy(ptr, data, size); else memset(ptr, 0, size); CreateAllocated(L, ptr, size); return 1; }
static int CreatePack(lua_State *L, int arg, size_t alignment) { int err; char *ptr; int type = checktype(L, arg); size_t n = toflattable(L, arg+1); size_t size = n * sizeoftype(type); if(size == 0) return luaL_argerror(L, arg+1, errstring(ERR_LENGTH)); ptr = (char*)AlignedAlloc(alignment, size); if(!ptr) return luaL_error(L, "failed to allocate page aligned memory"); err = testdata(L, type, n, ptr, size); if(err) { free(ptr); return luaL_argerror(L, arg+1, errstring(err)); } CreateAllocated(L, ptr, size); return 1; }
static int Copy(lua_State *L) { int t = lua_type(L, 4); if(t == LUA_TLIGHTUSERDATA) return CopyPtr(L); if(t == LUA_TUSERDATA) return CopyHostmem(L); return luaL_argerror(L, 4, errstring(ERR_TYPE)); }
static int Clear(lua_State *L) /* clear(offset, size, c) */ { size_t len; const char *s; char c; hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_checkinteger(L, 2); size_t size = luaL_checkinteger(L, 3); if(lua_type(L, 4) == LUA_TSTRING) { s = luaL_checklstring(L, 4, &len); if(len != 1) return luaL_argerror(L, 4, "invalid length"); /* must be 1 */ c = s[0]; } else c = luaL_optinteger(L, 4, 0); if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); if(size == 0) return 0; memset(hostmem->ptr + offset, c, size); return 0; }
static int Write(lua_State *L) { int t = lua_type(L, 3); if(t == LUA_TSTRING) return WritePack(L); if(t == LUA_TNIL) return WriteData(L); return luaL_argerror(L, 3, errstring(ERR_TYPE)); }
// log_error: log an error of the operation void log_error(DWORD id, BYTE code) { time_t now = time(NULL); char nowstring[32]; // ctime_r documentation says there must be // room here for 26 bytes. ctime_r(&now, &nowstring[0]); write_log(1, "id:%d, error:%s, time:%s", id, errstring(code), nowstring); }
static int CopyHostmem(lua_State *L) { hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_checkinteger(L, 2); size_t size = luaL_checkinteger(L, 3); hostmem_t* srchostmem = checkhostmem(L, 4, NULL); size_t srcoffset = luaL_checkinteger(L, 5); if(hostmem == srchostmem) return luaL_argerror(L, 4, "source and destination hostmem are the same"); if(size == 0) return 0; if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); if((srcoffset >= srchostmem->size) || (size > srchostmem->size - srcoffset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); memcpy(hostmem->ptr + offset, srchostmem->ptr + srcoffset, size); return 0; }
static int Ptr(lua_State *L) { hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_optinteger(L, 2, 0); size_t size = luaL_optinteger(L, 3, 0); if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); lua_pushlightuserdata(L, hostmem->ptr + offset); return 1; }
static int WritePack(lua_State *L) { hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_checkinteger(L, 2); int type = checktype(L, 3); size_t size = hostmem->size - offset; if(offset >= hostmem->size) return luaL_error(L, errstring(ERR_BOUNDARIES)); checkdata(L, 4, type, hostmem->ptr + offset, size); return 0; }
thread_t* thread_create(runnable_t runnable, size_t stacksize, const char* name, void* p) { thread_t* thread = (thread_t*)malloc(sizeof(thread_t)); memset(thread, 0, sizeof(thread_t)); if (pthread_attr_init(&thread->attr) < 0) { error_log("pthread_attr_init:%d,%s\n", errno, errstring(errno)); free(thread); return NULL; } if (pthread_attr_setstacksize(&thread->attr, stacksize) < 0) { error_log("pthread_attr_setstacksize:%d,%s\n", errno, errstring(errno)); free(thread); return NULL; } if (pthread_attr_getstacksize(&thread->attr, &thread->stacksize) < 0) { error_log("pthread_attr_getstacksize:%d,%s\n", errno, errstring(errno)); free(thread); return NULL; } thread->name = name; /*thread->stacksize = stacksize;*/ thread->runnable = runnable; thread->p = p; thread->running = true; if (pthread_create(&thread->pid, &thread->attr, static_runnable, thread)) { error_log("pthread_create:%d,%s\n", errno, errstring(errno)); free(thread); return NULL; } return thread; }
bool thread_pool_insert(const char* name, runnable_t runnable, void* p) { thread_t* thread = thread_create(runnable, 16*MB, name, p); if (!thread) { error_log("cannot create thread:%d,%s\n", errno, errstring(errno)); return false; } thread->next = thread_pool; thread_pool = thread; return true; }
static int CopyPtr(lua_State *L) { hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_checkinteger(L, 2); size_t size = luaL_checkinteger(L, 3); void *ptr = checklightuserdata(L, 4); if(size == 0) return 0; if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); memcpy(hostmem->ptr + offset, ptr, size); return 0; }
static int WriteData(lua_State *L) { size_t size; hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_checkinteger(L, 2); /* arg 3 should be nil */ const char *data = luaL_checklstring(L, 4, &size); if(size == 0) return 0; if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); memcpy(hostmem->ptr + offset, data, size); return 0; }
static int CreateAllocated(lua_State *L, char *ptr, size_t size) { ud_t *ud; hostmem_t* hostmem; hostmem = (hostmem_t*)MallocNoErr(L, sizeof(hostmem_t)); if(!hostmem) { free(ptr); return luaL_error(L, errstring(ERR_MEMORY)); } hostmem->ptr = ptr; hostmem->size = size; ud = newhostmem(L, hostmem); MarkAllocated(ud); return 1; }
static int Read(lua_State *L) { int type; hostmem_t* hostmem = checkhostmem(L, 1, NULL); size_t offset = luaL_optinteger(L, 2, 0); size_t size = luaL_optinteger(L, 3, hostmem->size - offset); if((offset >= hostmem->size) || (size > hostmem->size - offset)) return luaL_error(L, errstring(ERR_BOUNDARIES)); if(lua_type(L, 4) == LUA_TSTRING) /* unpack according to 'type' */ { type = checktype(L, 4); if(size == 0) { lua_newtable(L); return 1; } return pushdata(L, type, hostmem->ptr + offset, size); } if(size == 0) lua_pushstring(L, ""); else lua_pushlstring(L, hostmem->ptr + offset, size); return 1; }
// log_error: log an error of the operation void log_error(DWORD id, BYTE code) { time_t result; result = time(NULL); write_log(1, "id:%d, error:%s, time:%s", id, errstring(code), ctime(&result)); }