- Timestamp:
- Jul 11, 2017, 10:26:53 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r170 r171 1 1 /* 2 2 * thread.c - implementation of thread operations (user & kernel) 3 * 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Alain Greiner (2016,2017) … … 74 74 { 75 75 page_t * page; // pointer on page descriptor containing thread descriptor 76 kmem_req_t req; // kmem request 76 kmem_req_t req; // kmem request 77 77 78 78 // allocates memory for thread descriptor + kernel stack … … 85 85 if( page == NULL ) return NULL; 86 86 else return (thread_t *)ppm_page2vaddr( page ); 87 } 87 } 88 88 89 89 ///////////////////////////////////////////////////////////////////////////////////// … … 141 141 spinlock_unlock( &process->th_lock ); 142 142 143 if( error ) 143 if( error ) 144 144 { 145 145 printk("\n[ERROR] in %s : cannot get TRDID\n", __FUNCTION__ ); … … 149 149 // Initialize new thread descriptor 150 150 thread->trdid = trdid; 151 thread->type = type; 151 thread->type = type; 152 152 thread->quantum = 0; // TODO 153 153 thread->ticks_nr = 0; // TODO … … 162 162 xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) ); 163 163 164 thread->u_stack_base = u_stack_base; 164 thread->u_stack_base = u_stack_base; 165 165 thread->u_stack_size = u_stack_size; 166 thread->k_stack_base = (intptr_t)thread; 166 thread->k_stack_base = (intptr_t)thread; 167 167 thread->k_stack_size = CONFIG_THREAD_DESC_SIZE; 168 168 169 169 thread->entry_func = func; // thread entry point 170 170 thread->entry_args = args; // thread function arguments 171 thread->flags = 0; // all flags reset 171 thread->flags = 0; // all flags reset 172 172 thread->signals = 0; // no pending signal 173 173 thread->errno = 0; // no error detected 174 thread->fork_user = 0; // no fork required 174 thread->fork_user = 0; // no fork required 175 175 thread->fork_cxy = 0; 176 176 … … 195 195 dqdt_local_update_threads( 1 ); 196 196 197 // register new thread in core scheduler 197 // register new thread in core scheduler 198 198 sched_register_thread( thread->core , thread ); 199 199 200 200 return 0; 201 202 } // end thread_init() 203 201 } 204 202 205 203 ///////////////////////////////////////////////////////// … … 228 226 } 229 227 230 // select a target core in local cluster 228 // select a target core in local cluster 231 229 if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid; 232 230 else core_lid = cluster_select_local_core(); … … 237 235 printk("\n[ERROR] in %s : illegal core index attribute = %d\n", 238 236 __FUNCTION__ , core_lid ); 239 237 240 238 return EINVAL; 241 239 } 242 240 243 // allocate a stack from local VMM 241 // allocate a stack from local VMM 244 242 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 245 243 … … 248 246 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 249 247 return ENOMEM; 250 } 251 252 // allocate s memory tor thread descriptor248 } 249 250 // allocate memory for thread descriptor 253 251 thread = thread_alloc(); 254 252 … … 260 258 } 261 259 262 // initialize sthread descriptor260 // initialize thread descriptor 263 261 error = thread_init( thread, 264 262 process, … … 270 268 vseg->max - vseg->min ); 271 269 272 if( error ) 270 if( error ) 273 271 { 274 272 printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ ); … … 278 276 } 279 277 280 // set LOADABLE flag 278 // set LOADABLE flag 281 279 thread->flags = THREAD_FLAG_LOADABLE; 282 280 … … 284 282 if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED; 285 283 286 // allocate & initiali se CPU context287 error = hal_cpu_context_create( thread ); 288 289 if( error ) 284 // allocate & initialize CPU context 285 error = hal_cpu_context_create( thread ); 286 287 if( error ) 290 288 { 291 289 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); … … 295 293 } 296 294 297 // allocate & initiali se FPU context298 error = hal_fpu_context_create( thread ); 295 // allocate & initialize FPU context 296 error = hal_fpu_context_create( thread ); 299 297 300 298 if( error ) … … 306 304 } 307 305 308 thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n", 306 thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n", 309 307 __FUNCTION__ , thread->trdid , process->pid , core_lid ); 310 308 311 309 *new_thread = thread; 312 310 return 0; 313 314 } // end thread_user_create() 315 311 } 316 312 317 313 ////////////////////////////////////////////// … … 326 322 thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ ); 327 323 328 // allocate a stack from local VMM 324 // allocate a stack from local VMM 329 325 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 330 326 … … 333 329 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 334 330 return ENOMEM; 335 } 331 } 336 332 337 333 // select a target core in local cluster … … 341 337 thread_t * this = CURRENT_THREAD; 342 338 343 // allocate dmemory for new thread descriptor339 // allocate memory for new thread descriptor 344 340 thread = thread_alloc(); 345 341 … … 351 347 } 352 348 353 // initialize sthread descriptor349 // initialize thread descriptor 354 350 error = thread_init( thread, 355 351 process, … … 372 368 if( this->flags & THREAD_FLAG_DETACHED ) thread->flags = THREAD_FLAG_DETACHED; 373 369 374 // allocate & initiali se CPU context from calling thread375 error = hal_cpu_context_copy( thread , this ); 370 // allocate & initialize CPU context from calling thread 371 error = hal_cpu_context_copy( thread , this ); 376 372 377 373 if( error ) … … 383 379 } 384 380 385 // allocate & initiali se FPU context from calling thread386 error = hal_fpu_context_copy( thread , this ); 381 // allocate & initialize FPU context from calling thread 382 error = hal_fpu_context_copy( thread , this ); 387 383 388 384 if( error ) … … 394 390 } 395 391 396 thread_dmsg("\n[INFO] %s : exit / thread %x for process %x on core %d in cluster %x\n", 392 thread_dmsg("\n[INFO] %s : exit / thread %x for process %x on core %d in cluster %x\n", 397 393 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy ); 398 394 399 395 *new_thread = thread; 400 396 return 0; 401 402 } // end thread_user_fork() 403 404 397 } 405 398 406 399 ///////////////////////////////////////////////////////// 407 400 error_t thread_kernel_create( thread_t ** new_thread, 408 401 thread_type_t type, 409 void * func, 410 void * args, 402 void * func, 403 void * args, 411 404 lid_t core_lid ) 412 405 { 413 406 error_t error; 414 407 thread_t * thread; // pointer on new thread descriptor 415 kmem_req_t req; // kmem request (for release) 408 kmem_req_t req; // kmem request (for release) 416 409 417 410 thread_dmsg("\n[INFO] %s : enters for type %s in cluster %x\n", 418 411 __FUNCTION__ , thread_type_str( type ) , local_cxy ); 419 412 420 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 413 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 421 414 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 422 415 __FUNCTION__ , "illegal thread type" ); 423 416 424 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , 417 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , 425 418 __FUNCTION__ , "illegal core_lid" ); 426 419 427 // allocate dmemory for new thread descriptor420 // allocate memory for new thread descriptor 428 421 thread = thread_alloc(); 429 422 430 423 if( thread == NULL ) return ENOMEM; 431 424 432 // initialize sthread descriptor425 // initialize thread descriptor 433 426 error = thread_init( thread, 434 427 &process_zero, … … 439 432 0 , 0 ); // no user stack for a kernel thread 440 433 441 if( error ) // release allocated memory for thread descriptor 434 if( error ) // release allocated memory for thread descriptor 442 435 { 443 436 req.type = KMEM_PAGE; … … 447 440 } 448 441 449 450 // allocate & initialise CPU context 451 hal_cpu_context_create( thread ); 452 453 thread_dmsg("\n[INFO] %s : exit in cluster %x / trdid = %x / core_lid = %d\n", 442 // allocate & initialize CPU context 443 hal_cpu_context_create( thread ); 444 445 thread_dmsg("\n[INFO] %s : exit in cluster %x / trdid = %x / core_lid = %d\n", 454 446 __FUNCTION__ , local_cxy , thread->trdid , core_lid ); 455 447 456 *new_thread = thread; 448 *new_thread = thread; 457 449 return 0; 458 459 } // end thread_kernel_create() 450 } 460 451 461 452 /////////////////////////////////////////////////// 462 453 error_t thread_kernel_init( thread_t * thread, 463 454 thread_type_t type, 464 void * func, 465 void * args, 455 void * func, 456 void * args, 466 457 lid_t core_lid ) 467 458 { 468 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 459 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 469 460 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 470 461 __FUNCTION__ , "illegal thread type" ); 471 462 472 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 473 { 474 printk("\n[PANIC] in %s : illegal core_lid / cores = %d / lid = %d / cxy = %x\n", 463 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 464 { 465 printk("\n[PANIC] in %s : illegal core_lid / cores = %d / lid = %d / cxy = %x\n", 475 466 __FUNCTION__ , LOCAL_CLUSTER->cores_nr , core_lid , local_cxy ); 476 467 hal_core_sleep(); … … 487 478 // allocate & initialize CPU context if success 488 479 if( error == 0 ) hal_cpu_context_create( thread ); 489 480 490 481 return error; 491 492 } // end thread_kernel_init() 482 } 493 483 494 484 /////////////////////////////////////////////////////////////////////////////////////// … … 511 501 512 502 assert( (thread->local_locks == 0) , __FUNCTION__ , "all local locks not released" ); 513 503 514 504 assert( (thread->remote_locks == 0) , __FUNCTION__ , "all remote locks not released" ); 515 505 … … 539 529 hal_restore_irq( state ); 540 530 541 // remove thread from process th_tbl[] 531 // remove thread from process th_tbl[] 542 532 // TODO This should be done before calling thread_destroy() 543 533 ltid_t ltid = LTID_FROM_TRDID( thread->trdid ); … … 561 551 thread_dmsg("\n[INFO] %s : exit for thread %x in process %x / duration = %d\n", 562 552 __FUNCTION__, thread->trdid , process->pid , tm_end - tm_start ); 563 564 } // end thread_destroy() 565 553 } 566 554 567 555 ///////////////////////////////////////////////// … … 569 557 xptr_t xp_child ) 570 558 { 571 // get extended pointers on children list root 572 cxy_t parent_cxy = GET_CXY( xp_parent ); 559 // get extended pointers on children list root 560 cxy_t parent_cxy = GET_CXY( xp_parent ); 573 561 thread_t * parent_ptr = (thread_t *)GET_PTR( xp_parent ); 574 562 xptr_t root = XPTR( parent_cxy , &parent_ptr->children_root ); 575 563 576 // get extended pointer on children list entry 577 cxy_t child_cxy = GET_CXY( xp_child ); 564 // get extended pointer on children list entry 565 cxy_t child_cxy = GET_CXY( xp_child ); 578 566 thread_t * child_ptr = (thread_t *)GET_PTR( xp_child ); 579 567 xptr_t entry = XPTR( child_cxy , &child_ptr->brothers_list ); … … 582 570 xlist_add_first( root , entry ); 583 571 hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->children_nr ) , 1 ); 584 } 572 } 585 573 586 574 /////////////////////////////////////////////////// … … 589 577 { 590 578 // get extended pointer on children list lock 591 cxy_t parent_cxy = GET_CXY( xp_parent ); 579 cxy_t parent_cxy = GET_CXY( xp_parent ); 592 580 thread_t * parent_ptr = (thread_t *)GET_PTR( xp_parent ); 593 581 xptr_t lock = XPTR( parent_cxy , &parent_ptr->children_lock ); 594 582 595 // get extended pointer on children list entry 596 cxy_t child_cxy = GET_CXY( xp_child ); 583 // get extended pointer on children list entry 584 cxy_t child_cxy = GET_CXY( xp_child ); 597 585 thread_t * child_ptr = (thread_t *)GET_PTR( xp_child ); 598 586 xptr_t entry = XPTR( child_cxy , &child_ptr->brothers_list ); … … 604 592 xlist_unlink( entry ); 605 593 hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->children_nr ) , -1 ); 606 594 607 595 // release the lock 608 596 remote_spinlock_unlock( lock ); … … 615 603 hal_atomic_or( &thread->signals , mask ); 616 604 } 617 605 618 606 /////////////////////////////////////////////////// 619 607 inline void thread_reset_signal( thread_t * thread, … … 622 610 hal_atomic_and( &thread->signals , ~mask ); 623 611 } 624 612 625 613 ////////////////////////////////// 626 614 inline bool_t thread_is_joinable() … … 693 681 hal_restore_irq( sr_save ); 694 682 } 695 else 696 { 697 // if attached, set blocking cause 683 else 684 { 685 // if attached, set blocking cause 698 686 thread_block( this , THREAD_BLOCKED_EXIT ); 699 687 } … … 702 690 sched_yield(); 703 691 return 0; 704 705 } // end thread_exit() 692 } 706 693 707 694 ///////////////////////////////////// … … 709 696 uint32_t cause ) 710 697 { 711 // set blocking cause 698 // set blocking cause 712 699 hal_atomic_or( &thread->blocked , cause ); 713 714 } // end thread_block() 700 } 715 701 716 702 //////////////////////////////////// … … 719 705 { 720 706 // get thread cluster and local pointer 721 cxy_t cxy = GET_CXY( thread ); 707 cxy_t cxy = GET_CXY( thread ); 722 708 thread_t * ptr = (thread_t *)GET_PTR( thread ); 723 709 724 710 // reset blocking cause 725 711 hal_remote_atomic_and( XPTR( cxy , &ptr->blocked ) , ~cause ); 726 727 } // end thread_unblock() 712 } 728 713 729 714 ///////////////////////////////////// … … 738 723 // send an IPI to reschedule the target thread core. 739 724 dev_icu_send_ipi( local_cxy , target->core->lid ); 740 741 } // end thread_kill() 742 725 } 743 726 744 727 /////////////////////// 745 728 void thread_idle_func() 746 729 { 747 748 730 #if CONFIG_IDLE_DEBUG 749 731 lid_t lid = CURRENT_CORE->lid; … … 767 749 sched_yield(); 768 750 } 769 } // end thread_idle()751 } 770 752 771 753 ///////////////////////////////////////////////// … … 796 778 cxy_t target_cxy; // target thread cluster identifier 797 779 ltid_t target_thread_ltid; // target thread local index 798 thread_t * target_thread_ptr; // target thread local pointer 780 thread_t * target_thread_ptr; // target thread local pointer 799 781 xptr_t target_process_xp; // extended pointer on target process descriptor 800 process_t * target_process_ptr; // local pointer on target process descriptor 782 process_t * target_process_ptr; // local pointer on target process descriptor 801 783 pid_t target_process_pid; // target process identifier 802 784 xlist_entry_t root; // root of list of process in target cluster … … 812 794 sizeof(xlist_entry_t) ); 813 795 814 // get extended pointer on lock protecting the list of processes 796 // get extended pointer on lock protecting the list of processes 815 797 lock_xp = XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_lock ); 816 798 … … 844 826 // get target thread local pointer 845 827 xptr_t xp = XPTR( target_cxy , &target_process_ptr->th_tbl[target_thread_ltid] ); 846 target_thread_ptr = (thread_t *)hal_remote_lpt( xp ); 828 target_thread_ptr = (thread_t *)hal_remote_lpt( xp ); 847 829 848 830 if( target_thread_ptr == NULL ) … … 852 834 853 835 return XPTR( target_cxy , target_thread_ptr ); 854 855 } // end thread_get_xptr() 856 836 } 837
Note: See TracChangeset
for help on using the changeset viewer.