| 1037 | */ |
| 1038 | |
| 1039 | LUA_API int lua_gc (lua_State *L, int what, int data) { |
| 1040 | int res = 0; |
| 1041 | global_State *g; |
| 1042 | lua_lock(L); |
| 1043 | g = G(L); |
| 1044 | switch (what) { |
| 1045 | case LUA_GCSTOP: { |
| 1046 | g->gcrunning = 0; |
| 1047 | break; |
| 1048 | } |
| 1049 | case LUA_GCRESTART: { |
| 1050 | luaE_setdebt(g, 0); |
| 1051 | g->gcrunning = 1; |
| 1052 | break; |
| 1053 | } |
| 1054 | case LUA_GCCOLLECT: { |
| 1055 | luaC_fullgc(L, 0); |
| 1056 | break; |
| 1057 | } |
| 1058 | case LUA_GCCOUNT: { |
| 1059 | /* GC values are expressed in Kbytes: #bytes/2^10 */ |
| 1060 | res = cast_int(gettotalbytes(g) >> 10); |
| 1061 | break; |
| 1062 | } |
| 1063 | case LUA_GCCOUNTB: { |
| 1064 | res = cast_int(gettotalbytes(g) & 0x3ff); |
| 1065 | break; |
| 1066 | } |
| 1067 | case LUA_GCSTEP: { |
| 1068 | l_mem debt = 1; /* =1 to signal that it did an actual step */ |
| 1069 | lu_byte oldrunning = g->gcrunning; |
| 1070 | g->gcrunning = 1; /* allow GC to run */ |
| 1071 | if (data == 0) { |
| 1072 | luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ |
| 1073 | luaC_step(L); |
| 1074 | } |
| 1075 | else { /* add 'data' to total debt */ |
| 1076 | debt = cast(l_mem, data) * 1024 + g->GCdebt; |
| 1077 | luaE_setdebt(g, debt); |
| 1078 | luaC_checkGC(L); |
| 1079 | } |
| 1080 | g->gcrunning = oldrunning; /* restore previous state */ |
| 1081 | if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ |
| 1082 | res = 1; /* signal it */ |
| 1083 | break; |
| 1084 | } |
| 1085 | case LUA_GCSETPAUSE: { |
| 1086 | res = g->gcpause; |
| 1087 | g->gcpause = data; |
| 1088 | break; |
| 1089 | } |
| 1090 | case LUA_GCSETSTEPMUL: { |
| 1091 | res = g->gcstepmul; |
| 1092 | if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */ |
| 1093 | g->gcstepmul = data; |
| 1094 | break; |
| 1095 | } |
| 1096 | case LUA_GCISRUNNING: { |
no test coverage detected