- Timestamp:
- Nov 10, 2020, 2:45:16 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 1d379b5
- Parents:
- 685810e (diff), b82d140 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- libcfa/src/concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/fwd.hfa
r685810e rf33eab7 65 65 66 66 extern uintptr_t __cfatls_get( unsigned long int member ); 67 // #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) )) 68 #define publicTLS_get( member ) (__cfaabi_tls.member) 69 // extern forall(otype T) T __cfatls_get( T * member, T value ); 70 // #define publicTLS_set( member, value ) __cfatls_set( (typeof(member)*)__builtin_offsetof(KernelThreadData, member), value ); 67 #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) )) 71 68 72 69 static inline uint64_t __tls_rand() { -
libcfa/src/concurrency/preemption.cfa
r685810e rf33eab7 231 231 } 232 232 233 struct asm_region { 234 void * before; 235 void * after; 236 }; 237 238 static inline bool __cfaasm_in( void * ip, struct asm_region & region ) { 239 return ip >= region.before && ip <= region.after; 240 } 241 242 233 243 //---------- 234 244 // Get data from the TLS block 245 // struct asm_region __cfaasm_get; 235 246 uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems 236 247 uintptr_t __cfatls_get( unsigned long int offset ) { 248 // __cfaasm_get.before = ({ void * value; asm("movq $__cfaasm_get_before, %[v]\n\t" : [v]"=r"(value) ); value; }); 249 // __cfaasm_get.after = ({ void * value; asm("movq $__cfaasm_get_after , %[v]\n\t" : [v]"=r"(value) ); value; }); 237 250 // create a assembler label before 238 251 // marked as clobber all to avoid movement … … 253 266 // create a assembler label before 254 267 // marked as clobber all to avoid movement 255 asm volatile("__cfaasm_d isable_before:":::"memory");268 asm volatile("__cfaasm_dsable_before:":::"memory"); 256 269 257 270 with( __cfaabi_tls.preemption_state ) { … … 275 288 // create a assembler label after 276 289 // marked as clobber all to avoid movement 277 asm volatile("__cfaasm_d isable_after:":::"memory");290 asm volatile("__cfaasm_dsable_after:":::"memory"); 278 291 } 279 292 … … 283 296 // create a assembler label before 284 297 // marked as clobber all to avoid movement 285 asm volatile("__cfaasm_en able_before:":::"memory");298 asm volatile("__cfaasm_enble_before:":::"memory"); 286 299 287 300 processor * proc = __cfaabi_tls.this_processor; // Cache the processor now since interrupts can start happening after the atomic store … … 318 331 // create a assembler label after 319 332 // marked as clobber all to avoid movement 320 asm volatile("__cfaasm_en able_after:":::"memory");333 asm volatile("__cfaasm_enble_after:":::"memory"); 321 334 } 322 335 … … 386 399 } 387 400 401 //----------------------------------------------------------------------------- 402 // Some assembly required 403 #if defined( __i386 ) 404 #ifdef __PIC__ 405 #define RELOC_PRELUDE( label ) \ 406 "calll .Lcfaasm_prelude_" #label "$pb\n\t" \ 407 ".Lcfaasm_prelude_" #label "$pb:\n\t" \ 408 "popl %%eax\n\t" \ 409 ".Lcfaasm_prelude_" #label "_end:\n\t" \ 410 "addl $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t" 411 #define RELOC_PREFIX "" 412 #define RELOC_SUFFIX "@GOT(%%eax)" 413 #else 414 #define RELOC_PREFIX "$" 415 #define RELOC_SUFFIX "" 416 #endif 417 #define __cfaasm_label( label ) static struct asm_region label = \ 418 ({ \ 419 struct asm_region region; \ 420 asm( \ 421 RELOC_PRELUDE( label ) \ 422 "movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \ 423 "movl " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \ 424 : [vb]"=r"(region.before), [va]"=r"(region.after) \ 425 ); \ 426 region; \ 427 }); 428 #elif defined( __x86_64 ) 429 #ifdef __PIC__ 430 #define RELOC_PREFIX "" 431 #define RELOC_SUFFIX "@GOTPCREL(%%rip)" 432 #else 433 #define RELOC_PREFIX "$" 434 #define RELOC_SUFFIX "" 435 #endif 436 #define __cfaasm_label( label ) static struct asm_region label = \ 437 ({ \ 438 struct asm_region region; \ 439 asm( \ 440 "movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \ 441 "movq " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \ 442 : [vb]"=r"(region.before), [va]"=r"(region.after) \ 443 ); \ 444 region; \ 445 }); 446 #elif defined( __aarch64__ ) 447 #ifdef __PIC__ 448 #define RELOC_TAG "@PLT" 449 #else 450 #define RELOC_TAG "" 451 #endif 452 #define __cfaasm_label( label ) \ 453 ({ \ 454 struct asm_region region; \ 455 asm( \ 456 "mov %[vb], __cfaasm_" #label "_before@GOTPCREL(%%rip)" "\n\t" \ 457 "mov %[va], __cfaasm_" #label "_after@GOTPCREL(%%rip)" "\n\t" \ 458 : [vb]"=r"(region.before), [va]"=r"(region.after) \ 459 ); \ 460 region; \ 461 }); 462 #else 463 #error unknown hardware architecture 464 #endif 465 388 466 // KERNEL ONLY 389 467 // Check if a __cfactx_switch signal handler shoud defer 390 468 // If true : preemption is safe 391 469 // If false : preemption is unsafe and marked as pending 392 static inline bool preemption_ready() { 470 static inline bool preemption_ready( void * ip ) { 471 // Get all the region for which it is not safe to preempt 472 __cfaasm_label( get ); 473 __cfaasm_label( check ); 474 __cfaasm_label( dsable ); 475 __cfaasm_label( enble ); 476 __cfaasm_label( nopoll ); 477 393 478 // Check if preemption is safe 394 bool ready = __cfaabi_tls.preemption_state.enabled && ! __cfaabi_tls.preemption_state.in_progress; 395 479 bool ready = true; 480 if( __cfaasm_in( ip, get ) ) { ready = false; goto EXIT; }; 481 if( __cfaasm_in( ip, check ) ) { ready = false; goto EXIT; }; 482 if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; }; 483 if( __cfaasm_in( ip, enble ) ) { ready = false; goto EXIT; }; 484 if( __cfaasm_in( ip, nopoll ) ) { ready = false; goto EXIT; }; 485 if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; }; 486 if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; }; 487 488 EXIT: 396 489 // Adjust the pending flag accordingly 397 490 __cfaabi_tls.this_processor->pending_preemption = !ready; … … 468 561 // Kernel Signal Handlers 469 562 //============================================================================================= 470 struct asm_region {471 void * before;472 void * after;473 };474 475 //-----------------------------------------------------------------------------476 // Some assembly required477 #if defined( __i386 )478 #define __cfaasm_label( label ) \479 ({ \480 struct asm_region region; \481 asm( \482 "movl $__cfaasm_" #label "_before, %[vb]\n\t" \483 "movl $__cfaasm_" #label "_after , %[va]\n\t" \484 : [vb]"=r"(region.before), [vb]"=r"(region.before) \485 ); \486 region; \487 });488 #elif defined( __x86_64 )489 #ifdef __PIC__490 #define PLT "@PLT"491 #else492 #define PLT ""493 #endif494 #define __cfaasm_label( label ) \495 ({ \496 struct asm_region region; \497 asm( \498 "movq $__cfaasm_" #label "_before" PLT ", %[vb]\n\t" \499 "movq $__cfaasm_" #label "_after" PLT ", %[va]\n\t" \500 : [vb]"=r"(region.before), [va]"=r"(region.after) \501 ); \502 region; \503 });504 #elif defined( __aarch64__ )505 #error __cfaasm_label undefined for arm506 #else507 #error unknown hardware architecture508 #endif509 510 563 __cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; ) 511 564 … … 530 583 531 584 // Check if it is safe to preempt here 532 if( !preemption_ready() ) { return; } 533 534 struct asm_region region; 535 region = __cfaasm_label( get ); if( ip >= region.before && ip <= region.after ) return; 536 region = __cfaasm_label( check ); if( ip >= region.before && ip <= region.after ) return; 537 region = __cfaasm_label( disable ); if( ip >= region.before && ip <= region.after ) return; 538 region = __cfaasm_label( enable ); if( ip >= region.before && ip <= region.after ) return; 539 region = __cfaasm_label( nopoll ); if( ip >= region.before && ip <= region.after ) return; 585 if( !preemption_ready( ip ) ) { return; } 540 586 541 587 __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", __cfaabi_tls.this_processor, __cfaabi_tls.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
Note: See TracChangeset
for help on using the changeset viewer.