• 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 <sys/eventfd.h>
20 #include <sys/epoll.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <cstdint>
24 #include "c/executor_task.h"
25 #include "ffrt_inner.h"
26 #include "eu/cpu_monitor.h"
27 #include "eu/cpu_worker.h"
28 #include "eu/co_routine.h"
29 #include "eu/scpuworker_manager.h"
30 #include "sched/scheduler.h"
31 #include "../common.h"
32 #include "tm/scpu_task.h"
33 
34 using namespace std;
35 using namespace ffrt;
36 using namespace testing;
37 #ifdef HWTEST_TESTING_EXT_ENABLE
38 using namespace testing::ext;
39 #endif
40 #ifdef APP_USE_ARM
41 #define SIZEOF_BYTES sizeof(uint32_t)
42 #else
43 #define SIZEOF_BYTES sizeof(uint64_t)
44 #endif
45 class CoroutineTest : public testing::Test {
46 protected:
SetUpTestCase()47     static void SetUpTestCase()
48     {
49     }
50 
TearDownTestCase()51     static void TearDownTestCase()
52     {
53     }
54 
SetUp()55     void SetUp() override
56     {
57     }
58 
TearDown()59     void TearDown() override
60     {
61     }
62 };
63 constexpr int BLOCKED_COUNT = 3;
64 
65 typedef struct {
66     int count;
67     std::mutex lock;
68 } StacklessCoroutine1;
69 
stackless_coroutine(void * co)70 ffrt_coroutine_ret_t stackless_coroutine(void* co)
71 {
72     StacklessCoroutine1* stacklesscoroutine = reinterpret_cast<StacklessCoroutine1*>(co);
73     std::lock_guard lg(stacklesscoroutine->lock);
74     printf("stacklesscoroutine %d\n", stacklesscoroutine->count);
75     stacklesscoroutine->count++;
76     if (stacklesscoroutine->count < BLOCKED_COUNT) {
77         ffrt_wake_coroutine(ffrt_get_current_task());
78         return ffrt_coroutine_pending;
79     } else if (stacklesscoroutine->count == BLOCKED_COUNT) {
80         ffrt_wake_coroutine(ffrt_get_current_task());
81         return ffrt_coroutine_pending;
82     } else {
83         return ffrt_coroutine_ready;
84     }
85     return ffrt_coroutine_pending;
86 }
87 
exec_stackless_coroutine(void * co)88 ffrt_coroutine_ret_t exec_stackless_coroutine(void *co)
89 {
90     return stackless_coroutine(co);
91 }
92 
destroy_stackless_coroutine(void * co)93 void destroy_stackless_coroutine(void *co)
94 {
95 }
96 
97 HWTEST_F(CoroutineTest, coroutine_submit_succ, TestSize.Level1)
98 {
99     // coroutine_submit_004
100     StacklessCoroutine1 co1 = {0};
101     StacklessCoroutine1 co2 = {0};
102     ffrt_task_attr_t attr;
103     ffrt_task_attr_init(&attr);
104     ffrt_submit_coroutine((void *)&co1, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
105     ffrt_submit_coroutine((void *)&co2, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
106     // ffrt_poller_wakeup_001
107     ffrt_poller_wakeup(ffrt_qos_default);
108     usleep(100000);
109     EXPECT_EQ(co1.count, 4);
110     EXPECT_EQ(co2.count, 4);
111 
112     ffrt_wake_coroutine(nullptr);
113 }
114 
115 HWTEST_F(CoroutineTest, coroutine_submit_fail, TestSize.Level1)
116 {
117     // get_task_001
118     EXPECT_EQ(ffrt_get_current_task(), nullptr);
119 
120     ffrt_task_attr_t attr;
121     ffrt_task_attr_init(&attr);
122 
123     // coroutine_submit_001
124     ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
125     ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
126 }
127 
128 struct TestData {
129     int fd;
130     uint64_t expected;
131 };
132 
testCallBack(void * token,uint32_t event)133 static void testCallBack(void* token, uint32_t event)
134 {
135     struct TestData* testData = reinterpret_cast<TestData*>(token);
136     uint64_t value = 0;
137     ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
138     EXPECT_EQ(n, sizeof(value));
139     EXPECT_EQ(value, testData->expected);
140     printf("cb done\n");
141 }
142 
143 HWTEST_F(CoroutineTest, ffrt_epoll_ctl_add_del, TestSize.Level1)
144 {
145     uint64_t expected = 0xabacadae;
146     int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
147 
__anoncbec3f170202() 148     ffrt::submit([&]() {
149         ssize_t n = write(testFd, &expected, sizeof(uint64_t));
150         EXPECT_EQ(sizeof(n), SIZEOF_BYTES);
151         }, {}, {});
152 
153     struct TestData testData {.fd = testFd, .expected = expected};
154     // poller_register_001
155     ffrt_epoll_ctl(ffrt_qos_default, EPOLL_CTL_ADD, testFd, EPOLLIN, reinterpret_cast<void*>(&testData), testCallBack);
156 
157     usleep(100);
158 
159     // poller_deregister_001
160     ffrt_epoll_ctl(ffrt_qos_default, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
161     close(testFd);
162 }