1 /* thread.h 2 * Copyright (C) 2001-2003, Parrot Foundation. 3 * Overview: 4 * This is the api header for the windows thread primitives 5 * Data Structure and Algorithms: 6 * History: 7 * Notes: 8 * References: 9 */ 10 11 #ifndef PARROT_THR_WINDOWS_H_GUARD 12 #define PARROT_THR_WINDOWS_H_GUARD 13 14 # undef FASTCALL 15 # define WIN32_LEAN_AND_MEAN 16 # include <windows.h> 17 # include <process.h> 18 # include <limits.h> 19 # undef CONST 20 21 typedef CRITICAL_SECTION Parrot_mutex; 22 typedef struct Windows_cond { 23 HANDLE m_hSema; 24 LONG m_lWaiters; 25 } Parrot_cond; 26 typedef HANDLE Parrot_thread; 27 28 # define MUTEX_INIT(m) InitializeCriticalSectionAndSpinCount((PCRITICAL_SECTION)&(m), 4000) 29 # define MUTEX_DESTROY(m) DeleteCriticalSection((PCRITICAL_SECTION)&(m)) 30 31 # define COND_INIT(c) \ 32 do { \ 33 (c).m_hSema = CreateSemaphore(NULL, 0, LONG_MAX, NULL); \ 34 (c).m_lWaiters = 0; \ 35 } while (0) 36 37 # define COND_DESTROY(c) CloseHandle((c).m_hSema) 38 39 # define LOCK(m) EnterCriticalSection((PCRITICAL_SECTION)&(m)) 40 # define UNLOCK(m) LeaveCriticalSection((PCRITICAL_SECTION)&(m)) 41 42 # define COND_WAIT(c, m) \ 43 do { \ 44 ++(c).m_lWaiters; \ 45 UNLOCK(m); \ 46 WaitForSingleObject((c).m_hSema, INFINITE); \ 47 LOCK(m); \ 48 --(c).m_lWaiters; \ 49 } while (0) 50 51 # define COND_TIMED_WAIT(c, m, t, rc) \ 52 do { \ 53 FLOATVAL now; \ 54 time_t sec; \ 55 LONG nsec; \ 56 DWORD diff; \ 57 now = Parrot_floatval_time(); \ 58 sec = (time_t)now; \ 59 nsec = (LONG)((now - sec)*1000.0f)*1000000L; \ 60 if ((t)->tv_sec > sec || ((t)->tv_sec == sec && (t)->tv_nsec > nsec)) \ 61 { \ 62 ++(c).m_lWaiters; \ 63 UNLOCK(m); \ 64 diff = (DWORD)(((t)->tv_sec - sec)*1000L + ((t)->tv_nsec - nsec)/1000000L); \ 65 (rc) = WaitForSingleObject((c).m_hSema, diff) != WAIT_OBJECT_0; \ 66 LOCK(m); \ 67 --(c).m_lWaiters; \ 68 } \ 69 else { \ 70 (rc) = 1; \ 71 } \ 72 } while (0) 73 74 # define COND_SIGNAL(c) \ 75 do { \ 76 if ((c).m_lWaiters > 0) \ 77 ReleaseSemaphore((c).m_hSema, 1, NULL); \ 78 } while (0) 79 80 # define COND_BROADCAST(c) \ 81 do { \ 82 if ((c).m_lWaiters > 0) \ 83 ReleaseSemaphore((c).m_hSema, (c).m_lWaiters, NULL); \ 84 } while (0) 85 86 # define JOIN(t, ret) \ 87 do { \ 88 WaitForSingleObject((t), INFINITE); \ 89 GetExitCodeThread((t), (LPDWORD)&(ret)); \ 90 CloseHandle(t); \ 91 } while (0) 92 93 # define DETACH(t) CloseHandle(t) 94 95 /* If the compiler CRT library has a good _beginthreadXX() routine, use it instead of 96 the Win32 API CreateThread(). _beginthreadXX guards call to the thread start routine 97 with SEH to implement runtime errors and signal support. Also it frees calloc-ed 98 per-thread data block at exit */ 99 #ifdef _MCS_VER1 100 # define THREAD_CREATE_JOINABLE(t, func, arg) \ 101 do { \ 102 unsigned tid; \ 103 (t) = (HANDLE)_beginthreadex(NULL, 0, unsigned (__stdcall * (func)) (void*), \ 104 (void*)(arg), 0, &tid); \ 105 } while (0) 106 #else 107 # define THREAD_CREATE_JOINABLE(t, func, arg) \ 108 do { \ 109 DWORD tid; \ 110 (t) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func), (PVOID)(arg), 0, &tid); \ 111 } while (0) 112 #endif 113 114 # define THREAD_CREATE_DETACHED(t, func, arg) \ 115 do { \ 116 THREAD_CREATE_JOINABLE((t), (func), (arg)); \ 117 DETACH(t); \ 118 } while (0) 119 120 # define CLEANUP_PUSH(f, a) 121 # define CLEANUP_POP(a) 122 123 typedef void (*Cleanup_Handler)(void *); 124 125 #endif /* PARROT_THR_WINDOWS_H_GUARD */ 126 127 /* 128 * Local variables: 129 * c-file-style: "parrot" 130 * End: 131 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 132 */ 133