blob: 708db24ab99db7db944f30a8469b538d9b1569c6 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include <windows.h>
bungeman@google.comeee66612012-02-17 22:00:07 +00009#include <intrin.h>
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkThread.h"
11
bungeman@google.comeee66612012-02-17 22:00:07 +000012//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.
scroggo@google.com50ccb0a2012-07-16 16:51:28 +000016#pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDecrement)
bungeman@google.coma02bc152012-05-16 18:21:56 +000017#pragma intrinsic(_InterlockedCompareExchange)
bungeman@google.comeee66612012-02-17 22:00:07 +000018
reed@google.comdcbd6e32012-01-12 15:21:16 +000019int32_t sk_atomic_inc(int32_t* addr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000020 // InterlockedIncrement returns the new value, we want to return the old.
bungeman@google.comeee66612012-02-17 22:00:07 +000021 return _InterlockedIncrement(reinterpret_cast<LONG*>(addr)) - 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +000022}
23
scroggo@google.com50ccb0a2012-07-16 16:51:28 +000024int32_t sk_atomic_add(int32_t* addr, int32_t inc) {
25 return _InterlockedExchangeAdd(reinterpret_cast<LONG*>(addr),
26 static_cast<LONG>(inc));
27}
28
reed@google.comdcbd6e32012-01-12 15:21:16 +000029int32_t sk_atomic_dec(int32_t* addr) {
bungeman@google.comeee66612012-02-17 22:00:07 +000030 return _InterlockedDecrement(reinterpret_cast<LONG*>(addr)) + 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +000031}
bungeman@google.coma02bc152012-05-16 18:21:56 +000032void sk_membar_aquire__after_atomic_dec() { }
33
34int32_t sk_atomic_conditional_inc(int32_t* addr) {
35 while (true) {
bungeman@google.com0afc6bb2013-06-20 17:54:26 +000036 LONG value = static_cast<int32_t const volatile&>(*addr);
bungeman@google.coma02bc152012-05-16 18:21:56 +000037 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() { }
reed@android.com8a1c16f2008-12-17 15:59:43 +000048
reed@google.comdcbd6e32012-01-12 15:21:16 +000049SkMutex::SkMutex() {
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000050 SK_COMPILE_ASSERT(sizeof(fStorage) > sizeof(CRITICAL_SECTION),
51 NotEnoughSizeForCriticalSection);
reed@android.com8a1c16f2008-12-17 15:59:43 +000052 InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage));
53}
54
reed@google.comdcbd6e32012-01-12 15:21:16 +000055SkMutex::~SkMutex() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage));
57}
58
reed@google.comdcbd6e32012-01-12 15:21:16 +000059void SkMutex::acquire() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000060 EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage));
61}
62
reed@google.comdcbd6e32012-01-12 15:21:16 +000063void SkMutex::release() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage));
65}