From 59d1e7ff624d37f61badcf88afaaa112259cee15 Mon Sep 17 00:00:00 2001 From: liujia178 Date: Fri, 1 Dec 2023 14:27:35 +0800 Subject: [PATCH] add benchmark testitem datetime rwlock and ashemem. Signed-off-by: liujia178 --- base/test/benchmarktest/BUILD.gn | 23 + .../ashemem_benchmark_test/BUILD.gn | 35 ++ .../ashemem_benchmark_test.cpp | 505 ++++++++++++++++++ base/test/benchmarktest/assert.h | 91 ++++ .../datatime_benchmark_test/BUILD.gn | 35 ++ .../datatime_benchmark_test.cpp | 215 ++++++++ base/test/benchmarktest/log.h | 36 ++ .../rwlock_benchmark_test/BUILD.gn | 35 ++ .../rwlock_benchmark_test.cpp | 237 ++++++++ bundle.json | 3 +- 10 files changed, 1214 insertions(+), 1 deletion(-) create mode 100644 base/test/benchmarktest/BUILD.gn create mode 100644 base/test/benchmarktest/ashemem_benchmark_test/BUILD.gn create mode 100644 base/test/benchmarktest/ashemem_benchmark_test/ashemem_benchmark_test.cpp create mode 100644 base/test/benchmarktest/assert.h create mode 100644 base/test/benchmarktest/datatime_benchmark_test/BUILD.gn create mode 100644 base/test/benchmarktest/datatime_benchmark_test/datatime_benchmark_test.cpp create mode 100644 base/test/benchmarktest/log.h create mode 100644 base/test/benchmarktest/rwlock_benchmark_test/BUILD.gn create mode 100644 base/test/benchmarktest/rwlock_benchmark_test/rwlock_benchmark_test.cpp diff --git a/base/test/benchmarktest/BUILD.gn b/base/test/benchmarktest/BUILD.gn new file mode 100644 index 0000000..c0ccf1d --- /dev/null +++ b/base/test/benchmarktest/BUILD.gn @@ -0,0 +1,23 @@ +# 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. + +group("benchmarktest") { + testonly = true + deps = [] + deps += [ + # deps file + "ashemem_benchmark_test:AshememTest", + "datatime_benchmark_test:DatatimeTest", + "rwlock_benchmark_test:RwlockTest", + ] +} diff --git a/base/test/benchmarktest/ashemem_benchmark_test/BUILD.gn b/base/test/benchmarktest/ashemem_benchmark_test/BUILD.gn new file mode 100644 index 0000000..0e6c174 --- /dev/null +++ b/base/test/benchmarktest/ashemem_benchmark_test/BUILD.gn @@ -0,0 +1,35 @@ +# 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. + +import("//build/test.gni") + +module_output_path = "commonlibrary_c_utils/ashemem" + +ohos_benchmarktest("AshememTest") { + module_out_path = module_output_path + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + sources = [ "ashemem_benchmark_test.cpp" ] + + deps = [ "//third_party/benchmark:benchmark" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog_base", + ] +} diff --git a/base/test/benchmarktest/ashemem_benchmark_test/ashemem_benchmark_test.cpp b/base/test/benchmarktest/ashemem_benchmark_test/ashemem_benchmark_test.cpp new file mode 100644 index 0000000..640a1aa --- /dev/null +++ b/base/test/benchmarktest/ashemem_benchmark_test/ashemem_benchmark_test.cpp @@ -0,0 +1,505 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include "directory_ex.h" +#include "securec.h" +#include "parcel.h" +#include "refbase.h" +#include "ashmem.h" +#include "../log.h" +#include "../assert.h" +using namespace std; + +namespace OHOS { +namespace { + +const int MAX_PARCEL_SIZE = 1000; +char g_data[MAX_PARCEL_SIZE]; +const int32_t MEMORY_SIZE = 1024; +const std::string MEMORY_CONTENT = "HelloWorld2020\0"; +const std::string MEMORY_NAME = "Test SharedMemory\0"; + +class BenchmarkAshmemTest : public benchmark::Fixture { +public: + BenchmarkAshmemTest() + { + Iterations(iterations); + Repetitions(repetitions); + ReportAggregatesOnly(true); + } + + ~BenchmarkAshmemTest() override = default; + void SetUp(const ::benchmark::State& state) override + { + }; + + void TearDown(const ::benchmark::State& state) override + { + for (int i = 0; i < MAX_PARCEL_SIZE; i++) + { + g_data[i] = 0; + } + } + +protected: + const int32_t repetitions = 3; + const int32_t iterations = 1000; +}; + +/** + * @tc.name: test_ashmem_WriteAndRead_001 + * @tc.desc: create and map ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_WriteAndRead_001)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_001 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + AssertEqual(ashmem->GetAshmemSize(), MEMORY_SIZE, + "ashmem->GetAshmemSize() == MEMORY_SIZE did not equal true as expected.", state); + + bool ret = ashmem->MapAshmem(PROT_READ | PROT_WRITE); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_001 end."); +} + +/** + * @tc.name: test_ashmem_WriteAndRead_002 + * @tc.desc: write to and read from ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_WriteAndRead_002)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_002 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT)); + AssertTrue(ret, "ret did not equal true as expected.", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertUnequal(readData, nullptr, "readData != nullptr did not equal true as expected.", state); + + const char *readContent = reinterpret_cast(readData); + AssertEqual(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0, + "memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)) did not equal 0 as expected.", state); + + readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT)); + AssertUnequal(readData, nullptr, "readData != nullptr did not equal true as expected.", state); + + readContent = reinterpret_cast(readData); + AssertEqual(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0, + "memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)) did not equal 0 as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_002 end."); +} + +/** + * @tc.name: test_ashmem_WriteAndRead_003 + * @tc.desc: test read-only ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_WriteAndRead_003)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_003 begin"); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ashmem->UnmapAshmem(); + + ret = ashmem->MapReadOnlyAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT)); + AssertFalse(ret, "ret did not equal false", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertUnequal(readData, nullptr, "readData != nullptr did not equal true as expected.", state); + + const char *readContent = reinterpret_cast(readData); + AssertEqual(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0, + "memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)) did not equal 0 as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_003 end."); +} + +/** + * @tc.name: test_ashmem_WriteAndRead_004 + * @tc.desc: set read-only protection and map again + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_WriteAndRead_004)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_004 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ashmem->UnmapAshmem(); + + ret = ashmem->SetProtection(PROT_READ); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->MapReadAndWriteAshmem(); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->MapReadOnlyAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertUnequal(readData, nullptr, "readData != nullptr did not equal true as expected.", state); + + const char *readContent = reinterpret_cast(readData); + AssertEqual(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0, + "memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)) did not equal 0 as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_004 end."); +} + +/** + * @tc.name: test_ashmem_WriteAndRead_005 + * @tc.desc: set read-only protection without mapping again + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_WriteAndRead_005)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_005 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->SetProtection(PROT_READ); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertFalse(ret, "ret did not equal false", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertUnequal(readData, nullptr, "readData != nullptr did not equal true as expected.", state); + + const char *readContent = reinterpret_cast(readData); + AssertEqual(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0, + "memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)) did not equal 0 as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_WriteAndRead_005 end."); +} + + +/** + * @tc.name: test_ashmem_InvalidOperation_001 + * @tc.desc: create invalid-size ashmem or set invalid protection type + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_001)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_001 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), -1); + AssertEqual(ashmem, nullptr, "ashmem == nullptr did not equal true as expected.", state); + + ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->SetProtection(-1); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_001 end."); +} + +/** + * @tc.name: test_ashmem_InvalidOperation_002 + * @tc.desc: map after closing ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_002)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_002 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + ashmem->CloseAshmem(); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertFalse(ret, "ret did not equal false", state); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_002 end."); +} + +/** + * @tc.name: test_ashmem_InvalidOperation_003 + * @tc.desc: write or read after closing ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_003)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_003 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ashmem->CloseAshmem(); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertFalse(ret, "ret did not equal false", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertEqual(readData, nullptr, "readData == nullptr did not equal true as expected.", state); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_003 end."); +} + +/** + * @tc.name: test_ashmem_InvalidOperation_004 + * @tc.desc: write or read after unmapping ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_004)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_004 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ashmem->UnmapAshmem(); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0); + AssertFalse(ret, "ret did not equal false", state); + + auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0); + AssertEqual(readData, nullptr, "readData == nullptr did not equal true as expected.", state); + + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_004 end."); +} + +/** + * @tc.name: test_ashmem_InvalidOperation_005 + * @tc.desc: expand protection type + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_005)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_005 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->SetProtection(PROT_WRITE); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->SetProtection(PROT_READ); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->SetProtection(PROT_READ | PROT_WRITE); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->SetProtection(PROT_NONE); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->SetProtection(PROT_READ); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_005 end."); +} + +/** + * @tc.name: test_ashmem_InvalidOperation_006 + * @tc.desc: test invalid input or test invalid operation + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_InvalidOperation_006)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_006 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + + bool ret = ashmem->MapReadAndWriteAshmem(); + AssertTrue(ret, "ret did not equal true as expected.", state); + + ret = ashmem->WriteToAshmem(nullptr, sizeof(MEMORY_CONTENT), 0); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), MEMORY_SIZE+1); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), -1); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), MEMORY_SIZE+1, 0); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), -1, 0); + AssertFalse(ret, "ret did not equal false", state); + + ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), MEMORY_SIZE); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + + ashmem->GetAshmemSize(); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->GetProtection(); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->UnmapAshmem(); + AssertFalse(ret, "ret did not equal false", state); + + ashmem->CloseAshmem(); + AssertFalse(ret, "ret did not equal false", state); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_InvalidOperation_006 end."); +} + +/** + * @tc.name: test_ashmem_constructor_001 + * @tc.desc: test Ashmem constructor + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_constructor_001)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_constructor_001 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "Failed to create Ashmem object.", state); + + int fd = ashmem->GetAshmemFd(); + int32_t size = ashmem->GetAshmemSize(); + AssertFalse((fd <= 0 || size <= 0), "Invalid file descriptor or size obtained from Ashmem.", state); + + sptr newAshmem = new Ashmem(fd, size); + AssertUnequal(newAshmem, nullptr, "Failed to create new Ashmem object with constructor.", state); + + int newFd = newAshmem->GetAshmemFd(); + int32_t newSize = newAshmem->GetAshmemSize(); + AssertFalse((newFd != fd || newSize != size), + "Mismatch in file descriptor or size in new Ashmem object.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + newAshmem->UnmapAshmem(); + newAshmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_constructor_001 end."); +} + +/** + * @tc.name: test_ashmem_ConstructorAndDestructor_001 + * @tc.desc: create and delete ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_ConstructorAndDestructor_001)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_ConstructorAndDestructor_001 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "ashmem != nullptr did not equal true as expected.", state); + AssertEqual(ashmem->GetAshmemSize(), MEMORY_SIZE, + "ashmem->GetAshmemSize() == MEMORY_SIZE did not equal true as expected.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_ConstructorAndDestructor_001 end."); +} + +/** + * @tc.name: test_ashmem_GetAshmemFd_001 + * @tc.desc: test getting file descriptor of ashmem + * @tc.type: FUNC + */ +BENCHMARK_F(BenchmarkAshmemTest, test_ashmem_GetAshmemFd_001)(benchmark::State& state) +{ + BENCHMARK_LOGD("AshmemTest test_ashmem_GetAshmemFd_001 start."); + while (state.KeepRunning()) { + sptr ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE); + AssertUnequal(ashmem, nullptr, "Failed to create Ashmem object.", state); + + int fd = ashmem->GetAshmemFd(); + AssertGreaterThan(fd, 0, "Invalid file descriptor obtained from Ashmem.", state); + + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } + BENCHMARK_LOGD("AshmemTest test_ashmem_GetAshmemFd_001 end."); +} +} // namespace +} // namespace OHOS +// Run the benchmark +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/base/test/benchmarktest/assert.h b/base/test/benchmarktest/assert.h new file mode 100644 index 0000000..e9ebc2a --- /dev/null +++ b/base/test/benchmarktest/assert.h @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#ifndef ASSERT_H +#define ASSERT_H + +#include + +template +void AssertEqual(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 != t2) { + state.SkipWithError(printInfo); + } +} + +template +void AssertUnequal(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 == t2) { + state.SkipWithError(printInfo); + } +} + +template +void AssertFalse(const T &t, const char* printInfo, benchmark::State& state) +{ + if (t) { + state.SkipWithError(printInfo); + } +} + +template +void AssertTrue(const T &t, const char* printInfo, benchmark::State& state) +{ + if (!t) { + state.SkipWithError(printInfo); + } +} + +template +void AssertLessThan(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 >= t2) { + state.SkipWithError(printInfo); + } +} + +template +void AssertLessThanOrEqual(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 > t2) { + state.SkipWithError(printInfo); + } +} + +template +void AssertGreaterThan(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 <= t2) { + state.SkipWithError(printInfo); + } +} + +template +void AssertGreaterThanOrEqual(const T1 &t1, const T2 &t2, const char* printInfo, benchmark::State& state) +{ + if (t1 < t2) { + state.SkipWithError(printInfo); + } +} + +void AssertStringEqual(const char* str1, const char* str2, const char* printInfo, benchmark::State& state) +{ + if (strcmp(str1, str2) != 0) { + state.SkipWithError(printInfo); + } +} +#endif \ No newline at end of file diff --git a/base/test/benchmarktest/datatime_benchmark_test/BUILD.gn b/base/test/benchmarktest/datatime_benchmark_test/BUILD.gn new file mode 100644 index 0000000..6342a79 --- /dev/null +++ b/base/test/benchmarktest/datatime_benchmark_test/BUILD.gn @@ -0,0 +1,35 @@ +# 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. + +import("//build/test.gni") + +module_output_path = "commonlibrary_c_utils/datatime" + +ohos_benchmarktest("DatatimeTest") { + module_out_path = module_output_path + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + sources = [ "datatime_benchmark_test.cpp" ] + + deps = [ "//third_party/benchmark:benchmark" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog_base", + ] +} diff --git a/base/test/benchmarktest/datatime_benchmark_test/datatime_benchmark_test.cpp b/base/test/benchmarktest/datatime_benchmark_test/datatime_benchmark_test.cpp new file mode 100644 index 0000000..20ce4af --- /dev/null +++ b/base/test/benchmarktest/datatime_benchmark_test/datatime_benchmark_test.cpp @@ -0,0 +1,215 @@ +/* + * 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 +#include "datetime_ex.h" +#include +#include +#include "../log.h" +#include "../assert.h" +using namespace std; + +namespace OHOS { +namespace { + +class BenchmarkDateTimeTest : public benchmark::Fixture { +public: + BenchmarkDateTimeTest() + { + Iterations(iterations); + Repetitions(repetitions); + ReportAggregatesOnly(); + } + + ~BenchmarkDateTimeTest() override = default; + void SetUp(const ::benchmark::State& state) override + { + } + + void TearDown(const ::benchmark::State& state) override + { + } + +protected: + const int32_t repetitions = 3; + const int32_t iterations = 1000; +}; + +const int64_t SLEEP_DURATION_MICROSECONDS = 100; + +/* + * @tc.name: testTimecover001 + * @tc.desc: convert all letters of str to uppercase + */ +BENCHMARK_F(BenchmarkDateTimeTest, testTimecover001)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testTimecover001 start."); + while (state.KeepRunning()) { + const int64_t second = 20; + const int64_t nanosecondsInASecond = 20000000000; + AssertEqual(SecToNanosec(second), nanosecondsInASecond, + "SecToNanosec(second) did not equal nanosecondsInASecond as expected.", state); + const int64_t millsec = 10; + const int64_t nanosecondsInAMillisecond = 10000000; + AssertEqual(MillisecToNanosec(millsec), nanosecondsInAMillisecond, + "MillisecToNanosec(millsec) did not equal nanosecondsInAMillisecond as expected.", state); + const int64_t microsec = 5; + const int64_t nanosecondsInAMicrosecond = 5000; + AssertEqual(MicrosecToNanosec(microsec), nanosecondsInAMicrosecond, + "MicrosecToNanosec(microsec) did not equal nanosecondsInAMicrosecond as expected.", state); + + const int64_t nanoces = 1000000000; + const int64_t secondsInANanosecond = 1; + const int64_t millisecondsInANanosecond = 1000; + const int64_t microsecondsInANanosecond = 1000000; + AssertEqual(NanosecToSec(nanoces), secondsInANanosecond, + "NanosecToSec(nanoces) did not equal secondsInANanosecond as expected.", state); + AssertEqual(NanosecToMillisec(nanoces), millisecondsInANanosecond, + "NanosecToMillisec(nanoces) did not equal millisecondsInANanosecond as expected.", state); + AssertEqual(NanosecToMicrosec(nanoces), microsecondsInANanosecond, + "NanosecToMicrosec(nanoces) did not equal microsecondsInANanosecond as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testTimecover001 end."); +} + +/* + * @tc.name: testTime001 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testTime001)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testTime001 start."); + while (state.KeepRunning()) { + int64_t second = GetSecondsSince1970ToNow(); + + struct tm curTime = {0}; + bool ret = GetSystemCurrentTime(&curTime); + AssertEqual(ret, true, "ret did not equal true as expected.", state); + ret = GetSystemCurrentTime(nullptr); + AssertEqual(ret, false, "ret did not equal false as expected.", state); + + int64_t second2 = GetSecondsSince1970ToPointTime(curTime); + AssertEqual(second, second2, "second did not equal second2 as expected.", state); + struct tm info; + info.tm_year = INT32_MIN; + info.tm_mon = 0; + info.tm_mday = 0; + info.tm_hour = 0; + info.tm_min = 0; + info.tm_sec = 0; + info.tm_isdst = 0; + const int64_t invalidReturnValue = -1; + second2 = GetSecondsSince1970ToPointTime(info); + AssertEqual(invalidReturnValue, second2, "invalidReturnValue did not equal second2 as expected.", state); + int64_t ret2 = GetSecondsBetween(curTime, info); + AssertTrue((ret2 = invalidReturnValue), "ret2 = invalidReturnValue did not equal true as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testTime001 end."); +} + +/* + * @tc.name: testTime002 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testTime002)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testTime002 start."); + while (state.KeepRunning()) { + int64_t days = GetDaysSince1970ToNow(); + int64_t seconds = GetSecondsSince1970ToNow(); + const int64_t secondsInAnHour = 3600; + const int64_t hoursInADay = 24; + int64_t resultdays = seconds / (secondsInAnHour * hoursInADay); + BENCHMARK_LOGD("DateTimeTest testTime002 days:%{public}lld result:%{public}lld seconds:%{public}lld", + days, resultdays, seconds); + AssertEqual(days, resultdays, "days did not equal resultdays as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testTime002 end."); +} + +/* + * @tc.name: testTime003 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testTime003)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testTime003 start."); + while (state.KeepRunning()) { + struct tm curTime = { 0 }; + bool ret = GetSystemCurrentTime(&curTime); + AssertEqual(ret, true, "ret did not equal true as expected.", state); + + struct tm curTime2 = { 0 }; + ret = GetSystemCurrentTime(&curTime2); + AssertEqual(ret, true, "ret did not equal true as expected.", state); + int64_t betweensec = GetSecondsBetween(curTime, curTime2); + AssertGreaterThanOrEqual(betweensec, 0, "betweensec >= 0 did not equal true as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testTime003 end."); +} + +/* + * @tc.name: testTime004 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testTime004)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testTime004 start."); + while (state.KeepRunning()) { + int timezone = 0; + bool ret = GetLocalTimeZone(timezone); + AssertEqual(ret, true, "ret did not equal true as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testTime004 end."); +} + +/* + * @tc.name: testGetTickCount001 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testGetTickCount001)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testGetTickCount001 start."); + while (state.KeepRunning()) { + int64_t begin = GetTickCount(); + usleep(SLEEP_DURATION_MICROSECONDS); + int64_t end = GetTickCount(); + + AssertGreaterThanOrEqual(end - begin, 0, "end - begin >= 0 did not equal true as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testGetTickCount001 end."); +} + +/* + * @tc.name: testGetMicroTickCount001 + * @tc.desc: datetime unit + */ +BENCHMARK_F(BenchmarkDateTimeTest, testGetMicroTickCount001)(benchmark::State& state) +{ + BENCHMARK_LOGD("DateTimeTest testGetMicroTickCount001 start."); + while (state.KeepRunning()) { + int64_t begin = GetMicroTickCount(); + usleep(SLEEP_DURATION_MICROSECONDS); + int64_t end = GetMicroTickCount(); + + AssertGreaterThanOrEqual(end - begin, 0, "end - begin >= 0 did not equal true as expected.", state); + } + BENCHMARK_LOGD("DateTimeTest testGetMicroTickCount001 end."); +} +} // namespace +} // namespace OHOS + +// Run the benchmark +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/base/test/benchmarktest/log.h b/base/test/benchmarktest/log.h new file mode 100644 index 0000000..19c2e78 --- /dev/null +++ b/base/test/benchmarktest/log.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef LOG_H +#define LOG_H + +#include "hilog_base/log_base.h" + +constexpr LogType BENCHMARK_LOG_TYPE = LOG_CORE; +constexpr unsigned int BENCHMARK_LOG_DOMAIN = 0xD003D00; +constexpr const char *BENCHMARK_LOG_TAG = "benchmark_test"; + +#define BENCHMARK_LOGF(...) \ + (void)HiLogBasePrint(BENCHMARK_LOG_TYPE, LOG_FATAL, BENCHMARK_LOG_DOMAIN, BENCHMARK_LOG_TAG, __VA_ARGS__) +#define BENCHMARK_LOGE(...) \ + (void)HiLogBasePrint(BENCHMARK_LOG_TYPE, LOG_ERROR, BENCHMARK_LOG_DOMAIN, BENCHMARK_LOG_TAG, __VA_ARGS__) +#define BENCHMARK_LOGW(...) \ + (void)HiLogBasePrint(BENCHMARK_LOG_TYPE, LOG_WARN, BENCHMARK_LOG_DOMAIN, BENCHMARK_LOG_TAG, __VA_ARGS__) +#define BENCHMARK_LOGI(...) \ + (void)HiLogBasePrint(BENCHMARK_LOG_TYPE, LOG_INFO, BENCHMARK_LOG_DOMAIN, BENCHMARK_LOG_TAG, __VA_ARGS__) +#define BENCHMARK_LOGD(...) \ + (void)HiLogBasePrint(BENCHMARK_LOG_TYPE, LOG_DEBUG, BENCHMARK_LOG_DOMAIN, BENCHMARK_LOG_TAG, __VA_ARGS__) + +#endif // LOG_H diff --git a/base/test/benchmarktest/rwlock_benchmark_test/BUILD.gn b/base/test/benchmarktest/rwlock_benchmark_test/BUILD.gn new file mode 100644 index 0000000..c3f9c10 --- /dev/null +++ b/base/test/benchmarktest/rwlock_benchmark_test/BUILD.gn @@ -0,0 +1,35 @@ +# 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. + +import("//build/test.gni") + +module_output_path = "commonlibrary_c_utils/rwlock" + +ohos_benchmarktest("RwlockTest") { + module_out_path = module_output_path + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + sources = [ "rwlock_benchmark_test.cpp" ] + + deps = [ "//third_party/benchmark:benchmark" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog_base", + ] +} diff --git a/base/test/benchmarktest/rwlock_benchmark_test/rwlock_benchmark_test.cpp b/base/test/benchmarktest/rwlock_benchmark_test/rwlock_benchmark_test.cpp new file mode 100644 index 0000000..a3c5767 --- /dev/null +++ b/base/test/benchmarktest/rwlock_benchmark_test/rwlock_benchmark_test.cpp @@ -0,0 +1,237 @@ +/* + * 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 +#include +#include +#include "rwlock.h" +#include "../log.h" +#include "../assert.h" + +using namespace std; + +namespace OHOS { +namespace { + +class BenchmarkRWLockTest : public benchmark::Fixture { +public: + BenchmarkRWLockTest() + { + Iterations(iterations); + Repetitions(repetitions); + ReportAggregatesOnly(); + } + + ~BenchmarkRWLockTest() override = default; + void SetUp(const ::benchmark::State& state) override + { + } + + void TearDown(const ::benchmark::State& state) override + { + } + +protected: + const int32_t repetitions = 3; + const int32_t iterations = 1000; +}; + +const int SLEEP_DURATION_MS = 4; + +// This class is designed for test RWLock. "buf" is protected by "rwLock". +class TestRWLock { +public: + TestRWLock():rwLock(), buf() {} + + explicit TestRWLock(bool writeFirst):rwLock(writeFirst), buf() {} + + void WriteStr(const string& str) + { + BENCHMARK_LOGD("RWLockTest void WriteStr is called."); + rwLock.LockWrite(); + for (auto it = str.begin(); it != str.end(); it++) { + buf.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(10)); // 10: Extend time of holding the lock + } + rwLock.UnLockWrite(); + return; + } + + void ReadStr(string& str) + { + BENCHMARK_LOGD("RWLockTest void ReadStr is called."); + rwLock.LockRead(); + for (auto it = buf.begin(); it != buf.end(); it++) { + str.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(10)); // 10: Extend time of holding the lock + } + rwLock.UnLockRead(); + return; + } +private: + Utils::RWLock rwLock; + string buf; +}; + +const string WRITE_IN_1("write1"); +const string WRITE_IN_2("write2"); + +/* + * @tc.name: testRWLock001 + * @tc.desc: RWLock here is under write-first mode. If there are some writing operation waiting, + * reading will never happen. Reading operations are likely to run at the same time, when all writing operations + * have finished. + */ +BENCHMARK_F(BenchmarkRWLockTest, testRWLock001)(benchmark::State& state) +{ + BENCHMARK_LOGD("RWLockTest testRWLock001 start."); + while (state.KeepRunning()) { + TestRWLock test; + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + // Try our best to make `first` get the lock + this_thread::sleep_for(std::chrono::milliseconds(SLEEP_DURATION_MS)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + + first.join(); + second.join(); + third.join(); + fourth.join(); + + AssertEqual(readOut1, WRITE_IN_1 + WRITE_IN_2, + "readOut1 did not equal WRITE_IN_1 + WRITE_IN_2 as expected.", state); + AssertEqual(readOut2, WRITE_IN_1 + WRITE_IN_2, + "readOut2 did not equal WRITE_IN_1 + WRITE_IN_2 as expected.", state); + } + BENCHMARK_LOGD("RWLockTest testRWLock001 end."); +} + +/* + * @tc.name: testRWLock002 + * @tc.desc: RWLock here is not under write-first mode. So if there are writing and reading operations in queue + * with a writing mission running, they will compete when the writing mission completing, but reading operations are + * likely to run at the same time. + */ +BENCHMARK_F(BenchmarkRWLockTest, testRWLock002)(benchmark::State& state) +{ + BENCHMARK_LOGD("RWLockTest testRWLock002 start."); + while (state.KeepRunning()) { + TestRWLock test(false); + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(chrono::milliseconds(SLEEP_DURATION_MS)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + first.join(); + second.join(); + third.join(); + fourth.join(); + + AssertEqual(readOut1, readOut2, "readOut1 did not equal readOut2 as expected.", state); + } + BENCHMARK_LOGD("RWLockTest testRWLock002 end."); +} + +/* + * @tc.name: testRWLockDefaultConstructor001 + * @tc.desc: This test case validates the default constructor of RWLock. By default, the RWLock is in write-first mode. + * In this mode, if there are pending write operations, read operations will not occur. This test case creates + * a default RWLock and attempts to perform read operations while write operations are pending. + * The expected behavior is that the read operations should not occur until the write operations are complete. + */ +BENCHMARK_F(BenchmarkRWLockTest, testRWLockDefaultConstructor001)(benchmark::State& state) +{ + BENCHMARK_LOGD("RWLockTest testRWLockDefaultConstructor001 start."); + while (state.KeepRunning()) { + TestRWLock test; + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(std::chrono::milliseconds(SLEEP_DURATION_MS)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + + first.join(); + second.join(); + + AssertEqual(readOut1, WRITE_IN_1, "readOut1 did not equal WRITE_IN_1 as expected.", state); + } + BENCHMARK_LOGD("RWLockTest testRWLockDefaultConstructor001 end."); +} + +/* + * @tc.name: testUniqueWriteGuardScope001 + * @tc.desc: This benchmark test is designed to test the functionality of the UniqueWriteGuard class. + * In this test, a write lock is acquired on an instance of the RWLock class using an instance of + * the UniqueWriteGuard class. The WriteStr method of the TestRWLock class is then called to write a string to + * the buffer of the TestRWLock instance. After the write operation, the write lock is automatically released + * because the UniqueWriteGuard instance goes out of scope. The ReadStr method of the TestRWLock class is then called + * to read the string from the buffer of the TestRWLock instance. If the read string does not match the written + * string, the test fails and an error message is logged. This test case is repeated multiple times to measure + * the performance of the write lock operation. + */ +BENCHMARK_F(BenchmarkRWLockTest, testUniqueWriteGuardScope001)(benchmark::State& state) +{ + BENCHMARK_LOGD("RWLockTest testUniqueWriteGuardScope001 start."); + while (state.KeepRunning()) { + OHOS::Utils::RWLock rwLock; + TestRWLock test; + string readOut1(""); + OHOS::Utils::UniqueWriteGuard guard(rwLock); + test.WriteStr(WRITE_IN_1); + test.ReadStr(readOut1); + AssertEqual(readOut1, WRITE_IN_1, "readOut1 did not equal WRITE_IN_1 as expected.", state); + } + BENCHMARK_LOGD("RWLockTest testUniqueWriteGuardScope001 end."); +} + +/* + * @tc.name: testUniqueReadGuardScope001 + * @tc.desc: This benchmark test is designed to test the functionality of the UniqueReadGuard class. + * In this test, a read lock is acquired on an instance of the RWLock class using an instance of + * the UniqueReadGuard class. The ReadStr method of the TestRWLock class is then called to read the string from + * the buffer of the TestRWLock instance. After the read operation, the read lock is automatically released because + * the UniqueReadGuard instance goes out of scope. This test case is repeated multiple times to measure + * the performance of the read lock operation. + */ +BENCHMARK_F(BenchmarkRWLockTest, testUniqueReadGuardScope001)(benchmark::State& state) +{ + BENCHMARK_LOGD("RWLockTest testUniqueReadGuardScope001 start."); + while (state.KeepRunning()) { + OHOS::Utils::RWLock rwLock; + TestRWLock test; + string readOut1(""); + test.WriteStr(WRITE_IN_1); // Write a string to the buffer before acquiring the read lock. + OHOS::Utils::UniqueReadGuard guard(rwLock); + test.ReadStr(readOut1); + AssertEqual(readOut1, WRITE_IN_1, "readOut1 did not equal WRITE_IN_1 as expected.", state); + } + BENCHMARK_LOGD("RWLockTest testUniqueReadGuardScope001 end."); +} +} // namespace +} // namespace OHOS +// Run the benchmark +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/bundle.json b/bundle.json index 4366b17..9f72ca3 100644 --- a/bundle.json +++ b/bundle.json @@ -110,7 +110,8 @@ } ], "test": [ - "//commonlibrary/c_utils/base/test:unittest" + "//commonlibrary/c_utils/base/test:unittest", + "//commonlibrary/c_utils/base/test/benchmarktest:benchmarktest" ] } } -- Gitee