diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lanes.c | 77 | ||||
| -rw-r--r-- | src/threading.c | 137 | ||||
| -rw-r--r-- | src/threading.h | 4 |
3 files changed, 116 insertions, 102 deletions
diff --git a/src/lanes.c b/src/lanes.c index cd1d4f1..9f6a4d6 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
| @@ -1052,21 +1052,22 @@ LUAG_FUNC( lane_new) | |||
| 1052 | Lane** ud; | 1052 | Lane** ud; |
| 1053 | 1053 | ||
| 1054 | char const* libs_str = lua_tostring( L, 2); | 1054 | char const* libs_str = lua_tostring( L, 2); |
| 1055 | int const priority = (int) luaL_optinteger( L, 3, 0); | 1055 | bool_t const have_priority = !lua_isnoneornil( L, 3); |
| 1056 | uint_t globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; | 1056 | int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT; |
| 1057 | uint_t package_idx = lua_isnoneornil( L, 5) ? 0 : 5; | 1057 | uint_t const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; |
| 1058 | uint_t required_idx = lua_isnoneornil( L, 6) ? 0 : 6; | 1058 | uint_t const package_idx = lua_isnoneornil( L, 5) ? 0 : 5; |
| 1059 | uint_t gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; | 1059 | uint_t const required_idx = lua_isnoneornil( L, 6) ? 0 : 6; |
| 1060 | uint_t const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; | ||
| 1060 | 1061 | ||
| 1061 | #define FIXED_ARGS 7 | 1062 | #define FIXED_ARGS 7 |
| 1062 | int const nargs = lua_gettop(L) - FIXED_ARGS; | 1063 | int const nargs = lua_gettop(L) - FIXED_ARGS; |
| 1063 | Universe* U = universe_get( L); | 1064 | Universe* const U = universe_get( L); |
| 1064 | ASSERT_L( nargs >= 0); | 1065 | ASSERT_L( nargs >= 0); |
| 1065 | 1066 | ||
| 1066 | // public Lanes API accepts a generic range -3/+3 | 1067 | // public Lanes API accepts a generic range -3/+3 |
| 1067 | // that will be remapped into the platform-specific scheduler priority scheme | 1068 | // that will be remapped into the platform-specific scheduler priority scheme |
| 1068 | // On some platforms, -3 is equivalent to -2 and +3 to +2 | 1069 | // On some platforms, -3 is equivalent to -2 and +3 to +2 |
| 1069 | if( priority < THREAD_PRIO_MIN || priority > THREAD_PRIO_MAX) | 1070 | if( have_priority && (priority < THREAD_PRIO_MIN || priority > THREAD_PRIO_MAX)) |
| 1070 | { | 1071 | { |
| 1071 | return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, priority); | 1072 | return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, priority); |
| 1072 | } | 1073 | } |
| @@ -1076,12 +1077,12 @@ LUAG_FUNC( lane_new) | |||
| 1076 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1077 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 1077 | 1078 | ||
| 1078 | // populate with selected libraries at the same time | 1079 | // populate with selected libraries at the same time |
| 1079 | L2 = luaG_newstate( U, L, libs_str); // L // L2 | 1080 | L2 = luaG_newstate( U, L, libs_str); // L // L2 |
| 1080 | 1081 | ||
| 1081 | STACK_GROW( L2, nargs + 3); // | 1082 | STACK_GROW( L2, nargs + 3); // |
| 1082 | STACK_CHECK( L2, 0); | 1083 | STACK_CHECK( L2, 0); |
| 1083 | 1084 | ||
| 1084 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] | 1085 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] |
| 1085 | STACK_CHECK( L, 0); | 1086 | STACK_CHECK( L, 0); |
| 1086 | 1087 | ||
| 1087 | // give a default "Lua" name to the thread to see VM name in Decoda debugger | 1088 | // give a default "Lua" name to the thread to see VM name in Decoda debugger |
| @@ -1110,8 +1111,8 @@ LUAG_FUNC( lane_new) | |||
| 1110 | return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx)); | 1111 | return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx)); |
| 1111 | } | 1112 | } |
| 1112 | 1113 | ||
| 1113 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil | 1114 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil |
| 1114 | while( lua_next( L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" | 1115 | while( lua_next( L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" |
| 1115 | { | 1116 | { |
| 1116 | if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) | 1117 | if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) |
| 1117 | { | 1118 | { |
| @@ -1125,29 +1126,29 @@ LUAG_FUNC( lane_new) | |||
| 1125 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); | 1126 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); |
| 1126 | 1127 | ||
| 1127 | // require the module in the target lane | 1128 | // require the module in the target lane |
| 1128 | lua_getglobal( L2, "require"); // require()? | 1129 | lua_getglobal( L2, "require"); // require()? |
| 1129 | if( lua_isnil( L2, -1)) | 1130 | if( lua_isnil( L2, -1)) |
| 1130 | { | 1131 | { |
| 1131 | lua_pop( L2, 1); // | 1132 | lua_pop( L2, 1); // |
| 1132 | luaL_error( L, "cannot pre-require modules without loading 'package' library first"); | 1133 | luaL_error( L, "cannot pre-require modules without loading 'package' library first"); |
| 1133 | } | 1134 | } |
| 1134 | else | 1135 | else |
| 1135 | { | 1136 | { |
| 1136 | lua_pushlstring( L2, name, len); // require() name | 1137 | lua_pushlstring( L2, name, len); // require() name |
| 1137 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode | 1138 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode |
| 1138 | { | 1139 | { |
| 1139 | // propagate error to main state if any | 1140 | // propagate error to main state if any |
| 1140 | luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error | 1141 | luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error |
| 1141 | return lua_error( L); | 1142 | return lua_error( L); |
| 1142 | } | 1143 | } |
| 1143 | // after requiring the module, register the functions it exported in our name<->function database | 1144 | // after requiring the module, register the functions it exported in our name<->function database |
| 1144 | populate_func_lookup_table( L2, -1, name); | 1145 | populate_func_lookup_table( L2, -1, name); |
| 1145 | lua_pop( L2, 1); // | 1146 | lua_pop( L2, 1); // |
| 1146 | } | 1147 | } |
| 1147 | } | 1148 | } |
| 1148 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] n | 1149 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] n |
| 1149 | ++ nbRequired; | 1150 | ++ nbRequired; |
| 1150 | } // func libs priority globals package required gc_cb [... args ...] | 1151 | } // func libs priority globals package required gc_cb [... args ...] |
| 1151 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1152 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1152 | } | 1153 | } |
| 1153 | STACK_MID( L, 0); | 1154 | STACK_MID( L, 0); |
| @@ -1165,17 +1166,17 @@ LUAG_FUNC( lane_new) | |||
| 1165 | } | 1166 | } |
| 1166 | 1167 | ||
| 1167 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1168 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 1168 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil | 1169 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil |
| 1169 | // Lua 5.2 wants us to push the globals table on the stack | 1170 | // Lua 5.2 wants us to push the globals table on the stack |
| 1170 | lua_pushglobaltable( L2); // _G | 1171 | lua_pushglobaltable( L2); // _G |
| 1171 | while( lua_next( L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v | 1172 | while( lua_next( L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v |
| 1172 | { | 1173 | { |
| 1173 | luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v | 1174 | luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v |
| 1174 | // assign it in L2's globals table | 1175 | // assign it in L2's globals table |
| 1175 | lua_rawset( L2, -3); // _G | 1176 | lua_rawset( L2, -3); // _G |
| 1176 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] k | 1177 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] k |
| 1177 | } // func libs priority globals package required gc_cb [... args ...] | 1178 | } // func libs priority globals package required gc_cb [... args ...] |
| 1178 | lua_pop( L2, 1); // | 1179 | lua_pop( L2, 1); // |
| 1179 | 1180 | ||
| 1180 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1181 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1181 | } | 1182 | } |
| @@ -1188,8 +1189,8 @@ LUAG_FUNC( lane_new) | |||
| 1188 | int res; | 1189 | int res; |
| 1189 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); | 1190 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); |
| 1190 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1191 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 1191 | lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func | 1192 | lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func |
| 1192 | res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func | 1193 | res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func |
| 1193 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1194 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1194 | if( res != 0) | 1195 | if( res != 0) |
| 1195 | { | 1196 | { |
| @@ -1199,7 +1200,7 @@ LUAG_FUNC( lane_new) | |||
| 1199 | else if( lua_type( L, 1) == LUA_TSTRING) | 1200 | else if( lua_type( L, 1) == LUA_TSTRING) |
| 1200 | { | 1201 | { |
| 1201 | // compile the string | 1202 | // compile the string |
| 1202 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func | 1203 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func |
| 1203 | { | 1204 | { |
| 1204 | return luaL_error( L, "error when parsing lane function code"); | 1205 | return luaL_error( L, "error when parsing lane function code"); |
| 1205 | } | 1206 | } |
| @@ -1214,7 +1215,7 @@ LUAG_FUNC( lane_new) | |||
| 1214 | int res; | 1215 | int res; |
| 1215 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); | 1216 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); |
| 1216 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1217 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 1217 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] | 1218 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] |
| 1218 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1219 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1219 | if( res != 0) | 1220 | if( res != 0) |
| 1220 | { | 1221 | { |
| @@ -1267,23 +1268,23 @@ LUAG_FUNC( lane_new) | |||
| 1267 | 1268 | ||
| 1268 | // Set metatable for the userdata | 1269 | // Set metatable for the userdata |
| 1269 | // | 1270 | // |
| 1270 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt | 1271 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt |
| 1271 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane | 1272 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane |
| 1272 | STACK_MID( L, 1); | 1273 | STACK_MID( L, 1); |
| 1273 | 1274 | ||
| 1274 | // Create uservalue for the userdata | 1275 | // Create uservalue for the userdata |
| 1275 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) | 1276 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) |
| 1276 | lua_newtable( L); // func libs cancelstep priority globals package required gc_cb lane uv | 1277 | lua_newtable( L); // func libs cancelstep priority globals package required gc_cb lane uv |
| 1277 | 1278 | ||
| 1278 | // Store the gc_cb callback in the uservalue | 1279 | // Store the gc_cb callback in the uservalue |
| 1279 | if( gc_cb_idx > 0) | 1280 | if( gc_cb_idx > 0) |
| 1280 | { | 1281 | { |
| 1281 | push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k | 1282 | push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k |
| 1282 | lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb | 1283 | lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb |
| 1283 | lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv | 1284 | lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv |
| 1284 | } | 1285 | } |
| 1285 | 1286 | ||
| 1286 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane | 1287 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane |
| 1287 | 1288 | ||
| 1288 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). | 1289 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). |
| 1289 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] | 1290 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] |
diff --git a/src/threading.c b/src/threading.c index 183dc87..2b68503 100644 --- a/src/threading.c +++ b/src/threading.c | |||
| @@ -323,9 +323,12 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (__stdcall *func)( void*), vo | |||
| 323 | FAIL( "CreateThread", GetLastError()); | 323 | FAIL( "CreateThread", GetLastError()); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | if (!SetThreadPriority( h, gs_prio_remap[prio + 3])) | 326 | if (prio != THREAD_PRIO_DEFAULT) |
| 327 | { | 327 | { |
| 328 | FAIL( "SetThreadPriority", GetLastError()); | 328 | if (!SetThreadPriority( h, gs_prio_remap[prio + 3])) |
| 329 | { | ||
| 330 | FAIL( "SetThreadPriority", GetLastError()); | ||
| 331 | } | ||
| 329 | } | 332 | } |
| 330 | 333 | ||
| 331 | *ref = h; | 334 | *ref = h; |
| @@ -681,7 +684,7 @@ static int const gs_prio_remap[] = | |||
| 681 | // least OS specific settings. Hopefully, Linuxes and OS X versions | 684 | // least OS specific settings. Hopefully, Linuxes and OS X versions |
| 682 | // are uniform enough, among each other... | 685 | // are uniform enough, among each other... |
| 683 | // | 686 | // |
| 684 | # if defined PLATFORM_OSX | 687 | # if defined PLATFORM_OSX |
| 685 | // AK 10-Apr-07 (OS X PowerPC 10.4.9): | 688 | // AK 10-Apr-07 (OS X PowerPC 10.4.9): |
| 686 | // | 689 | // |
| 687 | // With SCHED_RR, 26 seems to be the "normal" priority, where setting | 690 | // With SCHED_RR, 26 seems to be the "normal" priority, where setting |
| @@ -694,85 +697,92 @@ static int const gs_prio_remap[] = | |||
| 694 | // priority limits. This could imply, user mode applications won't | 697 | // priority limits. This could imply, user mode applications won't |
| 695 | // be able to use values outside of that range. | 698 | // be able to use values outside of that range. |
| 696 | // | 699 | // |
| 697 | # define _PRIO_MODE SCHED_OTHER | 700 | # define _PRIO_MODE SCHED_OTHER |
| 698 | 701 | ||
| 699 | // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope | 702 | // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope |
| 700 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | 703 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS |
| 701 | 704 | ||
| 702 | # define _PRIO_HI 32 // seems to work (_carefully_ picked!) | 705 | # define _PRIO_HI 32 // seems to work (_carefully_ picked!) |
| 703 | # define _PRIO_0 26 // detected | 706 | # define _PRIO_0 26 // detected |
| 704 | # define _PRIO_LO 1 // seems to work (tested) | 707 | # define _PRIO_LO 1 // seems to work (tested) |
| 705 | 708 | ||
| 706 | # elif defined PLATFORM_LINUX | 709 | # elif defined PLATFORM_LINUX |
| 707 | // (based on Ubuntu Linux 2.6.15 kernel) | 710 | // (based on Ubuntu Linux 2.6.15 kernel) |
| 708 | // | 711 | // |
| 709 | // SCHED_OTHER is the default policy, but does not allow for priorities. | 712 | // SCHED_OTHER is the default policy, but does not allow for priorities. |
| 710 | // SCHED_RR allows priorities, all of which (1..99) are higher than | 713 | // SCHED_RR allows priorities, all of which (1..99) are higher than |
| 711 | // a thread with SCHED_OTHER policy. | 714 | // a thread with SCHED_OTHER policy. |
| 712 | // | 715 | // |
| 713 | // <http://kerneltrap.org/node/6080> | 716 | // <http://kerneltrap.org/node/6080> |
| 714 | // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> | 717 | // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> |
| 715 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | 718 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> |
| 716 | // | 719 | // |
| 717 | // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, | 720 | // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, |
| 718 | // but even Ubuntu does not seem to define it. | 721 | // but even Ubuntu does not seem to define it. |
| 719 | // | 722 | // |
| 720 | # define _PRIO_MODE SCHED_RR | 723 | # define _PRIO_MODE SCHED_RR |
| 721 | 724 | ||
| 722 | // NTLP 2.5: only system scope allowed (being the basic reason why | 725 | // NTLP 2.5: only system scope allowed (being the basic reason why |
| 723 | // root privileges are required..) | 726 | // root privileges are required..) |
| 724 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | 727 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS |
| 725 | 728 | ||
| 726 | # define _PRIO_HI 99 | 729 | # define _PRIO_HI 99 |
| 727 | # define _PRIO_0 50 | 730 | # define _PRIO_0 50 |
| 728 | # define _PRIO_LO 1 | 731 | # define _PRIO_LO 1 |
| 729 | 732 | ||
| 730 | # elif defined(PLATFORM_BSD) | 733 | # elif defined(PLATFORM_BSD) |
| 731 | // | 734 | // |
| 732 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | 735 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> |
| 733 | // | 736 | // |
| 734 | // "When control over the thread scheduling is desired, then FreeBSD | 737 | // "When control over the thread scheduling is desired, then FreeBSD |
| 735 | // with the libpthread implementation is by far the best choice .." | 738 | // with the libpthread implementation is by far the best choice .." |
| 736 | // | 739 | // |
| 737 | # define _PRIO_MODE SCHED_OTHER | 740 | # define _PRIO_MODE SCHED_OTHER |
| 738 | # define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | 741 | # define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS |
| 739 | # define _PRIO_HI 31 | 742 | # define _PRIO_HI 31 |
| 740 | # define _PRIO_0 15 | 743 | # define _PRIO_0 15 |
| 741 | # define _PRIO_LO 1 | 744 | # define _PRIO_LO 1 |
| 742 | 745 | ||
| 743 | # elif defined(PLATFORM_CYGWIN) | 746 | # elif defined(PLATFORM_CYGWIN) |
| 744 | // | 747 | // |
| 745 | // TBD: Find right values for Cygwin | 748 | // TBD: Find right values for Cygwin |
| 746 | // | 749 | // |
| 747 | # elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) | 750 | # elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) |
| 748 | // any other value not supported by win32-pthread as of version 2.9.1 | 751 | // any other value not supported by win32-pthread as of version 2.9.1 |
| 749 | # define _PRIO_MODE SCHED_OTHER | 752 | # define _PRIO_MODE SCHED_OTHER |
| 750 | 753 | ||
| 751 | // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1 | 754 | // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1 |
| 752 | //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with? | 755 | //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with? |
| 753 | THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL | 756 | THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL |
| 754 | 757 | ||
| 755 | # else | 758 | # else |
| 756 | # error "Unknown OS: not implemented!" | 759 | # error "Unknown OS: not implemented!" |
| 757 | # endif | 760 | # endif |
| 758 | 761 | ||
| 759 | #if defined _PRIO_0 | 762 | #if defined _PRIO_0 |
| 760 | # define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2)) | 763 | # define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2)) |
| 761 | # define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2)) | 764 | # define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2)) |
| 762 | 765 | ||
| 763 | _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI | 766 | _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI |
| 764 | #endif // _PRIO_0 | 767 | #endif // _PRIO_0 |
| 765 | }; | 768 | }; |
| 766 | 769 | ||
| 770 | static int select_prio(int prio /* -3..+3 */) | ||
| 771 | { | ||
| 772 | if (prio == THREAD_PRIO_DEFAULT) | ||
| 773 | prio = 0; | ||
| 774 | // prio range [-3,+3] was checked by the caller | ||
| 775 | return gs_prio_remap[prio + 3]; | ||
| 776 | } | ||
| 777 | |||
| 767 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */) | 778 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */) |
| 768 | { | 779 | { |
| 769 | pthread_attr_t a; | 780 | pthread_attr_t a; |
| 770 | bool_t const normal = | 781 | bool_t const change_priority = |
| 771 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) | 782 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) |
| 772 | !sudo; // with sudo, even normal thread must use SCHED_RR | 783 | sudo && // with sudo, even normal thread must use SCHED_RR |
| 773 | #else | ||
| 774 | (prio == 0); | ||
| 775 | #endif | 784 | #endif |
| 785 | (prio != THREAD_PRIO_DEFAULT); | ||
| 776 | 786 | ||
| 777 | PT_CALL( pthread_attr_init( &a)); | 787 | PT_CALL( pthread_attr_init( &a)); |
| 778 | 788 | ||
| @@ -800,7 +810,7 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, | |||
| 800 | PT_CALL( pthread_attr_setstacksize( &a, _THREAD_STACK_SIZE)); | 810 | PT_CALL( pthread_attr_setstacksize( &a, _THREAD_STACK_SIZE)); |
| 801 | #endif | 811 | #endif |
| 802 | 812 | ||
| 803 | if( !normal) | 813 | if (change_priority) |
| 804 | { | 814 | { |
| 805 | struct sched_param sp; | 815 | struct sched_param sp; |
| 806 | // "The specified scheduling parameters are only used if the scheduling | 816 | // "The specified scheduling parameters are only used if the scheduling |
| @@ -816,8 +826,7 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, | |||
| 816 | 826 | ||
| 817 | PT_CALL( pthread_attr_setschedpolicy( &a, _PRIO_MODE)); | 827 | PT_CALL( pthread_attr_setschedpolicy( &a, _PRIO_MODE)); |
| 818 | 828 | ||
| 819 | // prio range [-3,+3] was checked by the caller | 829 | sp.sched_priority = select_prio(prio); |
| 820 | sp.sched_priority = gs_prio_remap[ prio + 3]; | ||
| 821 | PT_CALL( pthread_attr_setschedparam( &a, &sp)); | 830 | PT_CALL( pthread_attr_setschedparam( &a, &sp)); |
| 822 | } | 831 | } |
| 823 | 832 | ||
diff --git a/src/threading.h b/src/threading.h index 1224e08..3925076 100644 --- a/src/threading.h +++ b/src/threading.h | |||
| @@ -32,8 +32,10 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
| 32 | #define THREADAPI_PTHREAD 2 | 32 | #define THREADAPI_PTHREAD 2 |
| 33 | 33 | ||
| 34 | #if( defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) && !defined( HAVE_WIN32_PTHREAD) | 34 | #if( defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) && !defined( HAVE_WIN32_PTHREAD) |
| 35 | //#pragma message ( "THREADAPI_WINDOWS" ) | ||
| 35 | #define THREADAPI THREADAPI_WINDOWS | 36 | #define THREADAPI THREADAPI_WINDOWS |
| 36 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 37 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
| 38 | //#pragma message ( "THREADAPI_PTHREAD" ) | ||
| 37 | #define THREADAPI THREADAPI_PTHREAD | 39 | #define THREADAPI THREADAPI_PTHREAD |
| 38 | #endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 40 | #endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
| 39 | 41 | ||
| @@ -169,6 +171,8 @@ bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
| 169 | /*---=== Threading ===--- | 171 | /*---=== Threading ===--- |
| 170 | */ | 172 | */ |
| 171 | 173 | ||
| 174 | #define THREAD_PRIO_DEFAULT (-999) | ||
| 175 | |||
| 172 | #if THREADAPI == THREADAPI_WINDOWS | 176 | #if THREADAPI == THREADAPI_WINDOWS |
| 173 | 177 | ||
| 174 | typedef HANDLE THREAD_T; | 178 | typedef HANDLE THREAD_T; |
