aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-04-11 15:14:52 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-04-11 15:14:52 +0200
commitadaa36dbec1ce9aaafd61873b9d3d898a8c240cf (patch)
tree4c81e8f5983c3d696a636e2cc433ce7c0a9c3dd8 /src/lanes.c
parent1d310e6ecb6e156598337612f16573d9cd284f5e (diff)
downloadlanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.gz
lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.bz2
lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.zip
Bring all interesting fixes from the C++ implementation back into the C implementation
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c115
1 files changed, 60 insertions, 55 deletions
diff --git a/src/lanes.c b/src/lanes.c
index 332a1b8..ca2b53a 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -442,7 +442,7 @@ static bool_t selfdestruct_remove( Lane* s)
442/* 442/*
443* Process end; cancel any still free-running threads 443* Process end; cancel any still free-running threads
444*/ 444*/
445static int selfdestruct_gc( lua_State* L) 445static int universe_gc( lua_State* L)
446{ 446{
447 Universe* U = (Universe*) lua_touserdata( L, 1); 447 Universe* U = (Universe*) lua_touserdata( L, 1);
448 448
@@ -456,7 +456,7 @@ static int selfdestruct_gc( lua_State* L)
456 while( s != SELFDESTRUCT_END) 456 while( s != SELFDESTRUCT_END)
457 { 457 {
458 // attempt a regular unforced hard cancel with a small timeout 458 // attempt a regular unforced hard cancel with a small timeout
459 bool_t cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, CO_Hard, 0.0001, FALSE, 0.0); 459 bool_t cancelled = THREAD_ISNULL( s->thread) || (thread_cancel( L, s, CO_Hard, 0.0001, FALSE, 0.0) != CR_Timeout);
460 // if we failed, and we know the thread is waiting on a linda 460 // if we failed, and we know the thread is waiting on a linda
461 if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL) 461 if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL)
462 { 462 {
@@ -609,7 +609,7 @@ static int selfdestruct_gc( lua_State* L)
609// 609//
610LUAG_FUNC( set_singlethreaded) 610LUAG_FUNC( set_singlethreaded)
611{ 611{
612 uint_t cores = luaG_optunsigned( L, 1, 1); 612 lua_Integer cores = luaG_optunsigned( L, 1, 1);
613 (void) cores; // prevent "unused" warning 613 (void) cores; // prevent "unused" warning
614 614
615#ifdef PLATFORM_OSX 615#ifdef PLATFORM_OSX
@@ -653,24 +653,16 @@ static DECLARE_CONST_UNIQUE_KEY( EXTENDED_STACKTRACE_REGKEY, 0x2357c69a7c92c936)
653 653
654LUAG_FUNC( set_error_reporting) 654LUAG_FUNC( set_error_reporting)
655{ 655{
656 bool_t equal; 656 luaL_checktype(L, 1, LUA_TSTRING);
657 luaL_checktype( L, 1, LUA_TSTRING); 657 char const* mode = lua_tostring(L, 1);
658 lua_pushliteral( L, "extended"); 658 bool_t const extended = (strcmp(mode, "extended") == 0);
659 equal = lua_rawequal( L, -1, 1); 659 bool_t const basic = (strcmp(mode, "basic") == 0);
660 lua_pop( L, 1); 660 if (!extended && !basic)
661 if( equal)
662 { 661 {
663 goto done; 662 return luaL_error(L, "unsupported error reporting model %s", mode);
664 } 663 }
665 lua_pushliteral( L, "basic"); 664
666 equal = !lua_rawequal( L, -1, 1); 665 REGISTRY_SET( L, EXTENDED_STACKTRACE_REGKEY, lua_pushboolean( L, extended ? 1 : 0));
667 lua_pop( L, 1);
668 if( equal)
669 {
670 return luaL_error( L, "unsupported error reporting model");
671 }
672done:
673 REGISTRY_SET( L, EXTENDED_STACKTRACE_REGKEY, lua_pushboolean( L, equal));
674 return 0; 666 return 0;
675} 667}
676 668
@@ -788,7 +780,8 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
788 780
789LUAG_FUNC( set_debug_threadname) 781LUAG_FUNC( set_debug_threadname)
790{ 782{
791 DECLARE_CONST_UNIQUE_KEY( hidden_regkey, LG_set_debug_threadname); 783 // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator
784 static DECLARE_CONST_UNIQUE_KEY( hidden_regkey, 0x79C0669AAAE04440);
792 // C s_lane structure is a light userdata upvalue 785 // C s_lane structure is a light userdata upvalue
793 Lane* s = lua_touserdata( L, lua_upvalueindex( 1)); 786 Lane* s = lua_touserdata( L, lua_upvalueindex( 1));
794 luaL_checktype( L, -1, LUA_TSTRING); // "name" 787 luaL_checktype( L, -1, LUA_TSTRING); // "name"
@@ -1049,10 +1042,10 @@ LUAG_FUNC( lane_new)
1049 char const* libs_str = lua_tostring( L, 2); 1042 char const* libs_str = lua_tostring( L, 2);
1050 bool_t const have_priority = !lua_isnoneornil( L, 3); 1043 bool_t const have_priority = !lua_isnoneornil( L, 3);
1051 int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT; 1044 int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT;
1052 uint_t const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; 1045 int const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4;
1053 uint_t const package_idx = lua_isnoneornil( L, 5) ? 0 : 5; 1046 int const package_idx = lua_isnoneornil( L, 5) ? 0 : 5;
1054 uint_t const required_idx = lua_isnoneornil( L, 6) ? 0 : 6; 1047 int const required_idx = lua_isnoneornil( L, 6) ? 0 : 6;
1055 uint_t const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; 1048 int const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7;
1056 1049
1057#define FIXED_ARGS 7 1050#define FIXED_ARGS 7
1058 int const nargs = lua_gettop(L) - FIXED_ARGS; 1051 int const nargs = lua_gettop(L) - FIXED_ARGS;
@@ -1090,7 +1083,8 @@ LUAG_FUNC( lane_new)
1090 if( package_idx != 0) 1083 if( package_idx != 0)
1091 { 1084 {
1092 // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack 1085 // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack
1093 (void) luaG_inter_copy_package( U, L, L2, package_idx, eLM_LaneBody); 1086 InterCopyResult const ret = luaG_inter_copy_package( U, L, L2, package_idx, eLM_LaneBody);
1087 ASSERT_L(ret == eICR_Success); // either all went well, or we should not even get here
1094 } 1088 }
1095 1089
1096 // modules to require in the target lane *before* the function is transfered! 1090 // modules to require in the target lane *before* the function is transfered!
@@ -1179,25 +1173,32 @@ LUAG_FUNC( lane_new)
1179 STACK_MID( L2, 0); 1173 STACK_MID( L2, 0);
1180 1174
1181 // Lane main function 1175 // Lane main function
1182 if( lua_type( L, 1) == LUA_TFUNCTION)
1183 { 1176 {
1184 int res; 1177 int const func_type = lua_type(L, 1);
1185 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); 1178 if (func_type == LUA_TFUNCTION)
1186 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1187 lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func
1188 res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func
1189 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1190 if( res != 0)
1191 { 1179 {
1192 return luaL_error( L, "tried to copy unsupported types"); 1180 InterCopyResult res;
1181 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END));
1182 DEBUGSPEW_CODE(++U->debugspew_indent_depth);
1183 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func
1184 res = luaG_inter_move(U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func
1185 DEBUGSPEW_CODE(--U->debugspew_indent_depth);
1186 if (res != eICR_Success)
1187 {
1188 return luaL_error(L, "tried to copy unsupported types");
1189 }
1193 } 1190 }
1194 } 1191 else if (func_type == LUA_TSTRING)
1195 else if( lua_type( L, 1) == LUA_TSTRING)
1196 {
1197 // compile the string
1198 if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func
1199 { 1192 {
1200 return luaL_error( L, "error when parsing lane function code"); 1193 // compile the string
1194 if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func
1195 {
1196 return luaL_error(L, "error when parsing lane function code");
1197 }
1198 }
1199 else
1200 {
1201 luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); // doesn't return
1201 } 1202 }
1202 } 1203 }
1203 STACK_MID( L, 0); 1204 STACK_MID( L, 0);
@@ -1207,12 +1208,12 @@ LUAG_FUNC( lane_new)
1207 // revive arguments 1208 // revive arguments
1208 if( nargs > 0) 1209 if( nargs > 0)
1209 { 1210 {
1210 int res; 1211 InterCopyResult res;
1211 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); 1212 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END));
1212 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1213 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1213 res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] 1214 res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...]
1214 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1215 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1215 if( res != 0) 1216 if( res != eICR_Success)
1216 { 1217 {
1217 return luaL_error( L, "tried to copy unsupported types"); 1218 return luaL_error( L, "tried to copy unsupported types");
1218 } 1219 }
@@ -1277,7 +1278,7 @@ LUAG_FUNC( lane_new)
1277 lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane 1278 lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane
1278 1279
1279 // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 1280 // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1280 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] 1281 REGISTRY_SET( L2, LANE_POINTER_REGKEY, lua_pushlightuserdata( L2, s)); // func [... args ...]
1281 1282
1282 STACK_END( L, 1); 1283 STACK_END( L, 1);
1283 STACK_END( L2, 1 + nargs); 1284 STACK_END( L2, 1 + nargs);
@@ -1457,8 +1458,8 @@ LUAG_FUNC( thread_join)
1457 { 1458 {
1458 case DONE: 1459 case DONE:
1459 { 1460 {
1460 uint_t n = lua_gettop( L2); // whole L2 stack 1461 int n = lua_gettop( L2); // whole L2 stack
1461 if( (n > 0) && (luaG_inter_move( U, L2, L, n, eLM_LaneBody) != 0)) 1462 if( (n > 0) && (luaG_inter_move( U, L2, L, n, eLM_LaneBody) != eICR_Success))
1462 { 1463 {
1463 return luaL_error( L, "tried to copy unsupported types"); 1464 return luaL_error( L, "tried to copy unsupported types");
1464 } 1465 }
@@ -1472,7 +1473,7 @@ LUAG_FUNC( thread_join)
1472 STACK_GROW( L, 3); 1473 STACK_GROW( L, 3);
1473 lua_pushnil( L); 1474 lua_pushnil( L);
1474 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... 1475 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ...
1475 if( luaG_inter_move( U, L2, L, n, eLM_LaneBody) != 0) // nil "err" [trace] 1476 if( luaG_inter_move( U, L2, L, n, eLM_LaneBody) != eICR_Success) // nil "err" [trace]
1476 { 1477 {
1477 return luaL_error( L, "tried to copy unsupported types: %s", lua_tostring( L, -n)); 1478 return luaL_error( L, "tried to copy unsupported types: %s", lua_tostring( L, -n));
1478 } 1479 }
@@ -1874,7 +1875,7 @@ LUAG_FUNC( configure)
1874 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1875 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1875 lua_newtable( L); // settings universe mt 1876 lua_newtable( L); // settings universe mt
1876 lua_getfield( L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout 1877 lua_getfield( L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout
1877 lua_pushcclosure( L, selfdestruct_gc, 1); // settings universe mt selfdestruct_gc 1878 lua_pushcclosure( L, universe_gc, 1); // settings universe mt universe_gc
1878 lua_setfield( L, -2, "__gc"); // settings universe mt 1879 lua_setfield( L, -2, "__gc"); // settings universe mt
1879 lua_setmetatable( L, -2); // settings universe 1880 lua_setmetatable( L, -2); // settings universe
1880 lua_pop( L, 1); // settings 1881 lua_pop( L, 1); // settings
@@ -2051,16 +2052,20 @@ static void EnableCrashingOnCrashes( void)
2051 const DWORD EXCEPTION_SWALLOWING = 0x1; 2052 const DWORD EXCEPTION_SWALLOWING = 0x1;
2052 2053
2053 HMODULE kernel32 = LoadLibraryA("kernel32.dll"); 2054 HMODULE kernel32 = LoadLibraryA("kernel32.dll");
2054 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); 2055 if (kernel32)
2055 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
2056 if( pGetPolicy && pSetPolicy)
2057 { 2056 {
2058 DWORD dwFlags; 2057 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy");
2059 if( pGetPolicy( &dwFlags)) 2058 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
2059 if( pGetPolicy && pSetPolicy)
2060 { 2060 {
2061 // Turn off the filter 2061 DWORD dwFlags;
2062 pSetPolicy( dwFlags & ~EXCEPTION_SWALLOWING); 2062 if( pGetPolicy( &dwFlags))
2063 {
2064 // Turn off the filter
2065 pSetPolicy( dwFlags & ~EXCEPTION_SWALLOWING);
2066 }
2063 } 2067 }
2068 FreeLibrary(kernel32);
2064 } 2069 }
2065 //typedef void (* SignalHandlerPointer)( int); 2070 //typedef void (* SignalHandlerPointer)( int);
2066 /*SignalHandlerPointer previousHandler =*/ signal( SIGABRT, signal_handler); 2071 /*SignalHandlerPointer previousHandler =*/ signal( SIGABRT, signal_handler);
@@ -2072,7 +2077,7 @@ static void EnableCrashingOnCrashes( void)
2072 while( !s_ecoc_go_ahead) { Sleep(1); } // changes threads 2077 while( !s_ecoc_go_ahead) { Sleep(1); } // changes threads
2073 } 2078 }
2074} 2079}
2075#endif // PLATFORM_WIN32 2080#endif // PLATFORM_WIN32 && !defined NDEBUG
2076 2081
2077int LANES_API luaopen_lanes_core( lua_State* L) 2082int LANES_API luaopen_lanes_core( lua_State* L)
2078{ 2083{