Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add profile module, and use it in snax
- Loading branch information
Showing
5 changed files
with
243 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
#include <lua.h> | ||
#include <lauxlib.h> | ||
|
||
|
||
#include <time.h> | ||
|
||
#if defined(__APPLE__) | ||
#include <mach/task.h> | ||
#include <mach/mach.h> | ||
#endif | ||
|
||
#define NANOSEC 1000000000 | ||
|
||
static double | ||
get_time() { | ||
#if !defined(__APPLE__) | ||
struct timespec ti; | ||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ti); | ||
|
||
int sec = ti.tv_sec & 0xffff; | ||
int nsec = ti.tv_nsec; | ||
|
||
return (double)sec + (double)nsec / 1000000000; | ||
#else | ||
struct task_thread_times_info aTaskInfo; | ||
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT; | ||
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount)); | ||
|
||
int sec = aTaskInfo.user_time.seconds & 0xffff; | ||
int msec = aTaskInfo.user_time.microseconds; | ||
|
||
return (double)sec + (double)msec / 1000000; | ||
#endif | ||
} | ||
|
||
static inline double | ||
diff_time(double start) { | ||
double now = get_time(); | ||
if (now < start) { | ||
return now + 0x10000 - start; | ||
} else { | ||
return now - start; | ||
} | ||
} | ||
|
||
static int | ||
lstart(lua_State *L) { | ||
lua_pushthread(L); | ||
lua_rawget(L, lua_upvalueindex(2)); | ||
if (!lua_isnil(L, -1)) { | ||
return luaL_error(L, "Thread %p start profile more than once", lua_topointer(L, 1)); | ||
} | ||
lua_pushthread(L); | ||
lua_pushnumber(L, 0); | ||
lua_rawset(L, lua_upvalueindex(2)); | ||
|
||
lua_pushthread(L); | ||
lua_pushnumber(L, get_time()); | ||
lua_rawset(L, lua_upvalueindex(1)); | ||
|
||
return 0; | ||
} | ||
|
||
static int | ||
lstop(lua_State *L) { | ||
lua_pushthread(L); | ||
lua_rawget(L, lua_upvalueindex(1)); | ||
luaL_checktype(L, -1, LUA_TNUMBER); | ||
double ti = diff_time(lua_tonumber(L, -1)); | ||
lua_pushthread(L); | ||
lua_rawget(L, lua_upvalueindex(2)); | ||
double total_time = lua_tonumber(L, -1); | ||
|
||
lua_pushthread(L); | ||
lua_pushnil(L); | ||
lua_rawset(L, lua_upvalueindex(1)); | ||
|
||
lua_pushthread(L); | ||
lua_pushnil(L); | ||
lua_rawset(L, lua_upvalueindex(2)); | ||
|
||
lua_pushnumber(L, ti + total_time); | ||
|
||
return 1; | ||
} | ||
|
||
static int | ||
lresume(lua_State *L) { | ||
lua_pushvalue(L,1); | ||
lua_rawget(L, lua_upvalueindex(2)); | ||
if (lua_isnil(L, -1)) { // check total time | ||
lua_pop(L,1); | ||
} else { | ||
lua_pop(L,1); | ||
lua_pushvalue(L,1); | ||
lua_pushnumber(L, get_time()); | ||
lua_rawset(L, lua_upvalueindex(1)); // set start time | ||
} | ||
|
||
lua_CFunction co_resume = lua_tocfunction(L, lua_upvalueindex(3)); | ||
|
||
return co_resume(L); | ||
} | ||
|
||
static int | ||
lyield(lua_State *L) { | ||
lua_pushthread(L); | ||
lua_rawget(L, lua_upvalueindex(2)); // check total time | ||
if (lua_isnil(L, -1)) { | ||
lua_pop(L,1); | ||
} else { | ||
double ti = lua_tonumber(L, -1); | ||
lua_pop(L,1); | ||
|
||
lua_pushthread(L); | ||
lua_rawget(L, lua_upvalueindex(1)); | ||
double starttime = lua_tonumber(L, -1); | ||
lua_pop(L,1); | ||
|
||
ti += diff_time(starttime); | ||
|
||
lua_pushthread(L); | ||
lua_pushnumber(L, ti); | ||
lua_rawset(L, lua_upvalueindex(1)); | ||
} | ||
|
||
lua_CFunction co_yield = lua_tocfunction(L, lua_upvalueindex(3)); | ||
|
||
return co_yield(L); | ||
} | ||
|
||
int | ||
luaopen_profile(lua_State *L) { | ||
luaL_checkversion(L); | ||
luaL_Reg l[] = { | ||
{ "start", lstart }, | ||
{ "stop", lstop }, | ||
{ "resume", lresume }, | ||
{ "yield", lyield }, | ||
{ NULL, NULL }, | ||
}; | ||
luaL_newlibtable(L,l); | ||
lua_newtable(L); // table thread->start time | ||
lua_newtable(L); // table thread->total time | ||
|
||
lua_newtable(L); // weak table | ||
lua_pushliteral(L, "kv"); | ||
lua_setfield(L, -2, "__mode"); | ||
|
||
lua_pushvalue(L, -1); | ||
lua_setmetatable(L, -3); | ||
lua_setmetatable(L, -3); | ||
|
||
lua_pushnil(L); | ||
luaL_setfuncs(L,l,3); | ||
|
||
int libtable = lua_gettop(L); | ||
|
||
lua_getglobal(L, "coroutine"); | ||
lua_getfield(L, -1, "resume"); | ||
|
||
lua_CFunction co_resume = lua_tocfunction(L, -1); | ||
if (co_resume == NULL) | ||
return luaL_error(L, "Can't get coroutine.resume"); | ||
lua_pop(L,1); | ||
lua_getfield(L, libtable, "resume"); | ||
lua_pushcfunction(L, co_resume); | ||
lua_setupvalue(L, -2, 3); | ||
lua_pop(L,1); | ||
|
||
lua_getfield(L, -1, "yield"); | ||
|
||
lua_CFunction co_yield = lua_tocfunction(L, -1); | ||
if (co_yield == NULL) | ||
return luaL_error(L, "Can't get coroutine.yield"); | ||
lua_pop(L,1); | ||
lua_getfield(L, libtable, "yield"); | ||
lua_pushcfunction(L, co_yield); | ||
lua_setupvalue(L, -2, 3); | ||
|
||
lua_settop(L, libtable); | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters