1 /*------------------------------------------------------------------------- 2 * drawElements Thread Library 3 * --------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Win32 implementation of mutex. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deMutex.h" 25 26 #if (DE_OS == DE_OS_WIN32 || DE_OS == DE_OS_WINCE) 27 28 #include "deMemory.h" 29 30 #define VC_EXTRALEAN 31 #define WIN32_LEAN_AND_MEAN 32 #define NOMINMAX 33 #include <windows.h> 34 35 /* Critical section objects are more lightweight than mutexes on Win32. */ 36 #define USE_CRITICAL_SECTION 1 37 38 #if defined(USE_CRITICAL_SECTION) 39 40 enum 41 { 42 CRITICAL_SECTION_SPIN_COUNT = 2048 43 }; 44 45 DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(CRITICAL_SECTION*)); 46 deMutex_create(const deMutexAttributes * attributes)47deMutex deMutex_create (const deMutexAttributes* attributes) 48 { 49 CRITICAL_SECTION* criticalSection = (CRITICAL_SECTION*)deMalloc(sizeof(CRITICAL_SECTION)); 50 if (!criticalSection) 51 return 0; 52 53 DE_UNREF(attributes); 54 /* \note [2012-11-05 pyry] Critical sections are always recursive. */ 55 56 if (!InitializeCriticalSectionAndSpinCount(criticalSection, CRITICAL_SECTION_SPIN_COUNT)) 57 { 58 deFree(criticalSection); 59 return 0; 60 } 61 62 return (deMutex)criticalSection; 63 } 64 deMutex_destroy(deMutex mutex)65void deMutex_destroy (deMutex mutex) 66 { 67 DeleteCriticalSection((CRITICAL_SECTION*)mutex); 68 deFree((CRITICAL_SECTION*)mutex); 69 } 70 deMutex_lock(deMutex mutex)71void deMutex_lock (deMutex mutex) 72 { 73 EnterCriticalSection((CRITICAL_SECTION*)mutex); 74 } 75 deMutex_unlock(deMutex mutex)76void deMutex_unlock (deMutex mutex) 77 { 78 LeaveCriticalSection((CRITICAL_SECTION*)mutex); 79 } 80 deMutex_tryLock(deMutex mutex)81deBool deMutex_tryLock (deMutex mutex) 82 { 83 return TryEnterCriticalSection((CRITICAL_SECTION*)mutex) == TRUE; 84 } 85 86 #else 87 88 DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(HANDLE)); 89 deMutex_create(const deMutexAttributes * attributes)90deMutex deMutex_create (const deMutexAttributes* attributes) 91 { 92 HANDLE handle = DE_NULL; 93 94 DE_UNREF(attributes); 95 /* \note [2009-11-12 pyry] Created mutex is always recursive. */ 96 97 handle = CreateMutex(DE_NULL, FALSE, DE_NULL); 98 return (deMutex)handle; 99 } 100 deMutex_destroy(deMutex mutex)101void deMutex_destroy (deMutex mutex) 102 { 103 HANDLE handle = (HANDLE)mutex; 104 CloseHandle(handle); 105 } 106 deMutex_lock(deMutex mutex)107void deMutex_lock (deMutex mutex) 108 { 109 HANDLE handle = (HANDLE)mutex; 110 DWORD ret = WaitForSingleObject(handle, INFINITE); 111 DE_ASSERT(ret == WAIT_OBJECT_0); 112 } 113 deMutex_unlock(deMutex mutex)114void deMutex_unlock (deMutex mutex) 115 { 116 HANDLE handle = (HANDLE)mutex; 117 BOOL ret = ReleaseMutex(handle); 118 DE_ASSERT(ret == TRUE); 119 } 120 deMutex_tryLock(deMutex mutex)121deBool deMutex_tryLock (deMutex mutex) 122 { 123 HANDLE handle = (HANDLE)mutex; 124 DWORD ret = WaitForSingleObject(handle, 0); 125 return (ret == WAIT_OBJECT_0); 126 } 127 128 #endif /* USE_CRITICAL_SECTION */ 129 130 #endif /* DE_OS */ 131