Skip to content

Commit

Permalink
[GC] Added option to collect garbage before timeout expires
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleivg committed Jun 11, 2022
1 parent 421a871 commit 4bd3610
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
66 changes: 64 additions & 2 deletions src/lj_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,63 @@
#include "lj_strscan.h"
#include "lj_strfmt.h"

#include <time.h>
#if LJ_TARGET_POSIX
#include <sys/time.h>
#elif LJ_TARGET_WINDOWS
#define timercmp(a, b, CMP) \
(((a)->tv_sec == (b)->tv_sec) ? \
((a)->tv_nsec CMP (b)->tv_nsec) : \
((a)->tv_sec CMP (b)->tv_sec))
#define timeradd(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \
if ((result)->tv_nsec >= 1000000000) \
{ \
++(result)->tv_sec; \
(result)->tv_nsec -= 1000000000; \
} \
} while (0)
#endif

static void gc_step_timeout(lua_State *L, uint32_t timeout_usec)
{
#if LJ_TARGET_POSIX
struct timeval tv_timeout;
tv_timeout.tv_sec = 0;
tv_timeout.tv_usec = timeout_usec;

struct timeval tv_current;
gettimeofday(&tv_current, NULL);

timeradd(&tv_current, &tv_timeout, &tv_timeout);
while (timercmp(&tv_current, &tv_timeout, <)) {
if (lj_gc_step(L) > 0) {
break;
}

gettimeofday(&tv_current, NULL);
}
#elif LJ_TARGET_WINDOWS
struct timespec tv_timeout;
tv_timeout.tv_sec = 0;
tv_timeout.tv_nsec = timeout_usec * 1000;

struct timespec tv_current;
timespec_get(&tv_current, TIME_UTC);

timeradd(&tv_current, &tv_timeout, &tv_timeout);
while (timercmp(&tv_current, &tv_timeout, < )) {
if (lj_gc_step(L) > 0) {
break;
}

timespec_get(&tv_current, TIME_UTC);
}
#endif
}

/* -- Common helper functions --------------------------------------------- */

#define lj_checkapi_slot(idx) \
Expand Down Expand Up @@ -1299,11 +1356,16 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
while (g->gc.total >= g->gc.threshold)
if (lj_gc_step(L) > 0) {
res = 1;
break;
res = 1;
break;
}
break;
}
case LUA_GCTIMEOUT: {
gc_step_timeout(L, (uint32_t)data);
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 @@ -228,6 +228,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

0 comments on commit 4bd3610

Please sign in to comment.