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 #ifndef _GNU_SOURCE
17 #define _GNU_SOURCE
18 #endif
19
20 #include <map>
21 #include <functional>
22 #include "sync/sync.h"
23
24 #include "sched/execute_ctx.h"
25 #include "core/task_ctx.h"
26 #include "eu/co_routine.h"
27 #include "internal_inc/osal.h"
28 #include "internal_inc/types.h"
29 #include "dfx/log/ffrt_log_api.h"
30 #include "dfx/trace/ffrt_trace.h"
31 #include "cpp/sleep.h"
32
33 namespace ffrt {
34
35 namespace this_task {
36
ExecuteCtxTask()37 TaskCtx* ExecuteCtxTask()
38 {
39 auto ctx = ExecuteCtx::Cur();
40 return ctx->task;
41 }
42
sleep_until_impl(const time_point_t & to)43 void sleep_until_impl(const time_point_t& to)
44 {
45 if (!USE_COROUTINE || ExecuteCtxTask() == nullptr) {
46 std::this_thread::sleep_until(to);
47 return;
48 }
49 #ifdef _MSC_VER
50 std::this_thread::sleep_until(to);
51 #else
52 // be careful about local-var use-after-free here
53 std::function<void(WaitEntry*)> cb([](WaitEntry* we) { CoWake(we->task, false); });
54 FFRT_BLOCK_TRACER(ExecuteCtxTask()->gid, slp);
55 CoWait([&](TaskCtx* inTask) -> bool { return DelayedWakeup(to, &inTask->fq_we, cb); });
56
57 #endif
58 }
59
60 }
61 } // namespace ffrt
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 API_ATTRIBUTE((visibility("default")))
ffrt_yield()68 void ffrt_yield()
69 {
70 if (!ffrt::USE_COROUTINE || ffrt::this_task::ExecuteCtxTask() == nullptr) {
71 std::this_thread::yield();
72 return;
73 }
74 FFRT_BLOCK_TRACER(ffrt::this_task::ExecuteCtxTask()->gid, yld);
75 CoWait([](ffrt::TaskCtx* inTask) -> bool {
76 CoWake(inTask, false);
77 return true;
78 });
79 }
80
81 API_ATTRIBUTE((visibility("default")))
ffrt_usleep(uint64_t usec)82 int ffrt_usleep(uint64_t usec)
83 {
84 auto duration = std::chrono::microseconds{usec};
85 auto to = std::chrono::steady_clock::now() + duration;
86
87 ffrt::this_task::sleep_until_impl(to);
88 return ffrt_success;
89 }
90
91 #ifdef __cplusplus
92 }
93 #endif