Changeset 408 for trunk/kernel/kern/thread.c
- Timestamp:
- Dec 5, 2017, 4:20:07 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r407 r408 116 116 // - thread_user_fork() 117 117 // - thread_kernel_create() 118 // - thread_user_init()119 118 ///////////////////////////////////////////////////////////////////////////////////// 120 119 // @ thread : pointer on thread descriptor … … 200 199 thread->signature = THREAD_SIGNATURE; 201 200 201 // FIXME call hal_thread_init() function to initialise the save_sr field 202 thread->save_sr = 0xFF13; 203 202 204 // update local DQDT 203 205 dqdt_local_update_threads( 1 ); … … 322 324 } 323 325 326 // update DQDT for new thread 327 dqdt_local_update_threads( 1 ); 328 324 329 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / trdid = %x / process %x / core = %d\n", 325 330 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, … … 331 336 } // end thread_user_create() 332 337 333 //////////////////////////////////////////////////// 334 error_t thread_user_fork( process_t * process, 335 intptr_t stack_base, 336 uint32_t stack_size, 337 thread_t ** new_thread ) 338 /////////////////////////////////////////////////////// 339 error_t thread_user_fork( xptr_t parent_thread_xp, 340 process_t * child_process, 341 thread_t ** child_thread ) 338 342 { 339 343 error_t error; 340 thread_t * child; // pointer on new thread descriptor 341 lid_t core_lid; // selected core local index 342 343 thread_dmsg("\n[DBG] %s : core[%x,%d] enters\n", 344 __FUNCTION__ , local_cxy , core_lid ); 344 thread_t * child_ptr; // local pointer on local child thread 345 lid_t core_lid; // selected core local index 346 347 thread_t * parent_ptr; // local pointer on remote parent thread 348 cxy_t parent_cxy; // parent thread cluster 349 process_t * parent_process; // local pointer on parent process 350 xptr_t parent_gpt_xp; // extended pointer on parent thread GPT 351 352 void * func; // parent thread entry_func 353 void * args; // parent thread entry_args 354 intptr_t base; // parent thread u_stack_base 355 uint32_t size; // parent thread u_stack_size 356 uint32_t flags; // parent_thread flags 357 vpn_t vpn_base; // parent thread stack vpn_base 358 vpn_t vpn_size; // parent thread stack vpn_size 359 reg_t * uzone; // parent thread pointer on uzone 360 361 vseg_t * vseg; // child thread STACK vseg 362 363 thread_dmsg("\n[DBG] %s : core[%x,%d] enters at cycle %d\n", 364 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_get_cycles() ); 345 365 346 366 // select a target core in local cluster 347 367 core_lid = cluster_select_local_core(); 348 368 349 // get pointer on parent thread descriptor 350 thread_t * parent = CURRENT_THREAD; 351 352 // allocate memory for new thread descriptor 353 child = thread_alloc(); 354 355 if( child == NULL ) 369 // get cluster and local pointer on parent thread descriptor 370 parent_cxy = GET_CXY( parent_thread_xp ); 371 parent_ptr = (thread_t *)GET_PTR( parent_thread_xp ); 372 373 // get relevant fields from parent thread 374 func = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func ) ); 375 args = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args ) ); 376 base = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base ) ); 377 size = (uint32_t)hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->u_stack_size ) ); 378 flags = hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->flags ) ); 379 uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone ) ); 380 381 vpn_base = base >> CONFIG_PPM_PAGE_SHIFT; 382 vpn_size = size >> CONFIG_PPM_PAGE_SHIFT; 383 384 // get pointer on parent process in parent thread cluster 385 parent_process = (process_t *)hal_remote_lpt( XPTR( parent_cxy, 386 &parent_ptr->process ) ); 387 388 // get extended pointer on parent GPT in parent thread cluster 389 parent_gpt_xp = XPTR( parent_cxy , &parent_process->vmm.gpt ); 390 391 // allocate memory for child thread descriptor 392 child_ptr = thread_alloc(); 393 if( child_ptr == NULL ) 356 394 { 357 395 printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ ); 358 return ENOMEM;396 return -1; 359 397 } 360 398 361 399 // initialize thread descriptor 362 error = thread_init( child ,363 process,400 error = thread_init( child_ptr, 401 child_process, 364 402 THREAD_USER, 365 parent->entry_func,366 parent->entry_args,403 func, 404 args, 367 405 core_lid, 368 stack_base, 369 stack_size ); 370 406 base, 407 size ); 371 408 if( error ) 372 409 { 373 printk("\n[ERROR] in %s : cannot initialize newthread\n", __FUNCTION__ );374 thread_release( child );410 printk("\n[ERROR] in %s : cannot initialize child thread\n", __FUNCTION__ ); 411 thread_release( child_ptr ); 375 412 return EINVAL; 376 413 } 377 414 378 415 // return child pointer 379 *new_thread = child; 380 381 // set DETACHED flag if required 382 if( parent->flags & THREAD_FLAG_DETACHED ) child->flags = THREAD_FLAG_DETACHED; 416 *child_thread = child_ptr; 417 418 // set detached flag if required 419 if( flags & THREAD_FLAG_DETACHED ) child_ptr->flags = THREAD_FLAG_DETACHED; 420 421 // update uzone pointer in child thread descriptor 422 child_ptr->uzone = (char *)((intptr_t)uzone + 423 (intptr_t)child_ptr - 424 (intptr_t)parent_ptr ); 425 383 426 384 427 // allocate CPU context for child thread 385 if( hal_cpu_context_alloc( child ) )428 if( hal_cpu_context_alloc( child_ptr ) ) 386 429 { 387 430 printk("\n[ERROR] in %s : cannot allocate CPU context\n", __FUNCTION__ ); 388 thread_release( child );389 return ENOMEM;431 thread_release( child_ptr ); 432 return -1; 390 433 } 391 434 392 435 // allocate FPU context for child thread 393 if( hal_fpu_context_alloc( child ) )436 if( hal_fpu_context_alloc( child_ptr ) ) 394 437 { 395 438 printk("\n[ERROR] in %s : cannot allocate FPU context\n", __FUNCTION__ ); 396 thread_release( child ); 397 return ENOMEM; 398 } 399 400 // copy kernel stack content from parent to child thread descriptor 401 void * dst = (void *)(&child->signature) + 4; 402 void * src = (void *)(&parent->signature) + 4; 403 memcpy( dst , src , parent->k_stack_size ); 439 thread_release( child_ptr ); 440 return -1; 441 } 442 443 // create and initialize STACK vseg 444 vseg = vseg_alloc(); 445 vseg_init( vseg, 446 VSEG_TYPE_STACK, 447 base, 448 size, 449 vpn_base, 450 vpn_size, 451 0, 0, XPTR_NULL, // not a file vseg 452 local_cxy ); 453 454 // register STACK vseg in local child VSL 455 vseg_attach( &child_process->vmm , vseg ); 456 457 // copy all valid STACK GPT entries 458 vpn_t vpn; 459 bool_t mapped; 460 ppn_t ppn; 461 for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ ) 462 { 463 error = hal_gpt_pte_copy( &child_process->vmm.gpt, 464 parent_gpt_xp, 465 vpn, 466 true, // set cow 467 &ppn, 468 &mapped ); 469 if( error ) 470 { 471 vseg_detach( &child_process->vmm , vseg ); 472 vseg_free( vseg ); 473 thread_release( child_ptr ); 474 printk("\n[ERROR] in %s : cannot update child GPT\n", __FUNCTION__ ); 475 return -1; 476 } 477 478 // increment page descriptor fork_nr for the referenced page if mapped 479 if( mapped ) 480 { 481 xptr_t page_xp = ppm_ppn2page( ppn ); 482 cxy_t page_cxy = GET_CXY( page_xp ); 483 page_t * page_ptr = (page_t *)GET_PTR( page_xp ); 484 hal_remote_atomic_add( XPTR( page_cxy , &page_ptr->fork_nr ) , 1 ); 485 486 thread_dmsg("\n[DBG] %s : core[%x,%d] copied PTE to child GPT : vpn %x\n", 487 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ); 488 489 } 490 } 491 492 // set COW flag for STAK vseg in parent thread GPT 493 hal_gpt_flip_cow( true, // set cow 494 parent_gpt_xp, 495 vpn_base, 496 vpn_size ); 497 498 // update DQDT for child thread 499 dqdt_local_update_threads( 1 ); 404 500 405 501 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / created main thread %x for process %x\n", 406 __FUNCTION__, local_cxy , core_lid , child->trdid ,process->pid );502 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, child_ptr->trdid, child_process->pid ); 407 503 408 504 return 0; … … 452 548 hal_cpu_context_create( thread ); 453 549 550 // update DQDT for kernel thread 551 dqdt_local_update_threads( 1 ); 552 454 553 thread_dmsg("\n[DBG] %s : core = [%x,%d] exit / trdid = %x / type %s / cycle %d\n", 455 554 __FUNCTION__, local_cxy, core_lid, thread->trdid, thread_type_str(type), hal_time_stamp() ); … … 511 610 512 611 // update intrumentation values 513 uint32_t pgfaults = thread->info.pgfault_nr; 514 uint32_t u_errors = thread->info.u_err_nr; 515 uint32_t m_errors = thread->info.m_err_nr; 516 517 process->vmm.pgfault_nr += pgfaults; 518 process->vmm.u_err_nr += u_errors; 519 process->vmm.m_err_nr += m_errors; 612 process->vmm.pgfault_nr += thread->info.pgfault_nr; 520 613 521 614 // release memory allocated for CPU context and FPU context … … 635 728 { 636 729 this->flags &= ~THREAD_FLAG_SCHED; 637 sched_yield( );730 sched_yield( "delayed scheduling" ); 638 731 } 639 732 … … 697 790 698 791 // deschedule 699 sched_yield( );792 sched_yield( "exit" ); 700 793 return 0; 701 794 … … 721 814 while( 1 ) 722 815 { 816 // unmask IRQs 817 hal_enable_irq( NULL ); 818 723 819 if( CONFIG_THREAD_IDLE_MODE_SLEEP ) // force core to low-power mode 724 820 { … … 740 836 741 837 // force scheduling at each iteration 742 sched_yield( );838 sched_yield( "idle" ); 743 839 } 744 840 } // end thread_idle() … … 754 850 /////////////////////////////////////////////////// 755 851 void thread_kernel_time_update( thread_t * thread ) 756 {757 // TODO758 // printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );759 }760 761 ////////////////////////////////////////////////762 void thread_signals_handle( thread_t * thread )763 852 { 764 853 // TODO
Note: See TracChangeset
for help on using the changeset viewer.