diff options
| author | Benoit Germain <bnt.germain@gmail.com> | 2012-09-11 22:23:05 +0200 |
|---|---|---|
| committer | Benoit Germain <bnt.germain@gmail.com> | 2012-09-11 22:23:05 +0200 |
| commit | 5fad772d922250db9d46edec156cd89939c4d8b5 (patch) | |
| tree | 4a0425c4b6a2190dfdfcc64a9af6a04fb2ce0dd3 | |
| parent | 8697b3a058f4c58e3a463c77e10cb98fe318f26c (diff) | |
| download | lanes-5fad772d922250db9d46edec156cd89939c4d8b5.tar.gz lanes-5fad772d922250db9d46edec156cd89939c4d8b5.tar.bz2 lanes-5fad772d922250db9d46edec156cd89939c4d8b5.zip | |
code tweaks to enable building against win32-pthread on windows platforms.
not active by default, see threading.h.
| -rw-r--r-- | src/threading.c | 36 | ||||
| -rw-r--r-- | src/threading.h | 12 |
2 files changed, 33 insertions, 15 deletions
diff --git a/src/threading.c b/src/threading.c index 1cec1e0..7cd8da3 100644 --- a/src/threading.c +++ b/src/threading.c | |||
| @@ -41,9 +41,9 @@ THE SOFTWARE. | |||
| 41 | #include "threading.h" | 41 | #include "threading.h" |
| 42 | #include "lua.h" | 42 | #include "lua.h" |
| 43 | 43 | ||
| 44 | #if THREADAPI == THREADAPI_PTHREAD | 44 | #if !defined( PLATFORM_WIN32) && !defined( PLATFORM_POCKETPC) |
| 45 | # include <sys/time.h> | 45 | # include <sys/time.h> |
| 46 | #endif // THREADAPI == THREADAPI_PTHREAD | 46 | #endif // non-WIN32 timing |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) | 49 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) |
| @@ -71,7 +71,7 @@ THE SOFTWARE. | |||
| 71 | * FAIL is for unexpected API return values - essentially programming | 71 | * FAIL is for unexpected API return values - essentially programming |
| 72 | * error in _this_ code. | 72 | * error in _this_ code. |
| 73 | */ | 73 | */ |
| 74 | #if THREADAPI == THREADAPI_WINDOWS | 74 | #if defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) |
| 75 | static void FAIL( const char *funcname, int rc ) { | 75 | static void FAIL( const char *funcname, int rc ) { |
| 76 | fprintf( stderr, "%s() failed! (%d)\n", funcname, rc ); | 76 | fprintf( stderr, "%s() failed! (%d)\n", funcname, rc ); |
| 77 | #ifdef _MSC_VER | 77 | #ifdef _MSC_VER |
| @@ -79,7 +79,7 @@ static void FAIL( const char *funcname, int rc ) { | |||
| 79 | #endif // _MSC_VER | 79 | #endif // _MSC_VER |
| 80 | abort(); | 80 | abort(); |
| 81 | } | 81 | } |
| 82 | #endif // THREADAPI == THREADAPI_WINDOWS | 82 | #endif // win32 build |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| @@ -90,7 +90,7 @@ static void FAIL( const char *funcname, int rc ) { | |||
| 90 | */ | 90 | */ |
| 91 | time_d now_secs(void) { | 91 | time_d now_secs(void) { |
| 92 | 92 | ||
| 93 | #if THREADAPI == THREADAPI_WINDOWS | 93 | #if defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) |
| 94 | /* | 94 | /* |
| 95 | * Windows FILETIME values are "100-nanosecond intervals since | 95 | * Windows FILETIME values are "100-nanosecond intervals since |
| 96 | * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as | 96 | * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as |
| @@ -124,7 +124,7 @@ time_d now_secs(void) { | |||
| 124 | uli.HighPart= ft.dwHighDateTime; | 124 | uli.HighPart= ft.dwHighDateTime; |
| 125 | 125 | ||
| 126 | /* 'double' has less accuracy than 64-bit int, but if it were to degrade, | 126 | /* 'double' has less accuracy than 64-bit int, but if it were to degrade, |
| 127 | * it would do so gracefully. In practise, the integer accuracy is not | 127 | * it would do so gracefully. In practice, the integer accuracy is not |
| 128 | * of the 100ns class but just 1ms (Windows XP). | 128 | * of the 100ns class but just 1ms (Windows XP). |
| 129 | */ | 129 | */ |
| 130 | # if 1 | 130 | # if 1 |
| @@ -145,7 +145,7 @@ time_d now_secs(void) { | |||
| 145 | // <= 2.0.2 code | 145 | // <= 2.0.2 code |
| 146 | return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0; | 146 | return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0; |
| 147 | # endif | 147 | # endif |
| 148 | #else // THREADAPI == THREADAPI_PTHREAD | 148 | #else // !(defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) |
| 149 | struct timeval tv; | 149 | struct timeval tv; |
| 150 | // { | 150 | // { |
| 151 | // time_t tv_sec; /* seconds since Jan. 1, 1970 */ | 151 | // time_t tv_sec; /* seconds since Jan. 1, 1970 */ |
| @@ -156,7 +156,7 @@ time_d now_secs(void) { | |||
| 156 | assert( rc==0 ); | 156 | assert( rc==0 ); |
| 157 | 157 | ||
| 158 | return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0; | 158 | return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0; |
| 159 | #endif // THREADAPI THREADAPI_PTHREAD | 159 | #endif // !(defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | 162 | ||
| @@ -179,7 +179,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
| 179 | if (abs_secs==0.0) | 179 | if (abs_secs==0.0) |
| 180 | abs_secs= now_secs(); | 180 | abs_secs= now_secs(); |
| 181 | 181 | ||
| 182 | ts->tv_sec= floor( abs_secs ); | 182 | ts->tv_sec= (time_t) floor( abs_secs ); |
| 183 | ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns | 183 | ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns |
| 184 | if (ts->tv_nsec == 1000000000UL) | 184 | if (ts->tv_nsec == 1000000000UL) |
| 185 | { | 185 | { |
| @@ -381,7 +381,6 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 381 | // On Linux, SCHED_RR and su privileges are required.. !-( | 381 | // On Linux, SCHED_RR and su privileges are required.. !-( |
| 382 | // | 382 | // |
| 383 | #include <errno.h> | 383 | #include <errno.h> |
| 384 | #include <sys/time.h> | ||
| 385 | // | 384 | // |
| 386 | static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) { | 385 | static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) { |
| 387 | const char *why= (rc==EINVAL) ? "EINVAL" : | 386 | const char *why= (rc==EINVAL) ? "EINVAL" : |
| @@ -389,8 +388,9 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 389 | (rc==EPERM) ? "EPERM" : | 388 | (rc==EPERM) ? "EPERM" : |
| 390 | (rc==ENOMEM) ? "ENOMEM" : | 389 | (rc==ENOMEM) ? "ENOMEM" : |
| 391 | (rc==ESRCH) ? "ESRCH" : | 390 | (rc==ESRCH) ? "ESRCH" : |
| 391 | (rc==ENOTSUP) ? "ENOTSUP": | ||
| 392 | //... | 392 | //... |
| 393 | ""; | 393 | "<UNKNOWN>"; |
| 394 | fprintf( stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why ); | 394 | fprintf( stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why ); |
| 395 | abort(); | 395 | abort(); |
| 396 | } | 396 | } |
| @@ -440,6 +440,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 440 | pthread_attr_t _a; | 440 | pthread_attr_t _a; |
| 441 | pthread_attr_t *a= &_a; | 441 | pthread_attr_t *a= &_a; |
| 442 | struct sched_param sp; | 442 | struct sched_param sp; |
| 443 | bool_t normal; | ||
| 443 | 444 | ||
| 444 | PT_CALL( pthread_attr_init(a) ); | 445 | PT_CALL( pthread_attr_init(a) ); |
| 445 | 446 | ||
| @@ -464,7 +465,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 464 | PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) ); | 465 | PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) ); |
| 465 | #endif | 466 | #endif |
| 466 | 467 | ||
| 467 | bool_t normal= | 468 | normal= |
| 468 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) | 469 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) |
| 469 | !sudo; // with sudo, even normal thread must use SCHED_RR | 470 | !sudo; // with sudo, even normal thread must use SCHED_RR |
| 470 | #else | 471 | #else |
| @@ -574,6 +575,17 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 574 | // | 575 | // |
| 575 | // TBD: Find right values for Cygwin | 576 | // TBD: Find right values for Cygwin |
| 576 | // | 577 | // |
| 578 | #elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) | ||
| 579 | // any other value not supported by win32-pthread as of version 2.9.1 | ||
| 580 | #define _PRIO_MODE SCHED_OTHER | ||
| 581 | |||
| 582 | // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1 | ||
| 583 | //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with? | ||
| 584 | |||
| 585 | // win32-pthread seems happy with direct -2..+2 instead of some other remapping | ||
| 586 | #define _PRIO_HI (+2) | ||
| 587 | #define _PRIO_0 (0) | ||
| 588 | #define _PRIO_LO (-2) | ||
| 577 | #else | 589 | #else |
| 578 | #error "Unknown OS: not implemented!" | 590 | #error "Unknown OS: not implemented!" |
| 579 | #endif | 591 | #endif |
diff --git a/src/threading.h b/src/threading.h index f4f1ada..b95733d 100644 --- a/src/threading.h +++ b/src/threading.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #define __threading_h__ 1 | 5 | #define __threading_h__ 1 |
| 6 | 6 | ||
| 7 | /* Platform detection | 7 | /* Platform detection |
| 8 | */ | 8 | * win32-pthread: |
| 9 | * define HAVE_WIN32_PTHREAD and PTW32_INCLUDE_WINDOWS_H in your project configuration when building for win32-pthread. | ||
| 10 | * link against pthreadVC2.lib, and of course have pthreadVC2.dll somewhere in your path. | ||
| 11 | */ | ||
| 9 | #ifdef _WIN32_WCE | 12 | #ifdef _WIN32_WCE |
| 10 | #define PLATFORM_POCKETPC | 13 | #define PLATFORM_POCKETPC |
| 11 | #elif (defined _WIN32) | 14 | #elif (defined _WIN32) |
| @@ -44,7 +47,7 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
| 44 | #define THREADAPI_WINDOWS 1 | 47 | #define THREADAPI_WINDOWS 1 |
| 45 | #define THREADAPI_PTHREAD 2 | 48 | #define THREADAPI_PTHREAD 2 |
| 46 | 49 | ||
| 47 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 50 | #if( defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) && !defined( HAVE_WIN32_PTHREAD) |
| 48 | #define THREADAPI THREADAPI_WINDOWS | 51 | #define THREADAPI THREADAPI_WINDOWS |
| 49 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 52 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
| 50 | #define THREADAPI THREADAPI_PTHREAD | 53 | #define THREADAPI THREADAPI_PTHREAD |
| @@ -114,8 +117,11 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
| 114 | // FreeBSD 6.2 has pthread_yield() | 117 | // FreeBSD 6.2 has pthread_yield() |
| 115 | // ... | 118 | // ... |
| 116 | // | 119 | // |
| 117 | #ifdef PLATFORM_OSX | 120 | #if defined( PLATFORM_OSX) |
| 118 | #define YIELD() pthread_yield_np() | 121 | #define YIELD() pthread_yield_np() |
| 122 | #elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) | ||
| 123 | // for some reason win32-pthread doesn't have pthread_yield(), but sched_yield() | ||
| 124 | #define YIELD() sched_yield() | ||
| 119 | #else | 125 | #else |
| 120 | #define YIELD() pthread_yield() | 126 | #define YIELD() pthread_yield() |
| 121 | #endif | 127 | #endif |
