1 /** 2 * Copyright (c) 2023-2024 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 PANDA_RUNTIME_FIBERS_FIBER_CONTEXT_H_ 17 #define PANDA_RUNTIME_FIBERS_FIBER_CONTEXT_H_ 18 19 #if defined(PANDA_TARGET_ARM64) 20 #include "runtime/fibers/arch/aarch64/context_layout.h" 21 #elif defined(PANDA_TARGET_ARM32) 22 #include "runtime/fibers/arch/arm/context_layout.h" 23 #elif defined(PANDA_TARGET_X86) 24 #error "Unsupported target" 25 #elif defined(PANDA_TARGET_AMD64) 26 #include "runtime/fibers/arch/amd64/context_layout.h" 27 #else 28 #error "Unsupported target" 29 #endif 30 31 #include <cstddef> 32 #include <cstdint> 33 34 namespace ark::fibers { 35 36 /** 37 * This set of functions implements user mode context switch functionality. 38 * The primary (but not the only one) use case for that is the lightweight user mode threads ("fibers") support. 39 * 40 * These functions allow the user to: 41 * - retrieve current context 42 * - switch back to it 43 * - update the saved context with a new stack (allocated manually elsewhere) and an entrypoint 44 * None of these functions performs any system calls to the OS kernel. 45 */ 46 47 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 48 using FiberContext = uint8_t[FCTX_LEN_BYTES]; 49 using FiberEntry = void (*)(void *); 50 51 /// @brief Saves current usermode context to the provided buffer in memory. 52 extern "C" int GetCurrentContext(FiberContext *ctx); 53 54 /** 55 * @brief Saves current context and switches to the target one. 56 * @param from the buffer to save the current context in 57 * @param to the buffer to load the new context from 58 */ 59 extern "C" int SwitchContext(FiberContext *from, const FiberContext *to); 60 61 /** 62 * @brief Updates the previously saved context with a new stack and a new entry point. 63 * 64 * @param ctx a buffer with a valid saved context (via GetCurrentContext() or SwitchContext()) 65 * @param func the new entry point. After a context switch to ctx with SwitchContext(), the control transfers 66 * to the beginning of func. Upon completion, func should use SwitchContext() to transfer control further. 67 * If func, instead of that, does a simple return, this counts as an abnormal EP termination and the main program 68 * is terminated with an error. 69 * @param argument an optional argument to be passed to the func. Can be nullptr if needed. Might be a pointer to some 70 * structure or class that represents the fiber instance. 71 * @param stack a pointer to the stack to be used by the func. Should point to a preallocated buffer capable of holding 72 * at least stack_size_bytes bytes. Allocation and deallocation of this buffer is the caller's responsibility. 73 * @param stack_size_bytes minimal size of the stack provided 74 */ 75 extern "C" int UpdateContext(FiberContext *ctx, FiberEntry func, void *argument, uint8_t *stack, size_t stackSizeBytes); 76 77 /** 78 * @brief Updates the previously saved context with a new entry point, keeping the original stack. 79 * 80 * Effectively emulates a function call, so EP's return address is the original PC of the saved context. 81 */ 82 extern "C" int UpdateContextKeepStack(FiberContext *ctx, FiberEntry func, void *argument); 83 84 /// @brief Copies the context stored in @param src to @param dst 85 extern "C" PANDA_PUBLIC_API void CopyContext(FiberContext *dst, const FiberContext *src); 86 87 } // namespace ark::fibers 88 89 #endif /* PANDA_RUNTIME_FIBERS_FIBER_CONTEXT_H_ */ 90