1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/*
2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License.
6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at
7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and
14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License.
15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */
16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
175af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
185af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#define SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
19464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
20464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#if defined (WIN32)
21464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
22464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include <windows.h>
23464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
24246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicIncrement(size_t* address) {
25464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#if defined (_WIN64)
26464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return InterlockedIncrement64(reinterpret_cast<LONGLONG*>(address));
27464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#else
28464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return InterlockedIncrement(reinterpret_cast<LONG*>(address));
29464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#endif
30464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
31464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
32246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicDecrement(size_t* address) {
33464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#if defined (_WIN64)
34464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return InterlockedDecrement64(reinterpret_cast<LONGLONG*>(address));
35464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#else
36464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return InterlockedDecrement(reinterpret_cast<LONG*>(address));
37464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#endif
38464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
39464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
40464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#elif defined (__APPLE__)
41464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
42464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include <libkern/OSAtomic.h>
43464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
44246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicIncrement(size_t* address) {
45464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return OSAtomicIncrement32Barrier(reinterpret_cast<int32_t*>(address));
46464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
47464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
48246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicDecrement(size_t* address) {
49464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return OSAtomicDecrement32Barrier(reinterpret_cast<int32_t*>(address));
50464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
51464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
52050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com// Originally we check __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4, however, there are
53050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com// issues that clang not carring over this definition.  Therefore we boldly
54050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com// assume it's gcc or gcc-compatible here.  Compilation shall still fail since
55050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com// the intrinsics used are GCC-specific.
56050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com
57050736d52301766cd6bd3838766575dab3944551arthurhsu@google.com#else
58464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
59464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include <stddef.h>
60464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
61246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicIncrement(size_t* address) {
62464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return __sync_add_and_fetch(address, 1);
63464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
64464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
65246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comstatic inline size_t AtomicDecrement(size_t* address) {
66464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return __sync_sub_and_fetch(address, 1);
67464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
68464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
69464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#endif  // WIN32
70464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
715af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
72