Files
phs_v1.0.1.0/base/startup/init/test/unittest/param/atomic_unittest.cpp
2024-09-27 19:16:49 +08:00

116 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <climits>
#include <thread>
#include <cstdint>
#include <gtest/gtest.h>
#include "param_atomic.h"
#include "param_common.h"
#include "param_utils.h"
using namespace testing::ext;
const int THREAD_NUM = 5;
const int MAX_NUM = 10;
namespace init_ut {
class AtomicUnitTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp(void) {};
void TearDown(void) {};
};
/**
* 测试方法:
* 1create 线程,执行全局变量写操作
* store with dirty
* sleep
* store clear dirty
* store commit ++
* 2read 现成,执行全局变量读参数
*
*/
using AtomicTestData = struct {
ATOMIC_UINT32 commitId;
uint32_t data;
};
static AtomicTestData g_testData = { 0, 0 };
static void *TestSetData(void *args)
{
while (g_testData.data < MAX_NUM) {
uint32_t commitId = ATOMIC_LOAD_EXPLICIT(&g_testData.commitId, MEMORY_ORDER_RELAXED);
ATOMIC_STORE_EXPLICIT(&g_testData.commitId, commitId | PARAM_FLAGS_MODIFY, MEMORY_ORDER_RELAXED);
g_testData.data++;
usleep(200 * 1000); // 200 * 1000 wait
printf("TestSetData data: %d commit: %d \n", g_testData.data, g_testData.commitId & PARAM_FLAGS_COMMITID);
uint32_t flags = commitId & ~PARAM_FLAGS_COMMITID;
ATOMIC_STORE_EXPLICIT(&g_testData.commitId, (++commitId) | flags, MEMORY_ORDER_RELEASE);
futex_wake(&g_testData.commitId, INT_MAX);
usleep(100); // 100 wait
}
return nullptr;
}
static inline uint32_t TestReadCommitId(AtomicTestData *entry)
{
uint32_t commitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, MEMORY_ORDER_ACQUIRE);
while (commitId & PARAM_FLAGS_MODIFY) {
futex_wait(&entry->commitId, commitId);
commitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, MEMORY_ORDER_ACQUIRE);
}
return commitId & PARAM_FLAGS_COMMITID;
}
static inline int TestReadParamValue(AtomicTestData *entry, uint32_t *commitId)
{
uint32_t data;
uint32_t id = *commitId;
do {
*commitId = id;
data = entry->data;
id = TestReadCommitId(entry);
} while (*commitId != id); // if change, must read
return data;
}
static void *TestReadData(void *args)
{
uint32_t data = 0;
while (data < MAX_NUM) {
uint32_t commitId = TestReadCommitId(&g_testData);
data = TestReadParamValue(&g_testData, &commitId);
printf("[ %d] TestReadData data: %d commit: %d \n", gettid(), data, commitId);
usleep(10); // 10 wait
}
return nullptr;
}
HWTEST_F(AtomicUnitTest, AtomicUnitTest_001, TestSize.Level0)
{
printf("AtomicUnitTest_001 \n");
pthread_t writeThread = 0;
pthread_t readThread[THREAD_NUM] = { 0 };
pthread_create(&writeThread, nullptr, TestSetData, nullptr);
for (size_t i = 0; i < THREAD_NUM; i++) {
pthread_create(&readThread[i], nullptr, TestReadData, nullptr);
}
pthread_join(writeThread, nullptr);
printf("AtomicUnitTest_001 end \n");
}
}