mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 03:53:09 +00:00
Update to lua 5.4 (#1174)
* update to lua 5.4.0-rc1 * remove LUA_ERRGCMM * use age bits for shared * remove unused lbitlib.c * use luaV_fastget * fix #1174 * suspend函数tailcall优化 * 防止没有session导致未调用suspend * luaH_setint check shared (#1184) * set LUA_GCGEN by default * fix #1174 (#1186) checkshared in sweeplist * update to lua 5.4 rc2 * update to lua 5.4 rc4 * move skynet.profile into snlua * Use lua_sethook to interrupt tight loops * remove lua_checksig * critical condition for signals * update to lua 5.4 released * lua 5.4 bugfix * update lua bugfix * fix lua_sharestring (#1224) * update lua * update lua 5.4 * update README * add skynet.select * add test * test error & discard * yield session * request error has no error message * add timeout to skynet.select * bugfix * for lua 5.4 * new version * bugfix * bugfix * use if instead of while * make local * yield in select for * update lua 5.4.1 * change lua version (#1245) Co-authored-by: xiaojin <xiaojin@onemt.com.cn> * update lua version number Co-authored-by: hong <hongling0@gmail.com> Co-authored-by: hong <hongling-0@qq.com> Co-authored-by: 风---自由 <996442717qqcom@gmail.com> Co-authored-by: xiaojin <xiaojin@onemt.com.cn>
This commit is contained in:
@@ -1,269 +0,0 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <stdio.h>
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach/task.h>
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
#define NANOSEC 1000000000
|
||||
#define MICROSEC 1000000
|
||||
|
||||
// #define DEBUG_LOG
|
||||
|
||||
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 / NANOSEC;
|
||||
#else
|
||||
struct task_thread_times_info aTaskInfo;
|
||||
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
|
||||
if (KERN_SUCCESS != task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sec = aTaskInfo.user_time.seconds & 0xffff;
|
||||
int msec = aTaskInfo.user_time.microseconds;
|
||||
|
||||
return (double)sec + (double)msec / MICROSEC;
|
||||
#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) {
|
||||
if (lua_gettop(L) != 0) {
|
||||
lua_settop(L,1);
|
||||
luaL_checktype(L, 1, LUA_TTHREAD);
|
||||
} else {
|
||||
lua_pushthread(L);
|
||||
}
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
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_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnumber(L, 0);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
double ti = get_time();
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] start\n", L);
|
||||
#endif
|
||||
lua_pushnumber(L, ti);
|
||||
lua_rawset(L, lua_upvalueindex(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lstop(lua_State *L) {
|
||||
if (lua_gettop(L) != 0) {
|
||||
lua_settop(L,1);
|
||||
luaL_checktype(L, 1, LUA_TTHREAD);
|
||||
} else {
|
||||
lua_pushthread(L);
|
||||
}
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
if (lua_type(L, -1) != LUA_TNUMBER) {
|
||||
return luaL_error(L, "Call profile.start() before profile.stop()");
|
||||
}
|
||||
double ti = diff_time(lua_tonumber(L, -1));
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(2));
|
||||
double total_time = lua_tonumber(L, -1);
|
||||
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, lua_upvalueindex(1));
|
||||
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
|
||||
total_time += ti;
|
||||
lua_pushnumber(L, total_time);
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] stop (%lf/%lf)\n", lua_tothread(L,1), ti, total_time);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
timing_resume(lua_State *L) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, lua_upvalueindex(2));
|
||||
if (lua_isnil(L, -1)) { // check total time
|
||||
lua_pop(L,2); // pop from coroutine
|
||||
} else {
|
||||
lua_pop(L,1);
|
||||
double ti = get_time();
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] resume %lf\n", lua_tothread(L, -1), ti);
|
||||
#endif
|
||||
lua_pushnumber(L, ti);
|
||||
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
|
||||
lresume(lua_State *L) {
|
||||
lua_pushvalue(L,1);
|
||||
|
||||
return timing_resume(L);
|
||||
}
|
||||
|
||||
static int
|
||||
lresume_co(lua_State *L) {
|
||||
luaL_checktype(L, 2, LUA_TTHREAD);
|
||||
lua_rotate(L, 2, -1); // 'from' coroutine rotate to the top(index -1)
|
||||
|
||||
return timing_resume(L);
|
||||
}
|
||||
|
||||
static int
|
||||
timing_yield(lua_State *L) {
|
||||
#ifdef DEBUG_LOG
|
||||
lua_State *from = lua_tothread(L, -1);
|
||||
#endif
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, lua_upvalueindex(2)); // check total time
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L,2);
|
||||
} else {
|
||||
double ti = lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
|
||||
lua_pushvalue(L, -1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
double starttime = lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
|
||||
double diff = diff_time(starttime);
|
||||
ti += diff;
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] yield (%lf/%lf)\n", from, diff, ti);
|
||||
#endif
|
||||
|
||||
lua_pushvalue(L, -1); // push coroutine
|
||||
lua_pushnumber(L, ti);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
lua_pop(L, 1); // pop coroutine
|
||||
}
|
||||
|
||||
lua_CFunction co_yield = lua_tocfunction(L, lua_upvalueindex(3));
|
||||
|
||||
return co_yield(L);
|
||||
}
|
||||
|
||||
static int
|
||||
lyield(lua_State *L) {
|
||||
lua_pushthread(L);
|
||||
|
||||
return timing_yield(L);
|
||||
}
|
||||
|
||||
static int
|
||||
lyield_co(lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTHREAD);
|
||||
lua_rotate(L, 1, -1);
|
||||
|
||||
return timing_yield(L);
|
||||
}
|
||||
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_profile(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] = {
|
||||
{ "start", lstart },
|
||||
{ "stop", lstop },
|
||||
{ "resume", lresume },
|
||||
{ "yield", lyield },
|
||||
{ "resume_co", lresume_co },
|
||||
{ "yield_co", lyield_co },
|
||||
{ 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); // cfunction (coroutine.resume or coroutine.yield)
|
||||
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, libtable, "resume_co");
|
||||
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_pop(L,1);
|
||||
|
||||
lua_getfield(L, libtable, "yield_co");
|
||||
lua_pushcfunction(L, co_yield);
|
||||
lua_setupvalue(L, -2, 3);
|
||||
lua_pop(L,1);
|
||||
|
||||
lua_settop(L, libtable);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -88,9 +88,6 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
|
||||
case LUA_ERRERR:
|
||||
skynet_error(context, "lua error in error : [%x to %s : %d]", source , self, session);
|
||||
break;
|
||||
case LUA_ERRGCMM:
|
||||
skynet_error(context, "lua gc error : [%x to %s : %d]", source , self, session);
|
||||
break;
|
||||
};
|
||||
|
||||
lua_pop(L,1);
|
||||
|
||||
Reference in New Issue
Block a user