• 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 
35 namespace this_task {
36 
ExecuteCtxTask()37 CPUEUTask* 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     auto task = ExecuteCtxTask();
46     bool legacyMode = task != nullptr ? (task->coRoutine != nullptr ? task->coRoutine->legacyMode : false) : false;
47     if (!USE_COROUTINE || task == nullptr || legacyMode) {
48         if (legacyMode) {
49             task->coRoutine->blockType = BlockType::BLOCK_THREAD;
50         }
51         std::this_thread::sleep_until(to);
52         if (legacyMode) {
53             task->coRoutine->blockType = BlockType::BLOCK_COROUTINE;
54         }
55         return;
56     }
57     // be careful about local-var use-after-free here
58     std::function<void(WaitEntry*)> cb([](WaitEntry* we) { CoWake(we->task, false); });
59     FFRT_BLOCK_TRACER(ExecuteCtxTask()->gid, slp);
60     CoWait([&](CPUEUTask* inTask) -> bool { return DelayedWakeup(to, &inTask->fq_we, cb); });
61 }
62 
63 }
64 } // namespace ffrt
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 API_ATTRIBUTE((visibility("default")))
ffrt_yield()71 void ffrt_yield()
72 {
73     auto curTask = ffrt::this_task::ExecuteCtxTask();
74     bool legacyMode = curTask != nullptr ?
75         (curTask->coRoutine != nullptr ? curTask->coRoutine->legacyMode : false) : false;
76     if (!ffrt::USE_COROUTINE || curTask == nullptr || legacyMode) {
77         if (legacyMode) {
78             curTask->coRoutine->blockType = BlockType::BLOCK_THREAD;
79         }
80         std::this_thread::yield();
81         if (legacyMode) {
82             curTask->coRoutine->blockType = BlockType::BLOCK_COROUTINE;
83         }
84         return;
85     }
86     FFRT_BLOCK_TRACER(curTask->gid, yld);
87     CoWait([](ffrt::CPUEUTask* inTask) -> bool {
88         CoWake(inTask, false);
89         return true;
90     });
91 }
92 
93 API_ATTRIBUTE((visibility("default")))
ffrt_usleep(uint64_t usec)94 int ffrt_usleep(uint64_t usec)
95 {
96     auto duration = std::chrono::microseconds{usec};
97     auto to = std::chrono::steady_clock::now() + duration;
98 
99     ffrt::this_task::sleep_until_impl(to);
100     return ffrt_success;
101 }
102 
103 #ifdef __cplusplus
104 }
105 #endif