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 c7f578f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 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
2 changes: 1 addition & 1 deletion src/lj_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
if (sx->len == len && strncmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
Expand Down

0 comments on commit c7f578f

Please sign in to comment.