• 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_worker.h"
27 #include "eu/co_routine.h"
28 #include "sched/scheduler.h"
29 #include "../common.h"
30 #include "tm/scpu_task.h"
31 
32 using namespace std;
33 using namespace ffrt;
34 using namespace testing;
35 #ifdef HWTEST_TESTING_EXT_ENABLE
36 using namespace testing::ext;
37 #endif
38 #ifdef APP_USE_ARM
39 #define SIZEOF_BYTES sizeof(uint32_t)
40 #else
41 #define SIZEOF_BYTES sizeof(uint64_t)
42 #endif
43 class CoroutineTest : public testing::Test {
44 protected:
SetUpTestCase()45     static void SetUpTestCase()
46     {
47     }
48 
TearDownTestCase()49     static void TearDownTestCase()
50     {
51     }
52 
SetUp()53     void SetUp() override
54     {
55     }
56 
TearDown()57     void TearDown() override
58     {
59     }
60 };
61 constexpr int BLOCKED_COUNT = 3;
62 
63 typedef struct {
64     std::atomic<int> count;
65     std::mutex lock;
66 } StacklessCoroutine1;
67 
stackless_coroutine(void * co)68 ffrt_coroutine_ret_t stackless_coroutine(void* co)
69 {
70     StacklessCoroutine1* stacklesscoroutine = reinterpret_cast<StacklessCoroutine1*>(co);
71     std::lock_guard lg(stacklesscoroutine->lock);
72     printf("stacklesscoroutine %d\n", stacklesscoroutine->count.load());
73     stacklesscoroutine->count++;
74     if (stacklesscoroutine->count < BLOCKED_COUNT) {
75         ffrt_wake_coroutine(ffrt_get_current_task());
76         return ffrt_coroutine_pending;
77     } else if (stacklesscoroutine->count == BLOCKED_COUNT) {
78         ffrt_wake_coroutine(ffrt_get_current_task());
79         return ffrt_coroutine_pending;
80     } else {
81         return ffrt_coroutine_ready;
82     }
83     return ffrt_coroutine_pending;
84 }
85 
exec_stackless_coroutine(void * co)86 ffrt_coroutine_ret_t exec_stackless_coroutine(void *co)
87 {
88     return stackless_coroutine(co);
89 }
90 
destroy_stackless_coroutine(void * co)91 void destroy_stackless_coroutine(void *co)
92 {
93 }
94 
95 HWTEST_F(CoroutineTest, coroutine_submit_succ, TestSize.Level0)
96 {
97     // coroutine_submit_004
98     StacklessCoroutine1 co1 = {0};
99     StacklessCoroutine1 co2 = {0};
100     ffrt_task_attr_t attr;
101     ffrt_task_attr_init(&attr);
102     ffrt_submit_coroutine((void *)&co1, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
103     ffrt_submit_coroutine((void *)&co2, exec_stackless_coroutine, destroy_stackless_coroutine, NULL, NULL, &attr);
104     // ffrt_poller_wakeup_001
105     ffrt_poller_wakeup(ffrt_qos_default);
106     usleep(100000);
107     EXPECT_EQ(co1.count, 4);
108     EXPECT_EQ(co2.count, 4);
109 
110     ffrt_wake_coroutine(nullptr);
111 }
112 
113 HWTEST_F(CoroutineTest, coroutine_submit_fail, TestSize.Level0)
114 {
115     // get_task_001
116     EXPECT_EQ(ffrt_get_current_task(), nullptr);
117 
118     ffrt_task_attr_t attr;
119     ffrt_task_attr_init(&attr);
120 
121     // coroutine_submit_001
122     ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
123     ffrt_submit_coroutine(nullptr, nullptr, nullptr, NULL, NULL, &attr);
124 }
125 
126 struct TestData {
127     int fd;
128     uint64_t expected;
129 };
130 
testCallBack(void * token,uint32_t event)131 static void testCallBack(void* token, uint32_t event)
132 {
133     struct TestData* testData = reinterpret_cast<TestData*>(token);
134     uint64_t value = 0;
135     ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
136     EXPECT_EQ(n, sizeof(value));
137     EXPECT_EQ(value, testData->expected);
138     printf("cb done\n");
139 }
140 
141 /*
142 * 测试用例名称:ffrt_get_current_coroutine_stack_success
143 * 测试用例描述:ffrt_get_current_coroutine_stack获取当前协程栈成功
144 * 预置条件    :提交ffrt任务
145 * 操作步骤    :在ffrt任务中调用ffrt_get_current_coroutine_stack接口
146 * 预期结果    :获取协程栈地址和大小成功
147 */
148 HWTEST_F(CoroutineTest, ffrt_get_current_coroutine_stack_success, TestSize.Level0)
149 {
150     ffrt_queue_attr_t queue_attr;
151     (void)ffrt_queue_attr_init(&queue_attr);
152     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
153 
__anon043cf0790202() 154     std::function<void()>&& OnePlusFunc = [&]() {
155         void* stackAddr = nullptr;
156         size_t size = 0;
157         bool ret = ffrt_get_current_coroutine_stack(&stackAddr, &size);
158         if (ffrt::USE_COROUTINE) {
159             EXPECT_EQ(ret, true);
160             EXPECT_NE(stackAddr, nullptr);
161             EXPECT_NE(size, 0);
162         } else {
163             EXPECT_EQ(ret, false);
164             EXPECT_EQ(stackAddr, nullptr);
165             EXPECT_EQ(size, 0);
166         }
167     };
168     ffrt_task_handle_t task = ffrt_queue_submit_h(queue_handle,
169         ffrt::create_function_wrapper(OnePlusFunc, ffrt_function_kind_queue), nullptr);
170     const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, task}};
171     ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
172     ffrt_wait_deps(&wait);
173     ffrt_task_handle_destroy(task);
174     ffrt_queue_attr_destroy(&queue_attr);
175     ffrt_queue_destroy(queue_handle);
176 }
177