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