Changeset e0a4686 in mainline
- Timestamp:
- 2018-03-08T18:25:31Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 53ad43c, 615e83d
- Parents:
- fd57cf17
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-06 22:03:11)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-08 18:25:31)
- Location:
- uspace
- Files:
-
- 3 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/taskdump/fibrildump.c
rfd57cf17 re0a4686 110 110 return EIO; 111 111 112 pc = fibril.ctx.pc;112 pc = context_get_pc(&fibril.ctx); 113 113 fp = context_get_fp(&fibril.ctx); 114 114 if (0) stacktrace_print_generic(&fibrildump_st_ops, sess, -
uspace/lib/c/Makefile
rfd57cf17 re0a4686 65 65 generic/clipboard.c \ 66 66 generic/config.c \ 67 generic/context.c \ 67 68 generic/corecfg.c \ 68 69 generic/devman.c \ -
uspace/lib/c/arch/abs32le/include/libarch/fibril.h
rfd57cf17 re0a4686 37 37 38 38 #include <stdint.h> 39 #include <libarch/fibril_context.h> 39 40 40 41 #define SP_DELTA 0 … … 48 49 } while (0) 49 50 50 /* 51 * On real hardware this stores the registers which 52 * need to be preserved across function calls. 53 */ 54 typedef struct { 55 uintptr_t sp; 56 uintptr_t fp; 57 uintptr_t pc; 58 uintptr_t tls; 59 } context_t; 60 61 static inline uintptr_t context_get_fp(context_t *ctx) 51 static inline uintptr_t _context_get_fp(context_t *ctx) 62 52 { 63 53 /* On real hardware, this function returns the frame pointer. */ -
uspace/lib/c/arch/amd64/include/libarch/fibril.h
rfd57cf17 re0a4686 53 53 } while (0) 54 54 55 static inline uintptr_t context_get_fp(context_t *ctx)55 static inline uintptr_t _context_get_fp(context_t *ctx) 56 56 { 57 57 return ctx->rbp; -
uspace/lib/c/arch/arm32/include/libarch/fibril.h
rfd57cf17 re0a4686 67 67 } while (0) 68 68 69 static inline uintptr_t context_get_fp(context_t *ctx)69 static inline uintptr_t _context_get_fp(context_t *ctx) 70 70 { 71 71 return ctx->fp; -
uspace/lib/c/arch/ia32/include/libarch/fibril.h
rfd57cf17 re0a4686 54 54 } while (0) 55 55 56 static inline uintptr_t context_get_fp(context_t *ctx)56 static inline uintptr_t _context_get_fp(context_t *ctx) 57 57 { 58 58 return ctx->ebp; -
uspace/lib/c/arch/ia64/include/libarch/fibril.h
rfd57cf17 re0a4686 65 65 } while (0) 66 66 67 static inline uintptr_t context_get_fp(context_t *ctx)67 static inline uintptr_t _context_get_fp(context_t *ctx) 68 68 { 69 69 return 0; /* FIXME */ -
uspace/lib/c/arch/mips32/include/libarch/fibril.h
rfd57cf17 re0a4686 57 57 } while (0) 58 58 59 static inline uintptr_t context_get_fp(context_t *ctx)59 static inline uintptr_t _context_get_fp(context_t *ctx) 60 60 { 61 61 return ctx->sp; -
uspace/lib/c/arch/ppc32/include/libarch/fibril.h
rfd57cf17 re0a4686 54 54 } while (0) 55 55 56 static inline uintptr_t context_get_fp(context_t *ctx)56 static inline uintptr_t _context_get_fp(context_t *ctx) 57 57 { 58 58 return ctx->sp; -
uspace/lib/c/arch/riscv64/include/libarch/fibril.h
rfd57cf17 re0a4686 59 59 } context_t; 60 60 61 static inline uintptr_t context_get_fp(context_t *ctx)61 static inline uintptr_t _context_get_fp(context_t *ctx) 62 62 { 63 63 /* This function returns the frame pointer. */ -
uspace/lib/c/arch/sparc64/include/libarch/fibril.h
rfd57cf17 re0a4686 52 52 } while (0) 53 53 54 static inline uintptr_t context_get_fp(context_t *ctx)54 static inline uintptr_t _context_get_fp(context_t *ctx) 55 55 { 56 56 return ctx->sp + STACK_BIAS; -
uspace/lib/c/generic/fibril.c
rfd57cf17 re0a4686 44 44 #include <stdio.h> 45 45 #include <libarch/barrier.h> 46 #include < libarch/faddr.h>46 #include <context.h> 47 47 #include <futex.h> 48 48 #include <assert.h> … … 155 155 futex_lock(&fibril_futex); 156 156 157 fibril_t *srcf = __tcb_get()->fibril_data; 158 fibril_t *dstf = NULL; 159 160 /* Choose a new fibril to run */ 157 161 switch (stype) { 162 case FIBRIL_TO_MANAGER: 163 case FIBRIL_FROM_DEAD: 164 /* Make sure the async_futex is held. */ 165 assert((atomic_signed_t) async_futex.val.count <= 0); 166 167 /* If we are going to manager and none exists, create it */ 168 while (list_empty(&manager_list)) { 169 futex_unlock(&fibril_futex); 170 async_create_manager(); 171 futex_lock(&fibril_futex); 172 } 173 174 dstf = list_get_instance(list_first(&manager_list), 175 fibril_t, link); 176 177 if (stype == FIBRIL_FROM_DEAD) 178 dstf->clean_after_me = srcf; 179 break; 158 180 case FIBRIL_PREEMPT: 159 181 case FIBRIL_FROM_MANAGER: … … 162 184 return 0; 163 185 } 164 break; 165 case FIBRIL_TO_MANAGER: 166 case FIBRIL_FROM_DEAD: 167 /* Make sure the async_futex is held. */ 168 assert((atomic_signed_t) async_futex.val.count <= 0); 169 170 /* If we are going to manager and none exists, create it */ 171 while (list_empty(&manager_list)) { 172 futex_unlock(&fibril_futex); 173 async_create_manager(); 174 futex_lock(&fibril_futex); 175 } 176 break; 177 } 178 179 fibril_t *srcf = __tcb_get()->fibril_data; 180 if (stype != FIBRIL_FROM_DEAD) { 181 182 /* Save current state */ 183 if (!context_save(&srcf->ctx)) { 184 if (srcf->clean_after_me) { 185 /* 186 * Cleanup after the dead fibril from which we 187 * restored context here. 188 */ 189 void *stack = srcf->clean_after_me->stack; 190 if (stack) { 191 /* 192 * This check is necessary because a 193 * thread could have exited like a 194 * normal fibril using the 195 * FIBRIL_FROM_DEAD switch type. In that 196 * case, its fibril will not have the 197 * stack member filled. 198 */ 199 as_area_destroy(stack); 200 } 201 fibril_teardown(srcf->clean_after_me, true); 202 srcf->clean_after_me = NULL; 203 } 204 205 return 1; /* futex_unlock already done here */ 206 } 207 208 /* Put the current fibril into the correct run list */ 209 switch (stype) { 210 case FIBRIL_PREEMPT: 211 list_append(&srcf->link, &ready_list); 212 break; 213 case FIBRIL_FROM_MANAGER: 214 list_append(&srcf->link, &manager_list); 215 break; 216 default: 217 assert(stype == FIBRIL_TO_MANAGER); 218 219 srcf->switches++; 220 221 /* 222 * Don't put the current fibril into any list, it should 223 * already be somewhere, or it will be lost. 224 */ 225 break; 226 } 227 } 228 229 fibril_t *dstf; 230 231 /* Choose a new fibril to run */ 232 switch (stype) { 233 case FIBRIL_TO_MANAGER: 234 case FIBRIL_FROM_DEAD: 235 dstf = list_get_instance(list_first(&manager_list), fibril_t, 236 link); 237 238 if (stype == FIBRIL_FROM_DEAD) 239 dstf->clean_after_me = srcf; 240 break; 241 default: 186 242 187 dstf = list_get_instance(list_first(&ready_list), fibril_t, 243 188 link); 244 189 break; 245 190 } 246 247 191 list_remove(&dstf->link); 192 193 /* Put the current fibril into the correct run list */ 194 switch (stype) { 195 case FIBRIL_PREEMPT: 196 list_append(&srcf->link, &ready_list); 197 break; 198 case FIBRIL_FROM_MANAGER: 199 list_append(&srcf->link, &manager_list); 200 break; 201 case FIBRIL_FROM_DEAD: 202 // Nothing. 203 break; 204 case FIBRIL_TO_MANAGER: 205 srcf->switches++; 206 /* 207 * Don't put the current fibril into any list, it should 208 * already be somewhere, or it will be lost. 209 */ 210 break; 211 } 248 212 249 213 futex_unlock(&fibril_futex); … … 255 219 #endif 256 220 257 context_restore(&dstf->ctx); 258 /* not reached */ 221 /* Swap to the next fibril. */ 222 context_swap(&srcf->ctx, &dstf->ctx); 223 224 /* Restored by another fibril! */ 225 226 if (srcf->clean_after_me) { 227 /* 228 * Cleanup after the dead fibril from which we 229 * restored context here. 230 */ 231 void *stack = srcf->clean_after_me->stack; 232 if (stack) { 233 /* 234 * This check is necessary because a 235 * thread could have exited like a 236 * normal fibril using the 237 * FIBRIL_FROM_DEAD switch type. In that 238 * case, its fibril will not have the 239 * stack member filled. 240 */ 241 as_area_destroy(stack); 242 } 243 fibril_teardown(srcf->clean_after_me, true); 244 srcf->clean_after_me = NULL; 245 } 246 247 return 1; 259 248 } 260 249 … … 289 278 fibril->arg = arg; 290 279 291 context_save(&fibril->ctx); 292 context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack, 293 stack_size, fibril->tcb); 294 280 context_create_t sctx = { 281 .fn = fibril_main, 282 .stack_base = fibril->stack, 283 .stack_size = stack_size, 284 .tls = fibril->tcb, 285 }; 286 287 context_create(&fibril->ctx, &sctx); 295 288 return (fid_t) fibril; 296 289 } -
uspace/lib/c/generic/fibril_synch.c
rfd57cf17 re0a4686 73 73 if (oi->owned_by == f) 74 74 break; 75 stacktrace_print_fp_pc(context_get_fp(&oi->owned_by->ctx), 76 oi->owned_by->ctx.pc); 75 stacktrace_print_fp_pc( 76 context_get_fp(&oi->owned_by->ctx), 77 context_get_pc(&oi->owned_by->ctx)); 77 78 printf("Fibril %p waits for primitive %p.\n", 78 79 oi->owned_by, oi->owned_by->waits_for); -
uspace/lib/c/generic/setjmp.c
rfd57cf17 re0a4686 37 37 38 38 #include <setjmp.h> 39 #include <libarch/fibril.h> 40 #include <fibril.h> 39 #include <context.h> 40 41 // TODO: setjmp/longjmp are basically a stronger version of 42 // context_save/context_restore. It would be preferable to turn 43 // those two into setjmp/longjmp (all it would need is preserving the 44 // return value). 41 45 42 46 /** … … 52 56 env[0].return_value = (val == 0) ? 1 : val; 53 57 context_restore(&env[0].context); 54 __builtin_unreachable();55 58 } 56 59 -
uspace/lib/c/include/fibril.h
rfd57cf17 re0a4686 36 36 #define LIBC_FIBRIL_H_ 37 37 38 #include < libarch/fibril.h>38 #include <context.h> 39 39 #include <types/common.h> 40 40 #include <adt/list.h> 41 41 #include <libarch/tls.h> 42 43 #define context_set_generic(c, _pc, stack, size, ptls) \44 do { \45 (c)->pc = (sysarg_t) (_pc); \46 (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \47 (c)->tls = (sysarg_t) (ptls); \48 } while (0)49 42 50 43 #define FIBRIL_WRITER 1 … … 86 79 #define fibril_local __thread 87 80 88 extern int context_save(context_t *ctx) __attribute__((returns_twice));89 extern void context_restore(context_t *ctx) __attribute__((noreturn));90 91 81 #define FIBRIL_DFLT_STK_SIZE 0 92 82 93 #define fibril_create(func, arg) \94 fibril_create_generic((func), (arg), FIBRIL_DFLT_STK_SIZE)95 83 extern fid_t fibril_create_generic(errno_t (*func)(void *), void *arg, size_t); 96 84 extern void fibril_destroy(fid_t fid); … … 103 91 extern fid_t fibril_get_id(void); 104 92 93 static inline fid_t fibril_create(errno_t (*func)(void *), void *arg) 94 { 95 return fibril_create_generic(func, arg, FIBRIL_DFLT_STK_SIZE); 96 } 97 105 98 static inline int fibril_yield(void) 106 99 {
Note:
See TracChangeset
for help on using the changeset viewer.