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 40enum 41{ 42 CRITICAL_SECTION_SPIN_COUNT = 2048 43}; 44 45DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(CRITICAL_SECTION*)); 46 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 65void deMutex_destroy (deMutex mutex) 66{ 67 DeleteCriticalSection((CRITICAL_SECTION*)mutex); 68 deFree((CRITICAL_SECTION*)mutex); 69} 70 71void deMutex_lock (deMutex mutex) 72{ 73 EnterCriticalSection((CRITICAL_SECTION*)mutex); 74} 75 76void deMutex_unlock (deMutex mutex) 77{ 78 LeaveCriticalSection((CRITICAL_SECTION*)mutex); 79} 80 81deBool deMutex_tryLock (deMutex mutex) 82{ 83 return TryEnterCriticalSection((CRITICAL_SECTION*)mutex) == TRUE; 84} 85 86#else 87 88DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(HANDLE)); 89 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 101void deMutex_destroy (deMutex mutex) 102{ 103 HANDLE handle = (HANDLE)mutex; 104 CloseHandle(handle); 105} 106 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 114void deMutex_unlock (deMutex mutex) 115{ 116 HANDLE handle = (HANDLE)mutex; 117 BOOL ret = ReleaseMutex(handle); 118 DE_ASSERT(ret == TRUE); 119} 120 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