• 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 #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 "eu/co_routine.h"
26 #include "internal_inc/osal.h"
27 #include "internal_inc/types.h"
28 #include "dfx/log/ffrt_log_api.h"
29 #include "ffrt_trace.h"
30 #include "tm/cpu_task.h"
31 #include "cpp/sleep.h"
32 
33 namespace ffrt {
34 namespace this_task {
ExecuteCtxTask()35 CPUEUTask* ExecuteCtxTask()
36 {
37     auto ctx = ExecuteCtx::Cur();
38     return ctx->task;
39 }
40 
SleepUntilImpl(const TimePoint & to)41 void SleepUntilImpl(const TimePoint& to)
42 {
43     auto task = ExecuteCtxTask();
44     if (ThreadWaitMode(task)) {
45         if (FFRT_UNLIKELY(LegacyMode(task))) {
46             task->blockType = BlockType::BLOCK_THREAD;
47         }
48         std::this_thread::sleep_until(to);
49         if (BlockThread(task)) {
50             task->blockType = BlockType::BLOCK_COROUTINE;
51         }
52         return;
53     }
54     // be careful about local-var use-after-free here
55     static std::function<void(WaitEntry*)> cb ([](WaitEntry* we) {
56         CoRoutineFactory::CoWakeFunc(we->task, CoWakeType::NO_TIMEOUT_WAKE);
57     });
58     FFRT_BLOCK_TRACER(ExecuteCtxTask()->gid, slp);
59     CoWait([&](CPUEUTask* task) -> bool { return DelayedWakeup(to, &task->fq_we, cb); });
60 }
61 }
62 } // namespace ffrt
63 
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67 
68 API_ATTRIBUTE((visibility("default")))
ffrt_yield()69 void ffrt_yield()
70 {
71     auto curTask = ffrt::this_task::ExecuteCtxTask();
72     if (ThreadWaitMode(curTask)) {
73         if (FFRT_UNLIKELY(LegacyMode(curTask))) {
74             curTask->blockType = BlockType::BLOCK_THREAD;
75         }
76         std::this_thread::yield();
77         if (BlockThread(curTask)) {
78             curTask->blockType = BlockType::BLOCK_COROUTINE;
79         }
80         return;
81     }
82     FFRT_BLOCK_TRACER(curTask->gid, yld);
83     CoWait([](ffrt::CPUEUTask* task) -> bool {
84         CoRoutineFactory::CoWakeFunc(task, CoWakeType::NO_TIMEOUT_WAKE);
85         return true;
86     });
87 }
88 
89 API_ATTRIBUTE((visibility("default")))
ffrt_usleep(uint64_t usec)90 int ffrt_usleep(uint64_t usec)
91 {
92     auto duration = std::chrono::microseconds{usec};
93     auto to = std::chrono::steady_clock::now() + duration;
94 
95     ffrt::this_task::SleepUntilImpl(to);
96     return ffrt_success;
97 }
98 
99 #ifdef __cplusplus
100 }
101 #endif