• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }