aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2012-09-11 22:23:05 +0200
committerBenoit Germain <bnt.germain@gmail.com>2012-09-11 22:23:05 +0200
commit5fad772d922250db9d46edec156cd89939c4d8b5 (patch)
tree4a0425c4b6a2190dfdfcc64a9af6a04fb2ce0dd3
parent8697b3a058f4c58e3a463c77e10cb98fe318f26c (diff)
downloadlanes-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.c36
-rw-r--r--src/threading.h12
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)
75static void FAIL( const char *funcname, int rc ) { 75static 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*/
91time_d now_secs(void) { 91time_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