OSDN Git Service

DO NOT MERGE Use POSIX timer API for wake alarms instead of OSI callouts.
[android-x86/system-bt.git] / osi / include / atomic.h
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 #pragma once
20
21 #include <stdbool.h>
22 #include <stdint.h>
23
24 // Set of atomic operations to work on data structures.
25 // The atomic type data should only be manipulated by these functions.
26 // This uses the gcc built in functions.
27 //  gcc doc section 6.50 "Built-in functions for memory model aware atomic operations"
28 //
29 // Data types:
30 // atomic_<name>_t
31 //
32 // e.g.
33 //  atomic_s32_t for a signed 32 bit integer.
34 //  atomic_u32_t for an unsigned 32 bit integer.
35 //
36 // Functions:
37 // atomic_<operation>_<name>(atomic_t *, ...)
38 //
39 // e.g.
40 //  uint32_t atomic_dec_prefix_u32(volatile atomic_u32_t *atomic)
41 //
42 // The prefix/postfix classification corresponds which value is returned
43 // from the function call, the old or the new one.
44
45 #if defined(GCC_VERSION) && GCC_VERSION < 40700
46 #warning "Atomics not supported"
47 #endif
48
49 #define ATOMIC_TYPE(name, type) \
50   struct atomic_##name { \
51     type _val; \
52 }; \
53 typedef struct atomic_##name atomic_##name##_t;
54
55 #define ATOMIC_STORE(name, type, sz) \
56 static inline void atomic_store_##name(volatile atomic_##name##_t *atomic, type val) { \
57   __atomic_store_##sz(&atomic->_val, val, __ATOMIC_SEQ_CST); \
58 }
59
60 #define ATOMIC_LOAD(name, type, sz) \
61 static inline type atomic_load_##name(volatile atomic_##name##_t *atomic) { \
62   return __atomic_load_##sz(&atomic->_val, __ATOMIC_SEQ_CST); \
63 }
64
65 // Returns value after operation, e.g. new value
66 #define ATOMIC_INC_PREFIX(name, type, sz) \
67 static inline type atomic_inc_prefix_##name(volatile atomic_##name##_t *atomic) { \
68   return __atomic_add_fetch_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
69 }
70
71 // Returns value after operation, e.g. new value
72 #define ATOMIC_DEC_PREFIX(name, type, sz) \
73 static inline type atomic_dec_prefix_##name(volatile atomic_##name##_t *atomic) { \
74   return __atomic_sub_fetch_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
75 }
76
77 // Returns value before operation, e.g. old value
78 #define ATOMIC_INC_POSTFIX(name, type, sz) \
79 static inline type atomic_inc_postfix_##name(volatile atomic_##name##_t *atomic) { \
80   return __atomic_fetch_add_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
81 }
82
83 // Returns value before operation, e.g. old value
84 #define ATOMIC_DEC_POSTFIX(name, type, sz) \
85 static inline type atomic_dec_postfix_##name(volatile atomic_##name##_t *atomic) { \
86   return __atomic_fetch_sub_##sz(atomic, 1, __ATOMIC_SEQ_CST); \
87 }
88
89 // Returns value after operation, e.g. new value
90 #define ATOMIC_ADD(name, type, sz) \
91 static inline type atomic_add_##name(volatile atomic_##name##_t *atomic, type val) { \
92   return __atomic_add_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \
93 }
94
95 // Returns value after operation, e.g. new value
96 #define ATOMIC_SUB(name, type, sz) \
97 static inline type atomic_sub_##name(volatile atomic_##name##_t *atomic, type val) { \
98   return __atomic_sub_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \
99 }
100
101 #define ATOMIC_MAKE(name, type, sz) \
102   ATOMIC_TYPE(name, type) \
103   ATOMIC_STORE(name, type, sz) \
104   ATOMIC_LOAD(name, type, sz) \
105   ATOMIC_INC_PREFIX(name, type, sz) \
106   ATOMIC_DEC_PREFIX(name, type, sz) \
107   ATOMIC_INC_POSTFIX(name, type, sz) \
108   ATOMIC_DEC_POSTFIX(name, type, sz) \
109   ATOMIC_ADD(name, type, sz) \
110   ATOMIC_SUB(name, type, sz)
111
112 ATOMIC_MAKE(s32, int32_t, 4)
113 ATOMIC_MAKE(u32, uint32_t, 4)
114 ATOMIC_MAKE(s64, int64_t, 8)
115 ATOMIC_MAKE(u64, uint64_t, 8)