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 |