]> git.mxchange.org Git - simgear.git/blob - simgear/threads/SGThread.cxx
Add support for win32-pthreads in MSVC.NET
[simgear.git] / simgear / threads / SGThread.cxx
1 #include <simgear/compiler.h>
2
3 #if defined(_MSC_VER) || defined(__MINGW32__)
4 #  include <time.h>
5 #else
6 #  include <sys/time.h>
7 #endif
8 #if _MSC_VER >= 1300
9 #  include "winsock2.h"
10 #endif
11
12 #include "SGThread.hxx"
13
14 void*
15 start_handler( void* arg )
16 {
17     SGThread* thr = static_cast<SGThread*>(arg);
18     thr->run();
19     return 0;
20 }
21
22 void
23 SGThread::set_cancel( cancel_t mode )
24 {
25     switch (mode)
26     {
27     case CANCEL_DISABLE:
28         pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, 0 );
29         break;
30     case CANCEL_DEFERRED:
31         pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, 0 );
32         pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, 0 );
33         break;
34     case CANCEL_IMMEDIATE:
35         pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, 0 );
36         pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, 0 );
37         break;
38     default:
39         break;
40     }
41 }
42
43 bool
44 SGMutex::trylock()
45 {
46     int status = pthread_mutex_lock( &mutex );
47     if (status == EBUSY)
48     {
49         return false;
50     }
51     assert( status == 0 );
52     return true;
53 }
54
55 #if defined(_MSC_VER) || defined(__MINGW32__)
56 int gettimeofday(struct timeval* tp, void* tzp) {
57     LARGE_INTEGER t;
58
59     if(QueryPerformanceCounter(&t)) {
60         /* hardware supports a performance counter */
61         LARGE_INTEGER f;
62         QueryPerformanceFrequency(&f);
63         tp->tv_sec = t.QuadPart/f.QuadPart;
64         tp->tv_usec = ((float)t.QuadPart/f.QuadPart*1000*1000)
65             - (tp->tv_sec*1000*1000);
66     } else {
67         /* hardware doesn't support a performance counter, so get the
68            time in a more traditional way. */
69         DWORD t;
70         t = timeGetTime();
71         tp->tv_sec = t / 1000;
72         tp->tv_usec = t % 1000;
73     }
74
75     /* 0 indicates that the call succeeded. */
76     return 0;
77 }
78 #endif
79
80 bool
81 SGPthreadCond::wait( SGMutex& mutex, unsigned long ms )
82 {
83     struct timeval now;
84     ::gettimeofday( &now, 0 );
85
86     // Wait time is now + ms milliseconds
87     unsigned int sec = ms / 1000;
88     unsigned int nsec = (ms % 1000) * 1000;
89     struct timespec abstime;
90     abstime.tv_sec = now.tv_sec + sec;
91     abstime.tv_nsec = now.tv_usec*1000 + nsec;
92
93     int status = pthread_cond_timedwait( &cond, &mutex.mutex, &abstime );
94     if (status == ETIMEDOUT)
95     {
96         return false;
97     }
98
99     assert( status == 0 );
100     return true;
101 }
102