1 /*
2 * Copyright (c) 2023 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<chrono>
18 #include<gtest/gtest.h>
19 #include"ffrt_inner.h"
20
21 using namespace std;
22 using namespace ffrt;
23 using namespace testing;
24
25 class CoroutineTest : public testing::Test {
26 protected:
SetUpTestCase()27 static void SetUpTestCase()
28 {
29 }
30
TearDownTestCase()31 static void TearDownTestCase()
32 {
33 }
34
SetUp()35 virtual void SetUp()
36 {
37 }
38
TeadDown()39 virtual void TeadDown()
40 {
41 }
42 };
43
44 const int BLOCKED_COUNT = 3;
45
46 typedef struct {
47 int count;
48 std::mutex lock;
49 }StacklessCoroutine1;
50
stackless_coroutine(void * co)51 ffrt_coroutine_ret_t stackless_coroutine(void* co)
52 {
53 StacklessCoroutine1* stacklesscoroutine = reinterpret_cast<StacklessCoroutine1*>(co);
54 std::lock_guard lg(stacklesscoroutine->lock);
55 printf("stacklesscoroutine %d\n", stacklesscoroutine->count);
56 stacklesscoroutine->count++;
57
58 if (stacklesscoroutine->count < BLOCKED_COUNT) {
59 ffrt_wake_coroutine(ffrt_get_current_task());
60 return ffrt_coroutine_pending;
61 } else if (stacklesscoroutine->count == BLOCKED_COUNT) {
62 ffrt_wake_coroutine(ffrt_get_current_task());
63 return ffrt_coroutine_pending;
64 } else {
65 return ffrt_coroutine_ready;
66 }
67 return ffrt_coroutine_pending;
68 }
69
exec_stackless_coroutine(void * co)70 ffrt_coroutine_ret_t exec_stackless_coroutine(void *co)
71 {
72 return stackless_coroutine(co);
73 }
74
destroy_stackless_coroutine(void * co)75 void destroy_stackless_coroutine(void *co)
76 {
77 }
78
TEST_F(CoroutineTest,coroutine_submit_succ)79 TEST_F(CoroutineTest, coroutine_submit_succ)
80 {
81 StacklessCoroutine1 co1 = {0};
82 StacklessCoroutine1 co2 = {0};
83 ffrt_task_attr_t attr;
84 ffrt_task_attr_init(&attr);
85 ffrt_submit_coroutine((void *)co1, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
86 ffrt_submit_coroutine((void *)co2, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
87 ffrt_poller_wakeup();
88 usleep(100000);
89 EXPECT_EQ(co1.count, 4);
90 EXPECT_EQ(co2.count, 4);
91 }
92
TEST_F(CoroutineTest,coroutine_submit_fail)93 TEST_F(CoroutineTest, coroutine_submit_fail)
94 {
95 EXPECT_SQ(ffrt_get_current_task(), nullptr);
96
97 ffrt_task_attr_t attr;
98 ffrt_task_attr_init(&attr);
99
100 ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
101 ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
102 }
103
104 struct TestData {
105 int fd;
106 uint64_t expected;
107 };
108
testCallBack(void * token,uint32_t event,uint8_t count)109 static void testCallBack(void* token, uint32_t event, uint8_t count)
110 {
111 struct TestData* testData = reinterpret_cast<TestData*>(token);
112 uint64_t value = 0;
113 ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
114 EXPECT_EQ(n, sizeof(value));
115 EXPECT_EQ(value, testData->expected);
116 }
117
TEST_F(CoroutineTest,ffrt_poller_register_deregister)118 TEST_F(CoroutineTest, ffrt_poller_register_deregister)
119 {
120 uint64_t expected = 0xabacadae;
121 int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
122
123 ffrt::submit([&]() {
124 ssize_t n = write(testFd, &expected, sizeof(uint64_t));
125 EXPECT_EQ(sizeof(n), sizeof(uint64_t));
126 }, {}, {})
127
128 struct TestData testData {.fd = testFd, .expected = expected};
129 ffrt_poller_register(testFd, EPOLLIN, reinterpret_cast<void*>(&testData), testCallBack);
130 usleep(100);
131 ffrt_poller_deregister(testFd);
132 close(testFd);
133 }