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