Changes in kernel/generic/include/context.h [ed7e057:8df5f20] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/context.h
red7e057 r8df5f20 36 36 #define KERN_CONTEXT_H_ 37 37 38 #include <panic.h>39 38 #include <trace.h> 40 39 #include <arch/context.h> 41 #include <arch/faddr.h>42 40 43 41 #define context_set_generic(ctx, _pc, stack, size) \ … … 49 47 extern int context_save_arch(context_t *ctx) __attribute__((returns_twice)); 50 48 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 context 53 * structure. A subsequent call to context_restore() will return to the same 54 * address as the corresponding call to context_save(). 55 * 56 * Note that context_save_arch() must reuse the stack frame of the function 57 * which called context_save(). We guarantee this by: 58 * 59 * a) implementing context_save_arch() in assembly so that it does not create 60 * its own stack frame, and by 61 * b) defining context_save() as a macro because the inline keyword is just a 62 * hint for the compiler, not a real constraint; the application of a macro 63 * will definitely not create a stack frame either. 64 * 65 * To imagine what could happen if there were some extra stack frames created 66 * either by context_save() or context_save_arch(), we need to realize that the 67 * sp saved in the contex_t structure points to the current stack frame as it 68 * existed when context_save_arch() was executing. After the return from 69 * context_save_arch() and context_save(), any extra stack frames created by 70 * these functions will be destroyed and their contents sooner or later 71 * overwritten by functions called next. Any attempt to restore to a context 72 * 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) 51 80 52 81 /** Restore register context. … … 62 91 * 63 92 */ 64 _NO_TRACE __attribute__((noreturn)) 65 static inline void context_restore(context_t *ctx) 93 _NO_TRACE static inline void context_restore(context_t *ctx) 66 94 { 67 95 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 to75 * `context_swap()`, the control flow behaves as if the earlier call to76 * `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);97 96 } 98 97
Note:
See TracChangeset
for help on using the changeset viewer.