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 34extern "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#define futex_wake_private(ftx, count) (void)(ftx) 53#define futex_wait_private(ftx, value) (void)(ftx) 54#else 55 56// support futex 57#ifndef __NR_futex 58#define PARAM_NR_FUTEX 202 /* syscall number */ 59#else 60#define PARAM_NR_FUTEX __NR_futex 61#endif 62 63#if !(defined FUTEX_WAIT || defined FUTEX_WAKE) 64#define FUTEX_WAIT 0 65#define FUTEX_WAKE 1 66#define FUTEX_PRIVATE_FLAG 128 67#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) 68#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) 69 70#define PARAM_FUTEX(ftx, op, value, timeout, bitset) \ 71 do { \ 72 struct timespec d_timeout = { 0, 1000 * 1000 * (timeout) }; \ 73 syscall(PARAM_NR_FUTEX, ftx, op, value, &d_timeout, NULL, bitset); \ 74 } while (0) 75 76#define futex_wake(ftx, count) PARAM_FUTEX(ftx, FUTEX_WAKE, count, 0, 0) 77#define futex_wait(ftx, value) PARAM_FUTEX(ftx, FUTEX_WAIT, value, 100, 0) 78#define futex_wake_private(ftx, count) PARAM_FUTEX(ftx, FUTEX_WAKE_PRIVATE, count, 0, 0) 79#define futex_wait_private(ftx, value) PARAM_FUTEX(ftx, FUTEX_WAIT_PRIVATE, value, 100, 0) 80#endif 81 82#if (defined(PARAM_SUPPORT_STDATOMIC) || defined(__LITEOS_A__)) 83#define MEMORY_ORDER_RELAXED memory_order_relaxed 84#define MEMORY_ORDER_CONSUME memory_order_consume 85#define MEMORY_ORDER_ACQUIRE memory_order_acquire 86#define MEMORY_ORDER_RELEASE memory_order_release 87 88#define ATOMIC_UINT32 atomic_uint 89#define ATOMIC_LLONG atomic_llong 90#define ATOMIC_INIT(commitId, value) atomic_init((commitId), (value)) 91#define ATOMIC_UINT64_INIT(commitId, value) atomic_init((commitId), (value)) 92#define ATOMIC_LOAD_EXPLICIT(commitId, order) atomic_load_explicit((commitId), (order)) 93#define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) atomic_load_explicit((commitId), order) 94#define ATOMIC_STORE_EXPLICIT(commitId, value, order) atomic_store_explicit((commitId), (value), (order)) 95#define ATOMIC_UINT64_STORE_EXPLICIT(commitId, value, order) atomic_store_explicit((commitId), (value), (order)) 96#define ATOMIC_SYNC_OR_AND_FETCH(commitId, value, order) atomic_fetch_or_explicit((commitId), (value), (order)) 97#define ATOMIC_SYNC_ADD_AND_FETCH(commitId, value, order) atomic_fetch_add_explicit((commitId), (value), (order)) 98 99#else 100 101#define MEMORY_ORDER_RELAXED 0 102#define MEMORY_ORDER_CONSUME 1 103#define MEMORY_ORDER_ACQUIRE 2 104#define MEMORY_ORDER_RELEASE 3 105 106#define ATOMIC_UINT32 uint32_t 107#define ATOMIC_LLONG int64_t 108 109static inline void param_atomic_store(ATOMIC_UINT32 *ptr, uint32_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 117static inline void param_atomic_uint64_store(ATOMIC_LLONG *ptr, int64_t value, int order) 118{ 119 __sync_lock_test_and_set(ptr, value); 120 if (order == MEMORY_ORDER_RELEASE) { 121 __sync_synchronize(); 122 } 123} 124 125static inline void param_atomic_init(ATOMIC_UINT32 *ptr, uint32_t value) 126{ 127 *ptr = 0; 128 __sync_fetch_and_add(ptr, value, 0); 129} 130 131static inline void param_atomic_uint64_init(ATOMIC_LLONG *ptr, int64_t value) 132{ 133 *ptr = 0; 134 __sync_fetch_and_add(ptr, value, 0); 135} 136 137static inline ATOMIC_UINT32 param_atomic_load(ATOMIC_UINT32 *ptr, int order) 138{ 139 return *((volatile ATOMIC_UINT32 *)ptr); 140} 141 142static inline ATOMIC_LLONG param_atomic_uint64_load(ATOMIC_LLONG *ptr, int order) 143{ 144 return *((volatile ATOMIC_LLONG *)ptr); 145} 146 147#define ATOMIC_INIT(commitId, value) param_atomic_init((commitId), (value)) 148#define ATOMIC_UINT64_INIT(commitId, value) param_atomic_uint64_init((commitId), (value)) 149#define ATOMIC_LOAD_EXPLICIT(commitId, order) param_atomic_load((commitId), order) 150#define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) param_atomic_uint64_load((commitId), order) 151#define ATOMIC_STORE_EXPLICIT(commitId, value, order) param_atomic_store((commitId), (value), (order)) 152#define ATOMIC_UINT64_STORE_EXPLICIT(commitId, value, order) param_atomic_uint64_store((commitId), (value), (order)) 153#define ATOMIC_SYNC_OR_AND_FETCH(commitId, value, order) __sync_or_and_fetch((commitId), (value)) 154#define ATOMIC_SYNC_ADD_AND_FETCH(commitId, value, order) __sync_add_and_fetch((commitId), (value)) 155#endif 156#endif // __LITEOS_M__ 157#ifdef __cplusplus 158#if __cplusplus 159} 160#endif 161#endif 162 163#endif // BASE_STARTUP_PARAM_ATOMIC_H