Changeset ed7e057 in mainline for kernel/generic/include/context.h
- Timestamp:
- 2024-01-16T15:46:47Z (12 months ago)
- Branches:
- master
- Children:
- 29029ac0, a5b5f17
- Parents:
- 4ed7870
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-01-15 20:09:30)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-01-16 15:46:47)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/context.h
r4ed7870 red7e057 36 36 #define KERN_CONTEXT_H_ 37 37 38 #include <panic.h> 38 39 #include <trace.h> 39 40 #include <arch/context.h> 41 #include <arch/faddr.h> 40 42 41 43 #define context_set_generic(ctx, _pc, stack, size) \ … … 47 49 extern int context_save_arch(context_t *ctx) __attribute__((returns_twice)); 48 50 extern void context_restore_arch(context_t *ctx) __attribute__((noreturn)); 49 50 /** Save register context.51 *52 * Save the current register context (including stack pointer) to a context53 * structure. A subsequent call to context_restore() will return to the same54 * address as the corresponding call to context_save().55 *56 * Note that context_save_arch() must reuse the stack frame of the function57 * which called context_save(). We guarantee this by:58 *59 * a) implementing context_save_arch() in assembly so that it does not create60 * its own stack frame, and by61 * b) defining context_save() as a macro because the inline keyword is just a62 * hint for the compiler, not a real constraint; the application of a macro63 * will definitely not create a stack frame either.64 *65 * To imagine what could happen if there were some extra stack frames created66 * either by context_save() or context_save_arch(), we need to realize that the67 * sp saved in the contex_t structure points to the current stack frame as it68 * existed when context_save_arch() was executing. After the return from69 * context_save_arch() and context_save(), any extra stack frames created by70 * these functions will be destroyed and their contents sooner or later71 * overwritten by functions called next. Any attempt to restore to a context72 * saved like that would therefore lead to a disaster.73 *74 * @param ctx Context structure.75 *76 * @return context_save() returns 1, context_restore() returns 0.77 *78 */79 #define context_save(ctx) context_save_arch(ctx)80 51 81 52 /** Restore register context. … … 91 62 * 92 63 */ 93 _NO_TRACE static inline void context_restore(context_t *ctx) 64 _NO_TRACE __attribute__((noreturn)) 65 static inline void context_restore(context_t *ctx) 94 66 { 95 67 context_restore_arch(ctx); 68 } 69 70 /** 71 * Saves current context to the variable pointed to by `self`, 72 * and restores the context denoted by `other`. 73 * 74 * When the `self` context is later restored by another call to 75 * `context_swap()`, the control flow behaves as if the earlier call to 76 * `context_swap()` just returned. 77 */ 78 _NO_TRACE static inline void context_swap(context_t *self, context_t *other) 79 { 80 if (context_save_arch(self)) 81 context_restore_arch(other); 82 } 83 84 _NO_TRACE static inline void context_create(context_t *context, 85 void (*fn)(void), void *stack_base, size_t stack_size) 86 { 87 *context = (context_t) { 0 }; 88 context_set(context, FADDR(fn), stack_base, stack_size); 89 } 90 91 __attribute__((noreturn)) static inline void context_replace(void (*fn)(void), 92 void *stack_base, size_t stack_size) 93 { 94 context_t ctx; 95 context_create(&ctx, fn, stack_base, stack_size); 96 context_restore(&ctx); 96 97 } 97 98
Note:
See TracChangeset
for help on using the changeset viewer.