• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef BASE_STARTUP_PARAM_ATOMIC_H
17 #define BASE_STARTUP_PARAM_ATOMIC_H
18 #include <stdint.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 
24 #if (defined(PARAM_SUPPORT_STDATOMIC) || defined(__LITEOS_A__))
25 #include <pthread.h>
26 #include <stdatomic.h>
27 #endif
28 #if defined FUTEX_WAIT || defined FUTEX_WAKE
29 #include <linux/futex.h>
30 #endif
31 
32 #ifdef __cplusplus
33 #if __cplusplus
34 extern "C" {
35 #endif
36 #endif
37 
38 #ifdef __LITEOS_M__
39 #define ATOMIC_UINT32 uint32_t
40 #define ATOMIC_LLONG  long long
41 #define ATOMIC_INIT(commitId, value) *(commitId) = (value)
42 #define ATOMIC_LOAD_EXPLICIT(commitId, order) *(commitId)
43 #define ATOMIC_STORE_EXPLICIT(commitId, value, order) *(commitId) = (value)
44 #define ATOMIC_UINT64_INIT(commitId, value) *(commitId) = (value)
45 #define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) *(commitId)
46 #define ATOMIC_UINT64_STORE_EXPLICIT(commitId, value, order) *(commitId) = (value)
47 #define ATOMIC_SYNC_OR_AND_FETCH(commitId, value, order) *(commitId) |= (value)
48 #define ATOMIC_SYNC_ADD_AND_FETCH(commitId, value, order) *(commitId) += (value)
49 
50 #define futex_wake(ftx, count) (void)(ftx)
51 #define futex_wait(ftx, value) (void)(ftx)
52 #else
53 
54 // support futex
55 #ifndef __NR_futex
56 #define PARAM_NR_FUTEX 202 /* syscall number */
57 #else
58 #define PARAM_NR_FUTEX __NR_futex
59 #endif
60 
61 #if !(defined FUTEX_WAIT || defined FUTEX_WAKE)
62 #define FUTEX_WAIT 0
63 #define FUTEX_WAKE 1
64 #define PARAM_FUTEX(ftx, op, value, timeout, bitset)                       \
65     do {                                                                   \
66         struct timespec d_timeout = { 0, 1000 * 1000 * (timeout) };        \
67         syscall(PARAM_NR_FUTEX, ftx, op, value, &d_timeout, NULL, bitset); \
68     } while (0)
69 
70 #define futex_wake(ftx, count) PARAM_FUTEX(ftx, FUTEX_WAKE, count, 0, 0)
71 #define futex_wait(ftx, value) PARAM_FUTEX(ftx, FUTEX_WAIT, value, 100, 0)
72 #endif
73 
74 #if (defined(PARAM_SUPPORT_STDATOMIC) || defined(__LITEOS_A__))
75 #define MEMORY_ORDER_RELAXED memory_order_relaxed
76 #define MEMORY_ORDER_CONSUME memory_order_consume
77 #define MEMORY_ORDER_ACQUIRE memory_order_acquire
78 #define MEMORY_ORDER_RELEASE memory_order_release
79 
80 #define ATOMIC_UINT32 atomic_uint
81 #define ATOMIC_LLONG atomic_llong
82 #define ATOMIC_INIT(commitId, value) atomic_init((commitId), (value))
83 #define ATOMIC_UINT64_INIT(commitId, value) atomic_init((commitId), (value))
84 #define ATOMIC_LOAD_EXPLICIT(commitId, order) atomic_load_explicit((commitId), (order))
85 #define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) atomic_load_explicit((commitId), order)
86 #define ATOMIC_STORE_EXPLICIT(commitId, value, order) atomic_store_explicit((commitId), (value), (order))
87 #define ATOMIC_UINT64_STORE_EXPLICIT(commitId, value, order) atomic_store_explicit((commitId), (value), (order))
88 #define ATOMIC_SYNC_OR_AND_FETCH(commitId, value, order) atomic_fetch_or_explicit((commitId), (value), (order))
89 #define ATOMIC_SYNC_ADD_AND_FETCH(commitId, value, order) atomic_fetch_add_explicit((commitId), (value), (order))
90 
91 #else
92 
93 #define MEMORY_ORDER_RELAXED 0
94 #define MEMORY_ORDER_CONSUME 1
95 #define MEMORY_ORDER_ACQUIRE 2
96 #define MEMORY_ORDER_RELEASE 3
97 
98 #define ATOMIC_UINT32 uint32_t
99 #define ATOMIC_LLONG int64_t
100 
101 static inline void param_atomic_store(ATOMIC_UINT32 *ptr, uint32_t value, int order)
102 {
103     __sync_lock_test_and_set(ptr, value);
104     if (order == MEMORY_ORDER_RELEASE) {
105         __sync_synchronize();
106     }
107 }
108 
109 static inline void param_atomic_uint64_store(ATOMIC_LLONG *ptr, int64_t value, int order)
110 {
111     __sync_lock_test_and_set(ptr, value);
112     if (order == MEMORY_ORDER_RELEASE) {
113         __sync_synchronize();
114     }
115 }
116 
117 static inline void param_atomic_init(ATOMIC_UINT32 *ptr, uint32_t value)
118 {
119     *ptr = 0;
120     __sync_fetch_and_add(ptr, value, 0);
121 }
122 
123 static inline void param_atomic_uint64_init(ATOMIC_LLONG *ptr, int64_t value)
124 {
125     *ptr = 0;
126     __sync_fetch_and_add(ptr, value, 0);
127 }
128 
129 static inline ATOMIC_UINT32 param_atomic_load(ATOMIC_UINT32 *ptr, int order)
130 {
131     return *((volatile ATOMIC_UINT32 *)ptr);
132 }
133 
134 static inline ATOMIC_LLONG param_atomic_uint64_load(ATOMIC_LLONG *ptr, int order)
135 {
136     return *((volatile ATOMIC_LLONG *)ptr);
137 }
138 
139 #define ATOMIC_INIT(commitId, value) param_atomic_init((commitId), (value))
140 #define ATOMIC_UINT64_INIT(commitId, value) param_atomic_uint64_init((commitId), (value))
141 #define ATOMIC_LOAD_EXPLICIT(commitId, order) param_atomic_load((commitId), order)
142 #define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) param_atomic_uint64_load((commitId), order)
143 #define ATOMIC_STORE_EXPLICIT(commitId, value, order) param_atomic_store((commitId), (value), (order))
144 #define ATOMIC_UINT64_STORE_EXPLICIT(commitId, value, order) param_atomic_uint64_store((commitId), (value), (order))
145 #define ATOMIC_SYNC_OR_AND_FETCH(commitId, value, order) __sync_or_and_fetch((commitId), (value))
146 #define ATOMIC_SYNC_ADD_AND_FETCH(commitId, value, order) __sync_add_and_fetch((commitId), (value))
147 #endif
148 #endif // __LITEOS_M__
149 #ifdef __cplusplus
150 #if __cplusplus
151 }
152 #endif
153 #endif
154 
155 #endif // BASE_STARTUP_PARAM_ATOMIC_H