1/* 2 * Copyright 2008 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include <windows.h> 9#include <intrin.h> 10#include "SkThread.h" 11 12//MSDN says in order to declare an interlocked function for use as an 13//intrinsic, include intrin.h and put the function in a #pragma intrinsic 14//directive. 15//The pragma appears to be unnecessary, but doesn't hurt. 16#pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDecrement) 17#pragma intrinsic(_InterlockedCompareExchange) 18 19int32_t sk_atomic_inc(int32_t* addr) { 20 // InterlockedIncrement returns the new value, we want to return the old. 21 return _InterlockedIncrement(reinterpret_cast<LONG*>(addr)) - 1; 22} 23 24int32_t sk_atomic_add(int32_t* addr, int32_t inc) { 25 return _InterlockedExchangeAdd(reinterpret_cast<LONG*>(addr), 26 static_cast<LONG>(inc)); 27} 28 29int32_t sk_atomic_dec(int32_t* addr) { 30 return _InterlockedDecrement(reinterpret_cast<LONG*>(addr)) + 1; 31} 32void sk_membar_aquire__after_atomic_dec() { } 33 34int32_t sk_atomic_conditional_inc(int32_t* addr) { 35 while (true) { 36 LONG value = static_cast<int32_t const volatile&>(*addr); 37 if (value == 0) { 38 return 0; 39 } 40 if (_InterlockedCompareExchange(reinterpret_cast<LONG*>(addr), 41 value + 1, 42 value) == value) { 43 return value; 44 } 45 } 46} 47void sk_membar_aquire__after_atomic_conditional_inc() { } 48 49SkMutex::SkMutex() { 50 SK_COMPILE_ASSERT(sizeof(fStorage) > sizeof(CRITICAL_SECTION), 51 NotEnoughSizeForCriticalSection); 52 InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); 53} 54 55SkMutex::~SkMutex() { 56 DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); 57} 58 59void SkMutex::acquire() { 60 EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); 61} 62 63void SkMutex::release() { 64 LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); 65} 66