1 /* 2 * Copyright (c) 2025 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 #include <thread> 17 #include <cinttypes> 18 #include <gtest/gtest.h> 19 #include <gmock/gmock.h> 20 21 #include "audio_service_log.h" 22 #include "audio_errors.h" 23 #include "futex_tool.h" 24 25 using namespace testing::ext; 26 27 namespace OHOS { 28 namespace AudioStandard { 29 namespace { 30 static constexpr int64_t TIMEOUT_IN_NS = 300000000; // 300ms 31 static constexpr int64_t SHORT_TIMEOUT_IN_NS = 30000000; // 30ms 32 static constexpr uint32_t CYCLES_TIMES = 500; 33 } // namespace 34 35 class FutexToolUnitTest : public testing::Test { 36 public: 37 static void SetUpTestCase(void); 38 static void TearDownTestCase(void); 39 void SetUp(); 40 void TearDown(); 41 }; 42 43 /** 44 * @tc.name : Test FutexTool API 45 * @tc.type : FUNC 46 * @tc.number: FutexTool_001 47 * @tc.desc : Test FutexTool interface. 48 */ 49 HWTEST(FutexToolUnitTest, FutexTool_001, TestSize.Level1) 50 { 51 std::atomic<uint32_t> futexVar = IS_READY; 52 std::atomic<uint32_t> readIndex = 0; 53 std::atomic<uint32_t> writeIndex = 0; 54 __anon5cb1ce490202() 55 std::thread threadWrite([&futexVar, &writeIndex] () { 56 writeIndex++; 57 FutexTool::FutexWake(&futexVar, IS_READY); 58 }); 59 __anon5cb1ce490302() 60 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 61 return writeIndex > readIndex; 62 }); 63 64 threadWrite.join(); 65 EXPECT_EQ(ret, FUTEX_SUCCESS); 66 } 67 68 /** 69 * @tc.name : Test FutexTool API 70 * @tc.type : FUNC 71 * @tc.number: FutexTool_002 72 * @tc.desc : Test FutexTool interface. 73 */ 74 HWTEST(FutexToolUnitTest, FutexTool_002, TestSize.Level1) 75 { 76 std::atomic<uint32_t> futexVar = IS_NOT_READY; 77 std::atomic<uint32_t> readIndex = 0; 78 std::atomic<uint32_t> writeIndex = 0; 79 __anon5cb1ce490402() 80 std::thread threadWrite([&futexVar, &writeIndex] () { 81 writeIndex++; 82 FutexTool::FutexWake(&futexVar, IS_READY); 83 }); 84 __anon5cb1ce490502() 85 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 86 return writeIndex > readIndex; 87 }); 88 89 threadWrite.join(); 90 EXPECT_EQ(ret, FUTEX_SUCCESS); 91 } 92 93 /** 94 * @tc.name : Test FutexTool API 95 * @tc.type : FUNC 96 * @tc.number: FutexTool_003 97 * @tc.desc : Test FutexTool interface. 98 */ 99 HWTEST(FutexToolUnitTest, FutexTool_003, TestSize.Level1) 100 { 101 std::atomic<uint32_t> futexVar = IS_READY; 102 std::atomic<uint32_t> writeIndex = 0; 103 __anon5cb1ce490602() 104 std::thread threadWrite([&futexVar, &writeIndex] () { 105 while (writeIndex++ < CYCLES_TIMES) {} 106 FutexTool::FutexWake(&futexVar, IS_READY); 107 }); 108 __anon5cb1ce490702() 109 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 110 return writeIndex >= CYCLES_TIMES; 111 }); 112 113 threadWrite.join(); 114 EXPECT_EQ(ret, FUTEX_SUCCESS); 115 } 116 117 /** 118 * @tc.name : Test FutexTool API 119 * @tc.type : FUNC 120 * @tc.number: FutexTool_004 121 * @tc.desc : Test FutexTool interface. 122 */ 123 HWTEST(FutexToolUnitTest, FutexTool_004, TestSize.Level1) 124 { 125 std::atomic<uint32_t> futexVar = IS_NOT_READY; 126 std::atomic<uint32_t> writeIndex = 0; 127 __anon5cb1ce490802() 128 std::thread threadWrite([&futexVar, &writeIndex] () { 129 while (writeIndex++ < CYCLES_TIMES) {} 130 FutexTool::FutexWake(&futexVar, IS_READY); 131 }); 132 __anon5cb1ce490902() 133 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 134 return writeIndex >= CYCLES_TIMES; 135 }); 136 137 threadWrite.join(); 138 EXPECT_EQ(ret, FUTEX_SUCCESS); 139 } 140 141 /** 142 * @tc.name : Test FutexTool API 143 * @tc.type : FUNC 144 * @tc.number: FutexTool_005 145 * @tc.desc : Test FutexTool interface. 146 */ 147 HWTEST(FutexToolUnitTest, FutexTool_005, TestSize.Level1) 148 { 149 std::atomic<uint32_t> futexVar = IS_READY; 150 std::atomic<uint32_t> readIndex = 0; 151 std::atomic<uint32_t> writeIndex = 0; 152 __anon5cb1ce490a02() 153 std::thread threadWrite([&futexVar, &writeIndex, &readIndex] () { 154 while (writeIndex++ < CYCLES_TIMES) { 155 if (writeIndex >= readIndex) { 156 FutexTool::FutexWake(&futexVar, IS_READY); 157 } 158 } 159 }); 160 161 while (readIndex++ < CYCLES_TIMES) { __anon5cb1ce490b02() 162 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 163 return writeIndex >= readIndex; 164 }); 165 EXPECT_EQ(ret, FUTEX_SUCCESS); 166 } 167 168 threadWrite.join(); 169 } 170 171 /** 172 * @tc.name : Test FutexTool API 173 * @tc.type : FUNC 174 * @tc.number: FutexTool_006 175 * @tc.desc : Test FutexTool interface. 176 */ 177 HWTEST(FutexToolUnitTest, FutexTool_006, TestSize.Level1) 178 { 179 std::atomic<uint32_t> futexVar = IS_NOT_READY; 180 std::atomic<uint32_t> readIndex = 0; 181 std::atomic<uint32_t> writeIndex = 0; 182 __anon5cb1ce490c02() 183 std::thread threadWrite([&futexVar, &writeIndex, &readIndex] () { 184 while (writeIndex++ < CYCLES_TIMES) { 185 if (writeIndex >= readIndex) { 186 FutexTool::FutexWake(&futexVar, IS_READY); 187 } 188 } 189 }); 190 191 while (readIndex++ < CYCLES_TIMES) { __anon5cb1ce490d02() 192 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 193 return writeIndex >= readIndex; 194 }); 195 EXPECT_EQ(ret, FUTEX_SUCCESS); 196 } 197 198 threadWrite.join(); 199 } 200 201 /** 202 * @tc.name : Test FutexTool API 203 * @tc.type : FUNC 204 * @tc.number: FutexTool_007 205 * @tc.desc : Test FutexTool interface. 206 */ 207 HWTEST(FutexToolUnitTest, FutexTool_007, TestSize.Level1) 208 { 209 std::atomic<uint32_t> futexVar = IS_READY; 210 __anon5cb1ce490e02() 211 auto ret = FutexTool::FutexWait(&futexVar, SHORT_TIMEOUT_IN_NS, [] () { 212 return false; 213 }); 214 215 EXPECT_EQ(ret, FUTEX_TIMEOUT); 216 } 217 } // namespace AudioStandard 218 } // namespace OHOS