From 30b046f829541ae5ff8dc1088cea8e09bdc320db Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 13 Sep 2012 22:40:16 +0200 Subject: minor internal changes * implemented set_debug_threadname() for pthread builds where possible * refactored linda __tostring and __concat * linda metatable's __metatable is a string instead of a boolean --- CHANGES | 6 +++- src/lanes.c | 109 ++++++++++++++++++-------------------------------------- src/threading.c | 52 +++++++++++++++++++++++++-- src/threading.h | 1 + 4 files changed, 91 insertions(+), 77 deletions(-) diff --git a/CHANGES b/CHANGES index 36f06ab..6eaca41 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ CHANGES: -CHAGE 46: BGe 10-Sep-2012 +CHANGE 47: BGe 13-Sep-2012 + * implemented set_debug_threadname() for pthread builds where possible + * refactored linda __tostring and __concat + +CHANGE 46: BGe 10-Sep-2012 * version 3.3.0 * lane.status can return "killed" if lane was forcefully killed with lanes:cancel() * lane:join(): return nil, "killed" if called on a killed lane. diff --git a/src/lanes.c b/src/lanes.c index 3ac085d..eac4753 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -713,18 +713,31 @@ LUAG_FUNC( linda_deep ) { * * Useful for concatenation or debugging purposes */ -LUAG_FUNC( linda_tostring) + +static int linda_tostring( lua_State* L, int _idx, bool_t _opt) { char text[32]; int len; - struct s_Linda* linda = lua_toLinda( L, 1); - luaL_argcheck( L, linda, 1, "expected a linda object!"); - if( linda->name[0]) - len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda->name); - else - len = sprintf( text, "linda: %p", linda); - lua_pushlstring( L, text, len); - return 1; + struct s_Linda* linda = lua_toLinda( L, _idx); + if( !_opt) + { + luaL_argcheck( L, linda, _idx, "expected a linda object!"); + } + if( linda) + { + if( linda->name[0]) + len = sprintf( text, "Linda: %.*s", (int)sizeof(text) - 8, linda->name); + else + len = sprintf( text, "Linda: %p", linda); + lua_pushlstring( L, text, len); + return 1; + } + return 0; +} + +LUAG_FUNC( linda_tostring) +{ + return linda_tostring( L, 1, FALSE); } @@ -736,35 +749,23 @@ LUAG_FUNC( linda_tostring) * Useful for concatenation or debugging purposes */ LUAG_FUNC( linda_concat) -{ - struct s_Linda *linda1 = lua_toLinda( L, 1); - struct s_Linda *linda2 = lua_toLinda( L, 2); - // lua semantics should enforce that one of the parameters we got is a linda - luaL_argcheck( L, linda1 || linda2, 1, "expected a linda object!"); - // replace the lindas by their string equivalents in the stack - if ( linda1) +{ // linda1? linda2? + bool_t atLeastOneLinda = FALSE; + // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. + if( linda_tostring( L, 1, TRUE)) { - char text[32]; - int len; - if( linda1->name[0]) - len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda1->name); - else - len = sprintf( text, "linda: %p", linda1); - lua_pushlstring( L, text, len); + atLeastOneLinda = TRUE; lua_replace( L, 1); } - if ( linda2) + if( linda_tostring( L, 2, TRUE)) { - char text[32]; - int len; - if( linda2->name[0]) - len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda2->name); - else - len = sprintf( text, "linda: %p", linda2); - lua_pushlstring( L, text, len); + atLeastOneLinda = TRUE; lua_replace( L, 2); } - // concat the result + if( !atLeastOneLinda) // should not be possible + { + return luaL_error( L, "internal error: linda_concat called on non-Linda"); + } lua_concat( L, 2); return 1; } @@ -853,7 +854,7 @@ static void linda_id( lua_State *L, char const * const which) lua_setfield( L, -2, "__index"); // protect metatable from external access - lua_pushboolean( L, 0); + lua_pushliteral( L, "Linda"); lua_setfield( L, -2, "__metatable"); lua_pushcfunction( L, LG_linda_tostring); @@ -1519,52 +1520,12 @@ static int lane_error( lua_State* L) } #endif // ERROR_FULL_STACK -#if defined PLATFORM_WIN32 && !defined __GNUC__ -//see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx -#define MS_VC_EXCEPTION 0x406D1388 -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -void SetThreadName( DWORD dwThreadID, char const *_threadName) -{ - THREADNAME_INFO info; - Sleep(10); - info.dwType = 0x1000; - info.szName = _threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - } -} -#endif - LUAG_FUNC( set_debug_threadname) { luaL_checktype( L, -1, LUA_TSTRING); -#if defined PLATFORM_WIN32 && !defined __GNUC__ - { - char const *threadName = lua_tostring( L, -1); - - // to see thead name in Visual Studio C debugger - SetThreadName(-1, threadName); - } -#endif // defined PLATFORM_WIN32 && !defined __GNUC__ + THREAD_SETNAME( lua_tostring( L, -1)); // to see VM name in Decoda debugger Virtual Machine window lua_setglobal( L, "decoda_name"); - return 0; } diff --git a/src/threading.c b/src/threading.c index 7cd8da3..3bcf6cd 100644 --- a/src/threading.c +++ b/src/threading.c @@ -303,6 +303,41 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) if (!TerminateThread( *ref, 0 )) FAIL("TerminateThread", GetLastError()); *ref= NULL; } + +#if !defined __GNUC__ + //see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + #define MS_VC_EXCEPTION 0x406D1388 + #pragma pack(push,8) + typedef struct tagTHREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + } THREADNAME_INFO; + #pragma pack(pop) +#endif // !__GNUC__ + + void THREAD_SETNAME( char const* _name) + { +#if !defined __GNUC__ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = _name; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; + + __try + { + RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +#endif // !__GNUC__ + } + + // void SIGNAL_INIT( SIGNAL_T *ref ) { // 'manual reset' event type selected, to be able to wake up all the @@ -735,6 +770,19 @@ bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T * void THREAD_KILL( THREAD_T *ref ) { pthread_cancel( *ref ); } -#endif // THREADAPI == THREADAPI_PTHREAD -static const lua_Alloc alloc_f= 0; + void THREAD_SETNAME( char const* _name) + { + // exact API to set the thread name is platform-dependant + // if you need to fix the build, or if you know how to fill a hole, tell me (bnt.germain@gmail.com) so that I can submit the fix in github. +#if defined PLATFORM_BSD + pthread_set_name_np( pthread_self(), _name); +#elif defined PLATFORM_LINUX || defined PLATFORM_QNX || defined PLATFORM_CYGWIN + pthread_setname_np(_name pthread_self(), _name); +#elif defined PLATFORM_OSX + pthread_setname_np(_name); +#elif defined PLATFORM_WIN32 || defined PLATFORM_POCKETPC + // no API in win32-pthread yet :-( +#endif + } +#endif // THREADAPI == THREADAPI_PTHREAD diff --git a/src/threading.h b/src/threading.h index b95733d..1d304fa 100644 --- a/src/threading.h +++ b/src/threading.h @@ -217,5 +217,6 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs, SIGNAL_T *signal_ref, MUTEX #endif // // THREADWAIT_METHOD == THREADWAIT_CONDVAR void THREAD_KILL( THREAD_T *ref ); +void THREAD_SETNAME( char const* _name); #endif // __threading_h__ -- cgit v1.2.3-55-g6feb