Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/lj_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,59 @@ LUA_API int lua_resume(lua_State *L, int nargs)

/* -- GC and memory management -------------------------------------------- */

#if LJ_TARGET_WINDOWS
static uint64_t gc_get_ns(void)
{
LARGE_INTEGER pf, pc;
uint64_t tv_sec, tv_nsec;

if (!QueryPerformanceFrequency(&pf) || !QueryPerformanceCounter(&pc))
return 0;

tv_sec = pc.QuadPart / pf.QuadPart;
tv_nsec = ((pc.QuadPart % pf.QuadPart) * 1000000000ULL + (pf.QuadPart >> 1)) / pf.QuadPart;

return 1000000000ULL * tv_sec + tv_nsec;
}
#elif LJ_TARGET_POSIX
#include <time.h>

static uint64_t gc_get_ns(void)
{
struct timespec ts;

#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
#else
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif

return 1000000000ULL * ts.tv_sec + ts.tv_nsec;
}
#endif

static int gc_step_timeout(lua_State *L, uint32_t timeout_usec)
{
#if LJ_TARGET_WINDOWS || LJ_TARGET_POSIX
int res = 0;
uint64_t timeout = timeout_usec * 1000;
uint64_t time_current = gc_get_ns();

timeout += time_current;
while (time_current < timeout) {
if (lj_gc_step(L) > 0) {
res = 1;
break;
}

time_current = gc_get_ns();
}
return res;
#else
return -1;
#endif
}

LUA_API int lua_gc(lua_State *L, int what, int data)
{
global_State *g = G(L);
Expand Down Expand Up @@ -1300,6 +1353,11 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
}
break;
}
case LUA_GCTIMEOUT:
res = gc_step_timeout(L, (uint32_t)data);
if (res >= 0)
g->gc.threshold = LJ_MAX_MEM;
break;
case LUA_GCSETPAUSE:
res = (int)(g->gc.pause);
g->gc.pause = (MSize)data;
Expand Down
1 change: 1 addition & 0 deletions src/lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ LUA_API int (lua_status) (lua_State *L);
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
#define LUA_GCISRUNNING 9
#define LUA_GCTIMEOUT 10

LUA_API int (lua_gc) (lua_State *L, int what, int data);

Expand Down