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#include <climits> 16d9f0492fSopenharmony_ci#include <thread> 17d9f0492fSopenharmony_ci#include <cstdint> 18d9f0492fSopenharmony_ci#include <gtest/gtest.h> 19d9f0492fSopenharmony_ci 20d9f0492fSopenharmony_ci#include "param_atomic.h" 21d9f0492fSopenharmony_ci#include "param_common.h" 22d9f0492fSopenharmony_ci#include "param_utils.h" 23d9f0492fSopenharmony_ci 24d9f0492fSopenharmony_ciusing namespace testing::ext; 25d9f0492fSopenharmony_ciconst int THREAD_NUM = 5; 26d9f0492fSopenharmony_ciconst int MAX_NUM = 10; 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_cinamespace init_ut { 29d9f0492fSopenharmony_ciclass AtomicUnitTest : public testing::Test { 30d9f0492fSopenharmony_cipublic: 31d9f0492fSopenharmony_ci static void SetUpTestCase(void) {}; 32d9f0492fSopenharmony_ci static void TearDownTestCase(void) {}; 33d9f0492fSopenharmony_ci void SetUp(void) {}; 34d9f0492fSopenharmony_ci void TearDown(void) {}; 35d9f0492fSopenharmony_ci}; 36d9f0492fSopenharmony_ci 37d9f0492fSopenharmony_ci/** 38d9f0492fSopenharmony_ci * 测试方法: 39d9f0492fSopenharmony_ci * 1,create 线程,执行全局变量写操作 40d9f0492fSopenharmony_ci * store with dirty 41d9f0492fSopenharmony_ci * sleep 42d9f0492fSopenharmony_ci * store clear dirty 43d9f0492fSopenharmony_ci * store commit ++ 44d9f0492fSopenharmony_ci * 2,read 现成,执行全局变量读参数 45d9f0492fSopenharmony_ci * 46d9f0492fSopenharmony_ci */ 47d9f0492fSopenharmony_ciusing AtomicTestData = struct { 48d9f0492fSopenharmony_ci ATOMIC_UINT32 commitId; 49d9f0492fSopenharmony_ci uint32_t data; 50d9f0492fSopenharmony_ci}; 51d9f0492fSopenharmony_ci 52d9f0492fSopenharmony_cistatic AtomicTestData g_testData = { 0, 0 }; 53d9f0492fSopenharmony_ci 54d9f0492fSopenharmony_cistatic void *TestSetData(void *args) 55d9f0492fSopenharmony_ci{ 56d9f0492fSopenharmony_ci while (g_testData.data < MAX_NUM) { 57d9f0492fSopenharmony_ci uint32_t commitId = ATOMIC_LOAD_EXPLICIT(&g_testData.commitId, MEMORY_ORDER_RELAXED); 58d9f0492fSopenharmony_ci ATOMIC_STORE_EXPLICIT(&g_testData.commitId, commitId | PARAM_FLAGS_MODIFY, MEMORY_ORDER_RELAXED); 59d9f0492fSopenharmony_ci g_testData.data++; 60d9f0492fSopenharmony_ci usleep(200 * 1000); // 200 * 1000 wait 61d9f0492fSopenharmony_ci printf("TestSetData data: %d commit: %d \n", g_testData.data, g_testData.commitId & PARAM_FLAGS_COMMITID); 62d9f0492fSopenharmony_ci uint32_t flags = commitId & ~PARAM_FLAGS_COMMITID; 63d9f0492fSopenharmony_ci ATOMIC_STORE_EXPLICIT(&g_testData.commitId, (++commitId) | flags, MEMORY_ORDER_RELEASE); 64d9f0492fSopenharmony_ci futex_wake(&g_testData.commitId, INT_MAX); 65d9f0492fSopenharmony_ci usleep(100); // 100 wait 66d9f0492fSopenharmony_ci } 67d9f0492fSopenharmony_ci return nullptr; 68d9f0492fSopenharmony_ci} 69d9f0492fSopenharmony_ci 70d9f0492fSopenharmony_cistatic inline uint32_t TestReadCommitId(AtomicTestData *entry) 71d9f0492fSopenharmony_ci{ 72d9f0492fSopenharmony_ci uint32_t commitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, MEMORY_ORDER_ACQUIRE); 73d9f0492fSopenharmony_ci while (commitId & PARAM_FLAGS_MODIFY) { 74d9f0492fSopenharmony_ci futex_wait(&entry->commitId, commitId); 75d9f0492fSopenharmony_ci commitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, MEMORY_ORDER_ACQUIRE); 76d9f0492fSopenharmony_ci } 77d9f0492fSopenharmony_ci return commitId & PARAM_FLAGS_COMMITID; 78d9f0492fSopenharmony_ci} 79d9f0492fSopenharmony_ci 80d9f0492fSopenharmony_cistatic inline int TestReadParamValue(AtomicTestData *entry, uint32_t *commitId) 81d9f0492fSopenharmony_ci{ 82d9f0492fSopenharmony_ci uint32_t data; 83d9f0492fSopenharmony_ci uint32_t id = *commitId; 84d9f0492fSopenharmony_ci do { 85d9f0492fSopenharmony_ci *commitId = id; 86d9f0492fSopenharmony_ci data = entry->data; 87d9f0492fSopenharmony_ci id = TestReadCommitId(entry); 88d9f0492fSopenharmony_ci } while (*commitId != id); // if change, must read 89d9f0492fSopenharmony_ci return data; 90d9f0492fSopenharmony_ci} 91d9f0492fSopenharmony_ci 92d9f0492fSopenharmony_cistatic void *TestReadData(void *args) 93d9f0492fSopenharmony_ci{ 94d9f0492fSopenharmony_ci uint32_t data = 0; 95d9f0492fSopenharmony_ci while (data < MAX_NUM) { 96d9f0492fSopenharmony_ci uint32_t commitId = TestReadCommitId(&g_testData); 97d9f0492fSopenharmony_ci data = TestReadParamValue(&g_testData, &commitId); 98d9f0492fSopenharmony_ci printf("[ %d] TestReadData data: %d commit: %d \n", gettid(), data, commitId); 99d9f0492fSopenharmony_ci usleep(10); // 10 wait 100d9f0492fSopenharmony_ci } 101d9f0492fSopenharmony_ci return nullptr; 102d9f0492fSopenharmony_ci} 103d9f0492fSopenharmony_ci 104d9f0492fSopenharmony_ciHWTEST_F(AtomicUnitTest, Init_AtomicUnitTest_001, TestSize.Level0) 105d9f0492fSopenharmony_ci{ 106d9f0492fSopenharmony_ci printf("AtomicUnitTest_001 \n"); 107d9f0492fSopenharmony_ci pthread_t writeThread = 0; 108d9f0492fSopenharmony_ci pthread_t readThread[THREAD_NUM] = { 0 }; 109d9f0492fSopenharmony_ci pthread_create(&writeThread, nullptr, TestSetData, nullptr); 110d9f0492fSopenharmony_ci for (size_t i = 0; i < THREAD_NUM; i++) { 111d9f0492fSopenharmony_ci pthread_create(&readThread[i], nullptr, TestReadData, nullptr); 112d9f0492fSopenharmony_ci } 113d9f0492fSopenharmony_ci pthread_join(writeThread, nullptr); 114d9f0492fSopenharmony_ci printf("AtomicUnitTest_001 end \n"); 115d9f0492fSopenharmony_ci} 116d9f0492fSopenharmony_ci}