1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <gtest/gtest.h>
17484543d1Sopenharmony_ci#include <chrono>
18484543d1Sopenharmony_ci#include "c/thread.h"
19484543d1Sopenharmony_ci#include "ffrt_inner.h"
20484543d1Sopenharmony_ci#include "../common.h"
21484543d1Sopenharmony_ci
22484543d1Sopenharmony_ciusing namespace ffrt;
23484543d1Sopenharmony_ciusing namespace std;
24484543d1Sopenharmony_ciusing namespace testing;
25484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE
26484543d1Sopenharmony_ciusing namespace testing::ext;
27484543d1Sopenharmony_ci#endif
28484543d1Sopenharmony_ci
29484543d1Sopenharmony_ciclass CVTest : public testing::Test {
30484543d1Sopenharmony_ciprotected:
31484543d1Sopenharmony_ci    static void SetUpTestCase()
32484543d1Sopenharmony_ci    {
33484543d1Sopenharmony_ci    }
34484543d1Sopenharmony_ci
35484543d1Sopenharmony_ci    static void TearDownTestCase()
36484543d1Sopenharmony_ci    {
37484543d1Sopenharmony_ci    }
38484543d1Sopenharmony_ci
39484543d1Sopenharmony_ci    virtual void SetUp()
40484543d1Sopenharmony_ci    {
41484543d1Sopenharmony_ci    }
42484543d1Sopenharmony_ci
43484543d1Sopenharmony_ci    virtual void TearDown()
44484543d1Sopenharmony_ci    {
45484543d1Sopenharmony_ci    }
46484543d1Sopenharmony_ci};
47484543d1Sopenharmony_ci
48484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_notify_one_test, TestSize.Level1)
49484543d1Sopenharmony_ci{
50484543d1Sopenharmony_ci    ffrt::condition_variable cond;
51484543d1Sopenharmony_ci    int a = 0;
52484543d1Sopenharmony_ci    ffrt::mutex lock_;
53484543d1Sopenharmony_ci
54484543d1Sopenharmony_ci    ffrt::submit(
55484543d1Sopenharmony_ci        [&]() {
56484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
57484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
58484543d1Sopenharmony_ci        },
59484543d1Sopenharmony_ci        {}, {});
60484543d1Sopenharmony_ci
61484543d1Sopenharmony_ci    ffrt::submit(
62484543d1Sopenharmony_ci        [&]() {
63484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
64484543d1Sopenharmony_ci            a = 1;
65484543d1Sopenharmony_ci            cond.notify_one();
66484543d1Sopenharmony_ci        },
67484543d1Sopenharmony_ci        {}, {});
68484543d1Sopenharmony_ci    ffrt::wait();
69484543d1Sopenharmony_ci}
70484543d1Sopenharmony_ci
71484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_notify_all_test, TestSize.Level1)
72484543d1Sopenharmony_ci{
73484543d1Sopenharmony_ci    ffrt::condition_variable cond;
74484543d1Sopenharmony_ci    int a = 0;
75484543d1Sopenharmony_ci    ffrt::mutex lock_;
76484543d1Sopenharmony_ci
77484543d1Sopenharmony_ci    ffrt::submit(
78484543d1Sopenharmony_ci        [&]() {
79484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
80484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
81484543d1Sopenharmony_ci        },
82484543d1Sopenharmony_ci        {}, {});
83484543d1Sopenharmony_ci    ffrt::submit(
84484543d1Sopenharmony_ci        [&]() {
85484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
86484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
87484543d1Sopenharmony_ci        },
88484543d1Sopenharmony_ci        {}, {});
89484543d1Sopenharmony_ci
90484543d1Sopenharmony_ci    ffrt::submit(
91484543d1Sopenharmony_ci        [&]() {
92484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
93484543d1Sopenharmony_ci            a = 1;
94484543d1Sopenharmony_ci            cond.notify_all();
95484543d1Sopenharmony_ci        },
96484543d1Sopenharmony_ci        {}, {});
97484543d1Sopenharmony_ci
98484543d1Sopenharmony_ci    ffrt::wait();
99484543d1Sopenharmony_ci}
100484543d1Sopenharmony_ci
101484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test, TestSize.Level1)
102484543d1Sopenharmony_ci{
103484543d1Sopenharmony_ci    ffrt::condition_variable cond;
104484543d1Sopenharmony_ci    std::atomic_int a = 0;
105484543d1Sopenharmony_ci    ffrt::mutex lock_;
106484543d1Sopenharmony_ci
107484543d1Sopenharmony_ci    ffrt::submit(
108484543d1Sopenharmony_ci        [&]() {
109484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
110484543d1Sopenharmony_ci            cond.wait_for(lck, 100ms, [&] { return a == 1; });
111484543d1Sopenharmony_ci            EXPECT_EQ(a, 2);
112484543d1Sopenharmony_ci        },
113484543d1Sopenharmony_ci        {}, {});
114484543d1Sopenharmony_ci
115484543d1Sopenharmony_ci    ffrt::submit(
116484543d1Sopenharmony_ci        [&]() {
117484543d1Sopenharmony_ci                std::unique_lock lck(lock_);
118484543d1Sopenharmony_ci                a = 2;
119484543d1Sopenharmony_ci                cond.notify_one();
120484543d1Sopenharmony_ci            },
121484543d1Sopenharmony_ci        {}, {});
122484543d1Sopenharmony_ci
123484543d1Sopenharmony_ci    ffrt::wait();
124484543d1Sopenharmony_ci}
125484543d1Sopenharmony_ci
126484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test2, TestSize.Level1)
127484543d1Sopenharmony_ci{
128484543d1Sopenharmony_ci    ffrt::condition_variable cond;
129484543d1Sopenharmony_ci    ffrt::mutex lock_;
130484543d1Sopenharmony_ci    ffrt::cv_status status;
131484543d1Sopenharmony_ci
132484543d1Sopenharmony_ci    ffrt::submit(
133484543d1Sopenharmony_ci        [&]() {
134484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
135484543d1Sopenharmony_ci            status = cond.wait_for(lck, 100ms);
136484543d1Sopenharmony_ci            EXPECT_EQ(status, ffrt::cv_status::timeout);
137484543d1Sopenharmony_ci        },
138484543d1Sopenharmony_ci        {}, {});
139484543d1Sopenharmony_ci
140484543d1Sopenharmony_ci    ffrt::wait();
141484543d1Sopenharmony_ci}
142484543d1Sopenharmony_ci
143484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test3, TestSize.Level1)
144484543d1Sopenharmony_ci{
145484543d1Sopenharmony_ci    ffrt::condition_variable cond;
146484543d1Sopenharmony_ci    ffrt::mutex lock_;
147484543d1Sopenharmony_ci    ffrt::cv_status status;
148484543d1Sopenharmony_ci
149484543d1Sopenharmony_ci    std::unique_lock lck(lock_);
150484543d1Sopenharmony_ci    status = cond.wait_for(lck, 100ms);
151484543d1Sopenharmony_ci    EXPECT_EQ(status, ffrt::cv_status::timeout);
152484543d1Sopenharmony_ci}
153484543d1Sopenharmony_ci
154484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_nullptr_test, TestSize.Level1)
155484543d1Sopenharmony_ci{
156484543d1Sopenharmony_ci    int ret = 0;
157484543d1Sopenharmony_ci
158484543d1Sopenharmony_ci    ret = ffrt_cond_init(nullptr, nullptr);
159484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
160484543d1Sopenharmony_ci    ret = ffrt_cond_signal(nullptr);
161484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
162484543d1Sopenharmony_ci    ret = ffrt_cond_broadcast(nullptr);
163484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
164484543d1Sopenharmony_ci    ret = ffrt_cond_wait(nullptr, nullptr);
165484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
166484543d1Sopenharmony_ci    ret = ffrt_cond_timedwait(nullptr, nullptr, nullptr);
167484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
168484543d1Sopenharmony_ci    ffrt_cond_destroy(nullptr);
169484543d1Sopenharmony_ci}
170484543d1Sopenharmony_ci
171484543d1Sopenharmony_ciclass MutexTest : public testing::Test {
172484543d1Sopenharmony_ciprotected:
173484543d1Sopenharmony_ci    static void SetUpTestCase()
174484543d1Sopenharmony_ci    {
175484543d1Sopenharmony_ci    }
176484543d1Sopenharmony_ci
177484543d1Sopenharmony_ci    static void TearDownTestCase()
178484543d1Sopenharmony_ci    {
179484543d1Sopenharmony_ci    }
180484543d1Sopenharmony_ci
181484543d1Sopenharmony_ci    virtual void SetUp()
182484543d1Sopenharmony_ci    {
183484543d1Sopenharmony_ci    }
184484543d1Sopenharmony_ci
185484543d1Sopenharmony_ci    virtual void TearDown()
186484543d1Sopenharmony_ci    {
187484543d1Sopenharmony_ci    }
188484543d1Sopenharmony_ci};
189484543d1Sopenharmony_ci
190484543d1Sopenharmony_ciHWTEST_F(MutexTest, try_lock_test, TestSize.Level1)
191484543d1Sopenharmony_ci{
192484543d1Sopenharmony_ci    int val = -1;
193484543d1Sopenharmony_ci    ffrt::mutex lock;
194484543d1Sopenharmony_ci    lock.lock();
195484543d1Sopenharmony_ci    val = lock.try_lock();
196484543d1Sopenharmony_ci    EXPECT_EQ(val, 0);
197484543d1Sopenharmony_ci    lock.unlock();
198484543d1Sopenharmony_ci    val = lock.try_lock();
199484543d1Sopenharmony_ci    EXPECT_EQ(val, 1);
200484543d1Sopenharmony_ci    lock.unlock();
201484543d1Sopenharmony_ci    lock.unlock();
202484543d1Sopenharmony_ci}
203484543d1Sopenharmony_ci
204484543d1Sopenharmony_ciHWTEST_F(MutexTest, lock_stress_test, TestSize.Level1)
205484543d1Sopenharmony_ci{
206484543d1Sopenharmony_ci    // trigger lazy init
207484543d1Sopenharmony_ci    ffrt::submit([&]() {}, {}, {});
208484543d1Sopenharmony_ci    ffrt::wait();
209484543d1Sopenharmony_ci
210484543d1Sopenharmony_ci    const int N = 10;
211484543d1Sopenharmony_ci    const int M = 10;
212484543d1Sopenharmony_ci    const int J = 10;
213484543d1Sopenharmony_ci    ffrt::mutex lock;
214484543d1Sopenharmony_ci    // std::mutex lock;
215484543d1Sopenharmony_ci    int acc = 0;
216484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
217484543d1Sopenharmony_ci    ffrt::submit(
218484543d1Sopenharmony_ci        [&]() {
219484543d1Sopenharmony_ci        for (int j = 0; j < M; ++j) {
220484543d1Sopenharmony_ci            lock.lock();
221484543d1Sopenharmony_ci            acc++;
222484543d1Sopenharmony_ci            lock.unlock();
223484543d1Sopenharmony_ci        }
224484543d1Sopenharmony_ci        },
225484543d1Sopenharmony_ci        {}, {});
226484543d1Sopenharmony_ci    }
227484543d1Sopenharmony_ci
228484543d1Sopenharmony_ci    for (int j = 0; j < J; ++j) {
229484543d1Sopenharmony_ci    lock.lock();
230484543d1Sopenharmony_ci    acc++;
231484543d1Sopenharmony_ci    lock.unlock();
232484543d1Sopenharmony_ci    }
233484543d1Sopenharmony_ci
234484543d1Sopenharmony_ci    ffrt::wait();
235484543d1Sopenharmony_ci    EXPECT_EQ(acc, (M * N + J));
236484543d1Sopenharmony_ci}
237484543d1Sopenharmony_ci
238484543d1Sopenharmony_ciclass SleepTest : public testing::Test {
239484543d1Sopenharmony_ciprotected:
240484543d1Sopenharmony_ci    static void SetUpTestCase()
241484543d1Sopenharmony_ci    {
242484543d1Sopenharmony_ci    }
243484543d1Sopenharmony_ci
244484543d1Sopenharmony_ci    static void TearDownTestCase()
245484543d1Sopenharmony_ci    {
246484543d1Sopenharmony_ci    }
247484543d1Sopenharmony_ci
248484543d1Sopenharmony_ci    virtual void SetUp()
249484543d1Sopenharmony_ci    {
250484543d1Sopenharmony_ci    }
251484543d1Sopenharmony_ci
252484543d1Sopenharmony_ci    virtual void TearDown()
253484543d1Sopenharmony_ci    {
254484543d1Sopenharmony_ci    }
255484543d1Sopenharmony_ci};
256484543d1Sopenharmony_ci
257484543d1Sopenharmony_ciHWTEST_F(SleepTest, yield_test, TestSize.Level1)
258484543d1Sopenharmony_ci{
259484543d1Sopenharmony_ci    int a = 0;
260484543d1Sopenharmony_ci
261484543d1Sopenharmony_ci    this_task::yield();
262484543d1Sopenharmony_ci
263484543d1Sopenharmony_ci    EXPECT_EQ(a, 0);
264484543d1Sopenharmony_ci}
265484543d1Sopenharmony_ci
266484543d1Sopenharmony_ciHWTEST_F(SleepTest, sleep_for_test1, TestSize.Level1)
267484543d1Sopenharmony_ci{
268484543d1Sopenharmony_ci    int a = 0;
269484543d1Sopenharmony_ci
270484543d1Sopenharmony_ci    this_task::sleep_for(10ms);
271484543d1Sopenharmony_ci
272484543d1Sopenharmony_ci    EXPECT_EQ(a, 0);
273484543d1Sopenharmony_ci}
274484543d1Sopenharmony_ci
275484543d1Sopenharmony_ciHWTEST_F(SleepTest, sleep_for_test2, TestSize.Level1)
276484543d1Sopenharmony_ci{
277484543d1Sopenharmony_ci    int a = 0;
278484543d1Sopenharmony_ci
279484543d1Sopenharmony_ci    submit([&]() {
280484543d1Sopenharmony_ci        this_task::sleep_for(5us);
281484543d1Sopenharmony_ci        a = 2;
282484543d1Sopenharmony_ci        }, {}, {});
283484543d1Sopenharmony_ci
284484543d1Sopenharmony_ci    wait();
285484543d1Sopenharmony_ci
286484543d1Sopenharmony_ci    EXPECT_EQ(a, 2);
287484543d1Sopenharmony_ci}
288484543d1Sopenharmony_ci
289484543d1Sopenharmony_civoid* thd_func(void *arg)
290484543d1Sopenharmony_ci{
291484543d1Sopenharmony_ci    int *counter = (int *)arg;
292484543d1Sopenharmony_ci    (*counter)++;
293484543d1Sopenharmony_ci    return arg;
294484543d1Sopenharmony_ci}
295484543d1Sopenharmony_ci
296484543d1Sopenharmony_ciHWTEST_F(SleepTest, thread_test, TestSize.Level1)
297484543d1Sopenharmony_ci{
298484543d1Sopenharmony_ci    int a = 0;
299484543d1Sopenharmony_ci    ffrt_thread_t thread;
300484543d1Sopenharmony_ci    ffrt_thread_create(&thread, nullptr, thd_func, &a);
301484543d1Sopenharmony_ci    void* result = nullptr;
302484543d1Sopenharmony_ci    ffrt_thread_join(thread, &result);
303484543d1Sopenharmony_ci    EXPECT_EQ(1, a);
304484543d1Sopenharmony_ci    EXPECT_EQ(&a, result);
305484543d1Sopenharmony_ci}
306