• 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 "cpp/queue.h"
17 #include "core/dependence_manager.h"
18 #include "serial_handler.h"
19 #include "serial_task.h"
20 
21 using namespace std;
22 using namespace ffrt;
23 
24 namespace {
ResetTimeoutCb(ffrt::task_attr_private * p)25 inline void ResetTimeoutCb(ffrt::task_attr_private* p)
26 {
27     if (p->timeoutCb_ == nullptr) {
28         return;
29     }
30     GetSerialTaskByFuncStorageOffset(p->timeoutCb_)->DecDeleteRef();
31     p->timeoutCb_ = nullptr;
32 }
33 
ffrt_queue_submit_base(ffrt_queue_t queue,ffrt_function_header_t * f,bool withHandle,uint64_t & delayUs)34 inline SerialTask* ffrt_queue_submit_base(ffrt_queue_t queue, ffrt_function_header_t* f, bool withHandle,
35     uint64_t& delayUs)
36 {
37     FFRT_COND_DO_ERR((queue == nullptr), return nullptr, "input invalid, queue == nullptr");
38     FFRT_COND_DO_ERR((f == nullptr), return nullptr, "input invalid, function header == nullptr");
39 
40     SerialTask* task = GetSerialTaskByFuncStorageOffset(f);
41     new (task)ffrt::SerialTask();
42     SerialHandler* handler = static_cast<SerialHandler*>(queue);
43     task->SetQueHandler(handler);
44 
45     if (withHandle) {
46         task->IncDeleteRef();
47     }
48     handler->SubmitDelayed(task, delayUs);
49     return task;
50 }
51 } // namespace
52 
53 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_init(ffrt_queue_attr_t * attr)54 int ffrt_queue_attr_init(ffrt_queue_attr_t* attr)
55 {
56     FFRT_COND_DO_ERR((attr == nullptr), return -1, "input invalid, attr == nullptr");
57     static_assert(sizeof(ffrt::task_attr_private) <= ffrt_task_attr_storage_size,
58         "size must be less than ffrt_queue_attr_storage_size");
59 
60     new (attr) ffrt::task_attr_private();
61     return 0;
62 }
63 
64 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_destroy(ffrt_queue_attr_t * attr)65 void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr)
66 {
67     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
68     auto p = reinterpret_cast<ffrt::task_attr_private*>(attr);
69     ResetTimeoutCb(p);
70     p->~task_attr_private();
71 }
72 
73 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_qos(ffrt_queue_attr_t * attr,ffrt_qos_t qos)74 void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos)
75 {
76     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
77     ffrt::QoS _qos = ffrt::QoS(qos);
78     (reinterpret_cast<ffrt::task_attr_private*>(attr))->qos_ = _qos();
79 }
80 
81 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_qos(const ffrt_queue_attr_t * attr)82 ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr)
83 {
84     FFRT_COND_DO_ERR((attr == nullptr), return ffrt_qos_default, "input invalid, attr == nullptr");
85     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
86     return static_cast<ffrt_qos_t>((reinterpret_cast<ffrt::task_attr_private*>(p))->qos_);
87 }
88 
89 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_timeout(ffrt_queue_attr_t * attr,uint64_t timeout_us)90 void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us)
91 {
92     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
93     (reinterpret_cast<ffrt::task_attr_private*>(attr))->timeout_ = timeout_us;
94 }
95 
96 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t * attr)97 uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr)
98 {
99     FFRT_COND_DO_ERR((attr == nullptr), return 0, "input invalid, attr == nullptr");
100     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
101     return (reinterpret_cast<ffrt::task_attr_private*>(p))->timeout_;
102 }
103 
104 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_callback(ffrt_queue_attr_t * attr,ffrt_function_header_t * f)105 void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f)
106 {
107     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
108     ffrt::task_attr_private* p = reinterpret_cast<ffrt::task_attr_private*>(attr);
109     ResetTimeoutCb(p);
110     p->timeoutCb_ = f;
111     // the memory of timeoutCb are managed in the form of SerialTask
112     SerialTask* task = GetSerialTaskByFuncStorageOffset(f);
113     new (task)ffrt::SerialTask();
114 }
115 
116 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_callback(const ffrt_queue_attr_t * attr)117 ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr)
118 {
119     FFRT_COND_DO_ERR((attr == nullptr), return nullptr, "input invalid, attr == nullptr");
120     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
121     return (reinterpret_cast<ffrt::task_attr_private*>(p))->timeoutCb_;
122 }
123 
124 API_ATTRIBUTE((visibility("default")))
ffrt_queue_create(ffrt_queue_type_t type,const char * name,const ffrt_queue_attr_t * attr)125 ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)
126 {
127     FFRT_COND_DO_ERR((type != ffrt_queue_serial), return nullptr, "input invalid, type unsupport");
128     FFRT_COND_DO_ERR((attr == nullptr), return nullptr, "input invalid, attr == nullptr");
129 
130     int qos = ffrt_queue_attr_get_qos(attr);
131     shared_ptr<SerialLooper> looper =
132         make_shared<SerialLooper>(name, qos, ffrt_queue_attr_get_timeout(attr), ffrt_queue_attr_get_callback(attr));
133     FFRT_COND_DO_ERR((looper == nullptr), return nullptr, "failed to construct SerialLooper");
134 
135     SerialHandler* handler = new (std::nothrow) SerialHandler(looper);
136     FFRT_COND_DO_ERR((handler == nullptr), return nullptr, "failed to construct SerialHandler");
137     return static_cast<ffrt_queue_t>(handler);
138 }
139 
140 API_ATTRIBUTE((visibility("default")))
ffrt_queue_destroy(ffrt_queue_t queue)141 void ffrt_queue_destroy(ffrt_queue_t queue)
142 {
143     FFRT_COND_DO_ERR((queue == nullptr), return, "input invalid, queue is nullptr");
144     SerialHandler* handler = static_cast<SerialHandler*>(queue);
145     delete handler;
146 }
147 
148 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)149 void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
150 {
151     uint64_t delayUs = (attr == nullptr) ? 0 : ffrt_task_attr_get_delay(attr);
152     SerialTask* task = ffrt_queue_submit_base(queue, f, false, delayUs);
153     FFRT_COND_DO_ERR((task == nullptr), return, "failed to submit serial task");
154 }
155 
156 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit_h(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)157 ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
158 {
159     uint64_t delayUs = (attr == nullptr) ? 0 : ffrt_task_attr_get_delay(attr);
160     SerialTask* task = ffrt_queue_submit_base(queue, f, true, delayUs);
161     FFRT_COND_DO_ERR((task == nullptr), return nullptr, "failed to submit serial task");
162     return static_cast<ffrt_task_handle_t>(task);
163 }
164 
165 API_ATTRIBUTE((visibility("default")))
ffrt_queue_wait(ffrt_task_handle_t handle)166 void ffrt_queue_wait(ffrt_task_handle_t handle)
167 {
168     FFRT_COND_DO_ERR((handle == nullptr), return, "input invalid, task_handle is nullptr");
169     SerialTask* task = static_cast<SerialTask*>(handle);
170     task->Wait();
171 }
172 
173 API_ATTRIBUTE((visibility("default")))
ffrt_queue_cancel(ffrt_task_handle_t handle)174 int ffrt_queue_cancel(ffrt_task_handle_t handle)
175 {
176     FFRT_COND_DO_ERR((handle == nullptr), return -1, "input invalid, handle is nullptr");
177     SerialTask* task = static_cast<SerialTask*>(handle);
178     FFRT_COND_DO_ERR((task->handler_ == nullptr), return -1, "input invalid, task->handler_ is nullptr");
179     return task->handler_->Cancel(task);
180 }