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 FFRT_CO_ROUTINE_HPP 17 #define FFRT_CO_ROUTINE_HPP 18 #include <functional> 19 #include <atomic> 20 #include "co2_context.h" 21 22 #if defined(__aarch64__) 23 constexpr size_t STACK_MAGIC = 0x7BCDABCDABCDABCD; 24 #elif defined(__arm__) 25 constexpr size_t STACK_MAGIC = 0x7BCDABCD; 26 #elif defined(__x86_64__) 27 constexpr size_t STACK_MAGIC = 0x7BCDABCDABCDABCD; 28 #elif defined(__riscv) && __riscv_xlen == 64 29 constexpr size_t STACK_MAGIC = 0x7BCDABCDABCDABCD; 30 #endif 31 32 namespace ffrt { 33 class CPUEUTask; 34 struct WaitEntry; 35 } // namespace ffrt 36 struct CoRoutine; 37 38 enum class CoStatus { 39 CO_UNINITIALIZED, 40 CO_NOT_FINISH, 41 CO_RUNNING, 42 }; 43 44 enum class CoStackProtectType { 45 CO_STACK_WEAK_PROTECT, 46 CO_STACK_STRONG_PROTECT 47 }; 48 49 enum class BlockType { 50 BLOCK_COROUTINE, 51 BLOCK_THREAD 52 }; 53 54 #if defined(__aarch64__) 55 constexpr uint64_t STACK_SIZE = 1 << 20; // 至少3*PAGE_SIZE 56 #elif defined(__arm__) 57 constexpr uint64_t STACK_SIZE = 1 << 15; 58 #else 59 constexpr uint64_t STACK_SIZE = 1 << 20; 60 #endif 61 62 using CoCtx = struct co2_context; 63 64 struct CoRoutineEnv { 65 CoRoutine* runningCo; 66 CoCtx schCtx; 67 const std::function<bool(ffrt::CPUEUTask*)>* pending; 68 }; 69 70 struct StackMem { 71 uint64_t size; 72 size_t magic; 73 uint8_t stk[8]; 74 }; 75 76 struct CoRoutine { 77 std::atomic_int status; 78 CoRoutineEnv* thEnv; 79 ffrt::CPUEUTask* task; 80 CoCtx ctx; 81 bool legacyMode = false; 82 BlockType blockType = BlockType::BLOCK_COROUTINE; 83 StackMem stkMem; 84 }; 85 86 struct CoStackAttr { 87 public: 88 explicit CoStackAttr(uint64_t coSize = STACK_SIZE, CoStackProtectType coType = 89 CoStackProtectType::CO_STACK_WEAK_PROTECT) 90 { 91 size = coSize; 92 type = coType; 93 } ~CoStackAttrCoStackAttr94 ~CoStackAttr() {} 95 uint64_t size; 96 CoStackProtectType type; 97 98 static inline CoStackAttr* Instance(uint64_t coSize = STACK_SIZE, 99 CoStackProtectType coType = CoStackProtectType::CO_STACK_WEAK_PROTECT) 100 { 101 static CoStackAttr inst(coSize, coType); 102 return &inst; 103 } 104 }; 105 106 void CoStackFree(void); 107 void CoWorkerExit(void); 108 109 void CoStart(ffrt::CPUEUTask* task); 110 void CoYield(void); 111 112 void CoWait(const std::function<bool(ffrt::CPUEUTask*)>& pred); 113 void CoWake(ffrt::CPUEUTask* task, bool timeOut); 114 #endif 115