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