|
1 /* |
|
2 * Copyright 2006 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 #ifndef SkThread_DEFINED |
|
9 #define SkThread_DEFINED |
|
10 |
|
11 #include "SkTypes.h" |
|
12 |
|
13 // SK_ATOMICS_PLATFORM_H must provide inline implementations for the following declarations. |
|
14 |
|
15 /** Atomically adds one to the int referenced by addr and returns the previous value. |
|
16 * No additional memory barrier is required; this must act as a compiler barrier. |
|
17 */ |
|
18 static int32_t sk_atomic_inc(int32_t* addr); |
|
19 |
|
20 /** Atomically adds inc to the int referenced by addr and returns the previous value. |
|
21 * No additional memory barrier is required; this must act as a compiler barrier. |
|
22 */ |
|
23 static int32_t sk_atomic_add(int32_t* addr, int32_t inc); |
|
24 |
|
25 /** Atomically subtracts one from the int referenced by addr and returns the previous value. |
|
26 * This must act as a release (SL/S) memory barrier and as a compiler barrier. |
|
27 */ |
|
28 static int32_t sk_atomic_dec(int32_t* addr); |
|
29 |
|
30 /** Atomically adds one to the int referenced by addr iff the referenced int was not 0 |
|
31 * and returns the previous value. |
|
32 * No additional memory barrier is required; this must act as a compiler barrier. |
|
33 */ |
|
34 static int32_t sk_atomic_conditional_inc(int32_t* addr); |
|
35 |
|
36 /** Atomic compare and set. |
|
37 * If *addr == before, set *addr to after and return true, otherwise return false. |
|
38 * This must act as a release (SL/S) memory barrier and as a compiler barrier. |
|
39 */ |
|
40 static bool sk_atomic_cas(int32_t* addr, int32_t before, int32_t after); |
|
41 |
|
42 /** If sk_atomic_dec does not act as an acquire (L/SL) barrier, |
|
43 * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. |
|
44 */ |
|
45 static void sk_membar_acquire__after_atomic_dec(); |
|
46 |
|
47 /** If sk_atomic_conditional_inc does not act as an acquire (L/SL) barrier, |
|
48 * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. |
|
49 */ |
|
50 static void sk_membar_acquire__after_atomic_conditional_inc(); |
|
51 |
|
52 #include SK_ATOMICS_PLATFORM_H |
|
53 |
|
54 /** SK_MUTEX_PLATFORM_H must provide the following (or equivalent) declarations. |
|
55 |
|
56 class SkBaseMutex { |
|
57 public: |
|
58 void acquire(); |
|
59 void release(); |
|
60 }; |
|
61 |
|
62 class SkMutex : SkBaseMutex { |
|
63 public: |
|
64 SkMutex(); |
|
65 ~SkMutex(); |
|
66 }; |
|
67 |
|
68 #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ... |
|
69 #define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ... |
|
70 */ |
|
71 |
|
72 #include SK_MUTEX_PLATFORM_H |
|
73 |
|
74 |
|
75 class SkAutoMutexAcquire : SkNoncopyable { |
|
76 public: |
|
77 explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) { |
|
78 SkASSERT(fMutex != NULL); |
|
79 mutex.acquire(); |
|
80 } |
|
81 |
|
82 explicit SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) { |
|
83 if (mutex) { |
|
84 mutex->acquire(); |
|
85 } |
|
86 } |
|
87 |
|
88 /** If the mutex has not been released, release it now. */ |
|
89 ~SkAutoMutexAcquire() { |
|
90 if (fMutex) { |
|
91 fMutex->release(); |
|
92 } |
|
93 } |
|
94 |
|
95 /** If the mutex has not been released, release it now. */ |
|
96 void release() { |
|
97 if (fMutex) { |
|
98 fMutex->release(); |
|
99 fMutex = NULL; |
|
100 } |
|
101 } |
|
102 |
|
103 private: |
|
104 SkBaseMutex* fMutex; |
|
105 }; |
|
106 #define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) |
|
107 |
|
108 #endif |