Changeset 443 for trunk/kernel/kern
- Timestamp:
- May 16, 2018, 4:15:22 PM (7 years ago)
- Location:
- trunk/kernel/kern
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/cluster.c
r440 r443 34 34 #include <spinlock.h> 35 35 #include <core.h> 36 #include <chdev.h> 36 37 #include <scheduler.h> 37 38 #include <list.h> … … 49 50 ///////////////////////////////////////////////////////////////////////////////////// 50 51 51 extern process_t process_zero; // allocated in kernel_init.c file52 53 54 /////////////////////////////////////////////// //52 extern process_t process_zero; // allocated in kernel_init.c file 53 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c file 54 55 ///////////////////////////////////////////////n 55 56 error_t cluster_init( struct boot_info_s * info ) 56 57 { … … 252 253 253 254 ////////////////////////////////////////////////////// 255 xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy, 256 pid_t pid ) 257 { 258 xptr_t root_xp; // xptr on root of list of processes in owner cluster 259 xptr_t lock_xp; // xptr on lock protecting this list 260 xptr_t iter_xp; // iterator 261 xptr_t current_xp; // xptr on current process descriptor 262 bool_t found; 263 264 cluster_t * cluster = LOCAL_CLUSTER; 265 266 // get owner cluster and lpid 267 cxy_t owner_cxy = CXY_FROM_PID( pid ); 268 lpid_t lpid = LPID_FROM_PID( pid ); 269 270 // get lock & root of list of copies from owner cluster 271 root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 272 lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 273 274 // take the lock protecting the list of processes 275 remote_spinlock_lock( lock_xp ); 276 277 // scan list of processes 278 found = false; 279 XLIST_FOREACH( root_xp , iter_xp ) 280 { 281 current_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 282 283 if( GET_CXY( current_xp ) == cxy ) 284 { 285 found = true; 286 break; 287 } 288 } 289 290 // release the lock protecting the list of processes 291 remote_spinlock_unlock( lock_xp ); 292 293 // return extended pointer on process descriptor in owner cluster 294 if( found ) return current_xp; 295 else return XPTR_NULL; 296 297 } // end cluster_get_process_from_pid_in_cxy() 298 299 300 ////////////////////////////////////////////////////// 254 301 xptr_t cluster_get_owner_process_from_pid( pid_t pid ) 255 302 { … … 298 345 } // end cluster_get_owner_process_from_pid() 299 346 347 300 348 ////////////////////////////////////////////////////////// 301 349 xptr_t cluster_get_reference_process_from_pid( pid_t pid ) … … 459 507 void cluster_process_local_link( process_t * process ) 460 508 { 461 uint32_t irq_state; 509 reg_t save_sr; 510 462 511 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 463 512 513 // get extended pointers on local process list root & lock 514 xptr_t root_xp = XPTR( local_cxy , &pm->local_root ); 515 xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock ); 516 464 517 // get lock protecting the process manager local list 465 remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , & irq_state);466 467 xlist_add_last( XPTR( local_cxy , &pm->local_root ),468 518 remote_spinlock_lock_busy( lock_xp , &save_sr ); 519 520 // register process in local list 521 xlist_add_last( root_xp , XPTR( local_cxy , &process->local_list ) ); 469 522 pm->local_nr++; 470 523 471 524 // release lock protecting the process manager local list 472 remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state);525 remote_spinlock_unlock_busy( lock_xp , save_sr ); 473 526 } 474 527 … … 476 529 void cluster_process_local_unlink( process_t * process ) 477 530 { 478 uint32_t irq_state; 531 reg_t save_sr; 532 479 533 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 480 534 535 // get extended pointers on local process list lock 536 xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock ); 537 481 538 // get lock protecting the process manager local list 482 remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , &irq_state ); 483 539 remote_spinlock_lock_busy( lock_xp , &save_sr ); 540 541 // remove process from local list 484 542 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); 485 543 pm->local_nr--; 486 544 487 545 // release lock protecting the process manager local list 488 remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state);546 remote_spinlock_unlock_busy( lock_xp , save_sr ); 489 547 } 490 548 … … 582 640 { 583 641 xptr_t root_xp; 642 xptr_t lock_xp; 584 643 xptr_t iter_xp; 585 xptr_t process_xp; 586 587 // get extended pointer on root of process in cluster cxy 644 xptr_t process_xp; 645 cxy_t txt0_cxy; 646 chdev_t * txt0_ptr; 647 xptr_t txt0_xp; 648 xptr_t txt0_lock_xp; 649 reg_t txt0_save_sr; // save SR to take TXT0 lock in busy mode 650 651 assert( (cluster_is_undefined( cxy ) == false), 652 __FUNCTION__, "illegal cluster index" ); 653 654 // get extended pointer on root and lock for local process list in cluster 588 655 root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root ); 589 590 // skip one line 591 printk("\n***** processes in cluster %x / cycle %d\n", cxy , (uint32_t)hal_get_cycles() ); 592 593 // loop on all reference processes in cluster cxy 656 lock_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_lock ); 657 658 // get pointers on TXT0 chdev 659 txt0_xp = chdev_dir.txt_tx[0]; 660 txt0_cxy = GET_CXY( txt0_xp ); 661 txt0_ptr = GET_PTR( txt0_xp ); 662 663 // get extended pointer on TXT0 lock 664 txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 665 666 // get lock on local process list 667 remote_spinlock_lock( lock_xp ); 668 669 // get TXT0 lock in busy waiting mode 670 remote_spinlock_lock_busy( txt0_lock_xp , &txt0_save_sr ); 671 672 // display header 673 nolock_printk("\n***** processes in cluster %x / cycle %d\n", 674 cxy , (uint32_t)hal_get_cycles() ); 675 676 // loop on all processes in cluster cxy 594 677 XLIST_FOREACH( root_xp , iter_xp ) 595 678 { … … 597 680 process_display( process_xp ); 598 681 } 682 683 // release TXT0 lock in busy waiting mode 684 remote_spinlock_unlock_busy( txt0_lock_xp , txt0_save_sr ); 685 686 // release lock on local process list 687 remote_spinlock_unlock( lock_xp ); 688 599 689 } // end cluster_processes_display() 600 690 -
trunk/kernel/kern/cluster.h
r440 r443 61 61 * Warning : the "owner" cluster, and the "reference" cluster can be different clusters. 62 62 * 63 * The process manager of a cluster K maintains three structures: 64 * 1) The pref_tbl[] is an array indexed by lpid. There is one entry per owned process. 63 * The process manager of a cluster K maintains three sets of process descriptors: 64 * 65 * 1) pref_tbl[] is an array indexed by lpid. There is one entry per owned process. 65 66 * Each entry contains an extended pointer on the reference process descriptor. 66 67 * 67 * 2) The local_root is the root of the local list of process descriptors in cluster K.68 * 2) The local_root is the root of the local list of all process descriptors in cluster K. 68 69 * A process descriptor P is present in K, as soon as P has a thread in cluster K. 69 70 * … … 187 188 /****************************************************************************************** 188 189 * This function returns an extended pointer on the process descriptor in owner cluster 189 * from the process PID. This PID can be be different from the calling process PID.190 * from the process <pid>. This PID can be be different from the calling process PID. 190 191 * It can be called by any thread running in any cluster, 191 192 ****************************************************************************************** … … 197 198 /****************************************************************************************** 198 199 * This function returns an extended pointer on the reference process descriptor 199 * from the process PID. This PID can be be different from the calling process PID.200 * from the process <pid>. This PID can be be different from the calling process PID. 200 201 * It can be called by any thread running in any cluster, 201 202 ****************************************************************************************** … … 204 205 *****************************************************************************************/ 205 206 xptr_t cluster_get_reference_process_from_pid( pid_t pid ); 207 208 /****************************************************************************************** 209 * This function returns an extended pointer on the process descriptor copy for the 210 * process identified by <pid> in cluster defined by <cxy> argument. 211 * This PID can be be different from the calling process PID. 212 * It can be called by any thread running in any cluster, 213 ****************************************************************************************** 214 * @ cxy : target cluster identifier. 215 * @ pid : process identifier. 216 * @ return extended pointer on reference process if found / XPTR_NULL if not found. 217 *****************************************************************************************/ 218 xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy, 219 pid_t pid ); 206 220 207 221 /****************************************************************************************** -
trunk/kernel/kern/core.c
r438 r443 49 49 core->usage = 0; 50 50 core->spurious_irqs = 0; 51 core->thread_idle = NULL;52 51 core->fpu_owner = NULL; 53 52 core->rand_last = hal_time_stamp() & 0xFFF; … … 90 89 void core_compute_stats( core_t * core ) 91 90 { 92 thread_t * idle = core-> thread_idle;91 thread_t * idle = core->scheduler.idle; 93 92 uint32_t ticks = core->ticks_nr; 94 93 … … 115 114 void core_reset_stats( core_t * core ) 116 115 { 117 core->ticks_nr = 0; 118 core->usage = 0; 119 core->thread_idle->ticks_nr = 0; 116 thread_t * idle = core->scheduler.idle; 117 118 core->ticks_nr = 0; 119 core->usage = 0; 120 idle->ticks_nr = 0; 121 120 122 hal_fence(); 121 123 } -
trunk/kernel/kern/core.h
r409 r443 57 57 uint32_t usage; /*! cumulated busy_percent (idle / total) */ 58 58 uint32_t spurious_irqs; /*! for instrumentation... */ 59 struct thread_s * thread_idle; /*! pointer on idle thread descriptor */60 59 struct thread_s * fpu_owner; /*! pointer on current FPU owner thread */ 61 60 uint32_t rand_last; /*! last computed random value */ -
trunk/kernel/kern/do_syscall.c
r438 r443 102 102 sys_trace, // 47 103 103 sys_fg, // 48 104 sys_undefined, // 49 104 105 }; 105 106 … … 136 137 else if( index == SYS_CLOSEDIR ) return "CLOSEDIR"; // 25 137 138 else if( index == SYS_GETCWD ) return "GETCWD"; // 26 139 else if( index == SYS_ISATTY ) return "ISATTY"; // 27 138 140 else if( index == SYS_ALARM ) return "ALARM"; // 28 139 141 else if( index == SYS_RMDIR ) return "RMDIR"; // 29 -
trunk/kernel/kern/kernel_init.c
r440 r443 59 59 #include <mapper.h> 60 60 61 #define KERNEL_INIT_SYNCHRO 0xA5A5B5B562 63 61 /////////////////////////////////////////////////////////////////////////////////////////// 64 62 // All the following global variables are replicated in all clusters. … … 912 910 913 911 #if( DEBUG_KERNEL_INIT & 1 ) 912 if( (core_lid == 0) & (local_cxy == 0) ) 914 913 chdev_dir_display(); 915 914 #endif … … 1179 1178 printk("\n[DBG] %s : exit barrier 8 : process init created / cycle %d\n", 1180 1179 __FUNCTION__ , (uint32_t)hal_get_cycles() ); 1180 #endif 1181 1182 #if (DEBUG_KERNEL_INIT & 1) 1183 if( (core_lid == 0) & (local_cxy == 0) ) 1184 sched_display( 0 ); 1181 1185 #endif 1182 1186 -
trunk/kernel/kern/printk.c
r437 r443 350 350 { 351 351 va_list args; 352 uint32_tsave_sr;352 reg_t save_sr; 353 353 354 354 // get pointers on TXT0 chdev -
trunk/kernel/kern/process.c
r441 r443 135 135 process->pid = pid; 136 136 process->ref_xp = XPTR( local_cxy , process ); 137 process->owner_xp = XPTR( local_cxy , process ); 137 138 process->parent_xp = parent_xp; 138 139 process->term_state = 0; … … 320 321 local_process->parent_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->parent_xp ) ); 321 322 local_process->ref_xp = reference_process_xp; 323 local_process->owner_xp = reference_process_xp; 322 324 local_process->term_state = 0; 323 325 … … 409 411 cluster_process_copies_unlink( process ); 410 412 411 // remove process from children_list if process is inowner cluster413 // remove process from children_list if process owner cluster 412 414 if( CXY_FROM_PID( pid ) == local_cxy ) 413 415 { … … 426 428 } 427 429 428 // release the process PID to cluster manager if owner cluster430 // release the process PID to cluster manager if process owner cluster 429 431 if( CXY_FROM_PID( pid ) == local_cxy ) cluster_pid_release( pid ); 430 432 … … 800 802 // allocate memory for local process descriptor 801 803 process_ptr = process_alloc(); 804 802 805 if( process_ptr == NULL ) return NULL; 803 806 804 807 // initialize local process descriptor copy 805 808 error = process_copy_init( process_ptr , ref_xp ); 809 806 810 if( error ) return NULL; 807 811 } … … 1021 1025 } 1022 1026 1023 1024 1027 // release lock protecting th_tbl 1025 1028 hal_fence(); … … 1030 1033 } // end process_register_thread() 1031 1034 1032 /////////////////////////////////////////////// 1033 void process_remove_thread( thread_t * thread ) 1034 { 1035 ///////////////////////////////////////////////// 1036 bool_t process_remove_thread( thread_t * thread ) 1037 { 1038 uint32_t count; // number of threads in local process descriptor 1039 1035 1040 assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" ); 1036 1041 … … 1043 1048 spinlock_lock( &process->th_lock ); 1044 1049 1045 assert( (process->th_nr) , __FUNCTION__ , "process th_nr cannot be 0\n" ); 1050 count = process->th_nr; 1051 1052 assert( (count > 0) , __FUNCTION__ , "process th_nr cannot be 0\n" ); 1046 1053 1047 1054 // remove thread from th_tbl[] … … 1049 1056 process->th_nr--; 1050 1057 1058 // release lock protecting th_tbl 1051 1059 hal_fence(); 1052 1053 // release lock protecting th_tbl1054 1060 spinlock_unlock( &process->th_lock ); 1061 1062 return (count == 1); 1055 1063 1056 1064 } // process_remove_thread() … … 1401 1409 process->pid = 0; 1402 1410 process->ref_xp = XPTR( local_cxy , process ); 1411 process->owner_xp = XPTR( local_cxy , process ); 1403 1412 process->parent_xp = XPTR_NULL; 1404 1413 process->term_state = 0; … … 1531 1540 process_t * process_ptr; 1532 1541 cxy_t process_cxy; 1542 1533 1543 xptr_t parent_xp; // extended pointer on parent process 1534 1544 process_t * parent_ptr; 1535 1545 cxy_t parent_cxy; 1536 1546 1547 xptr_t owner_xp; // extended pointer on owner process 1548 process_t * owner_ptr; 1549 cxy_t owner_cxy; 1550 1537 1551 pid_t pid; 1538 1552 pid_t ppid; 1539 1553 uint32_t state; 1540 xptr_t ref_xp;1541 1554 uint32_t th_nr; 1542 1555 1543 xptr_t txt_file_xp; // extended pointer on TXT_RX pseudo file1544 xptr_t chdev_xp;// extended pointer on TXT_RX chdev1545 chdev_t * chdev_ptr;1546 cxy_t chdev_cxy;1547 xptr_t owner_xp;// extended pointer on TXT owner process1556 xptr_t txt_file_xp; // extended pointer on TXT_RX file descriptor 1557 xptr_t txt_chdev_xp; // extended pointer on TXT_RX chdev 1558 chdev_t * txt_chdev_ptr; 1559 cxy_t txt_chdev_cxy; 1560 xptr_t txt_owner_xp; // extended pointer on TXT owner process 1548 1561 1549 1562 xptr_t elf_file_xp; // extended pointer on .elf file … … 1558 1571 process_ptr = GET_PTR( process_xp ); 1559 1572 process_cxy = GET_CXY( process_xp ); 1560 1561 // check reference process1562 ref_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->ref_xp ) );1563 assert( (process_xp == ref_xp) , __FUNCTION__ , "process is not the reference\n");1564 1573 1565 1574 // get PID and state … … 1576 1585 th_nr = hal_remote_lw( XPTR( process_cxy , &process_ptr->th_nr ) ); 1577 1586 1578 // get TXT name and process owner 1579 txt_file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1587 // get pointers on owner process descriptor 1588 owner_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->owner_xp ) ); 1589 owner_cxy = GET_CXY( owner_xp ); 1590 owner_ptr = GET_PTR( owner_xp ); 1591 1592 // get extended pointer on TXT_RX file descriptor attached to process 1593 txt_file_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->fd_array.array[0] ) ); 1580 1594 1581 1595 assert( (txt_file_xp != XPTR_NULL) , __FUNCTION__ , 1582 1596 "process must be attached to one TXT terminal\n" ); 1583 1597 1584 chdev_xp = chdev_from_file( txt_file_xp ); 1585 chdev_cxy = GET_CXY( chdev_xp ); 1586 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 1598 // get TXT_RX chdev pointers 1599 txt_chdev_xp = chdev_from_file( txt_file_xp ); 1600 txt_chdev_cxy = GET_CXY( txt_chdev_xp ); 1601 txt_chdev_ptr = GET_PTR( txt_chdev_xp ); 1602 1603 // get TXT_RX name and ownership 1587 1604 hal_remote_strcpy( XPTR( local_cxy , txt_name ) , 1588 XPTR( chdev_cxy , chdev_ptr->name ) ); 1589 owner_xp = (xptr_t)hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) ); 1605 XPTR( txt_chdev_cxy , txt_chdev_ptr->name ) ); 1606 1607 txt_owner_xp = (xptr_t)hal_remote_lwd( XPTR( txt_chdev_cxy, 1608 &txt_chdev_ptr->ext.txt.owner_xp ) ); 1590 1609 1591 1610 // get process .elf name 1592 1611 elf_file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->vfs_bin_xp ) ); 1593 1594 1612 elf_file_cxy = GET_CXY( elf_file_xp ); 1595 1613 elf_file_ptr = (vfs_file_t *)GET_PTR( elf_file_xp ); … … 1598 1616 1599 1617 // display process info 1600 if( owner_xp == process_xp )1601 { 1602 printk("PID %X | PPID %X | STS %X | %s (FG) | %X | %d | %s\n",1618 if( txt_owner_xp == process_xp ) 1619 { 1620 nolock_printk("PID %X | PPID %X | STS %X | %s (FG) | %X | %d | %s\n", 1603 1621 pid, ppid, state, txt_name, process_ptr, th_nr, elf_name ); 1604 1622 } 1605 1623 else 1606 1624 { 1607 printk("PID %X | PPID %X | STS %X | %s (BG) | %X | %d | %s\n",1625 nolock_printk("PID %X | PPID %X | STS %X | %s (BG) | %X | %d | %s\n", 1608 1626 pid, ppid, state, txt_name, process_ptr, th_nr, elf_name ); 1609 1627 } … … 1988 2006 xptr_t current_xp; 1989 2007 xptr_t iter_xp; 1990 1991 // check terminal index 2008 cxy_t txt0_cxy; 2009 chdev_t * txt0_ptr; 2010 xptr_t txt0_xp; 2011 xptr_t txt0_lock_xp; 2012 reg_t txt0_save_sr; // save SR to take TXT0 lock in busy mode 2013 1992 2014 assert( (txt_id < LOCAL_CLUSTER->nb_txt_channels) , 1993 2015 __FUNCTION__ , "illegal TXT terminal index" ); 2016 2017 // get pointers on TXT0 chdev 2018 txt0_xp = chdev_dir.txt_tx[0]; 2019 txt0_cxy = GET_CXY( txt0_xp ); 2020 txt0_ptr = GET_PTR( txt0_xp ); 2021 2022 // get extended pointer on TXT0 lock 2023 txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 1994 2024 1995 2025 // get pointers on TXT_RX[txt_id] chdev … … 2002 2032 lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock ); 2003 2033 2034 // get lock on attached process list 2035 remote_spinlock_lock( lock_xp ); 2036 2037 // get TXT0 lock in busy waiting mode 2038 remote_spinlock_lock_busy( txt0_lock_xp , &txt0_save_sr ); 2039 2004 2040 // display header 2005 printk("\n***** processes attached to TXT_%d\n", txt_id ); 2006 2007 // get lock 2008 remote_spinlock_lock( lock_xp ); 2041 nolock_printk("\n***** processes attached to TXT_%d / cycle %d\n", 2042 txt_id , (uint32_t)hal_get_cycles() ); 2009 2043 2010 2044 // scan attached process list … … 2015 2049 } 2016 2050 2017 // release lock 2051 // release TXT0 lock in busy waiting mode 2052 remote_spinlock_unlock_busy( txt0_lock_xp , txt0_save_sr ); 2053 2054 // release lock on attached process list 2018 2055 remote_spinlock_unlock( lock_xp ); 2019 2056 -
trunk/kernel/kern/process.h
r441 r443 90 90 * The process descriptor is replicated in all clusters containing at least one thread 91 91 * of the PID process, with the following rules : 92 * 1) The <pid>, <ppid>, <ref_xp>, < vfs_root_xp>, <vfs_bin_xp> fields are defined93 * in all process descriptor copies.92 * 1) The <pid>, <ppid>, <ref_xp>, <owner_xp>, <vfs_root_xp>, <vfs_bin_xp> fields are 93 * defined in all process descriptor copies. 94 94 * 2) The <vfs_cwd_xp> and associated <cwd_lock>, that can be dynamically modified, 95 95 * are only defined in the reference process descriptor. … … 106 106 * are defined in all process descriptors copies. 107 107 * 7) The termination <flags> and <exit_status> are only defined in the reference cluster. 108 * The term 108 * The term_state format is defined in the shared_syscalls.h file. 109 109 ********************************************************************************************/ 110 110 … … 119 119 pid_t pid; /*! process identifier */ 120 120 xptr_t ref_xp; /*! extended pointer on reference process */ 121 xptr_t owner_xp; /*! extended pointer on owner process */ 121 122 xptr_t parent_xp; /*! extended pointer on parent process */ 122 123 … … 264 265 /********************************************************************************************* 265 266 * This debug function diplays on the kernel terminal TXT0 detailed informations on a 266 * reference processidentified by the <process_xp> argument.267 * process descriptor identified by the <process_xp> argument. 267 268 * It can be called by a thread running in any cluster. 268 ********************************************************************************************* 269 * @ process_xp : extended pointer on reference process. 269 * WARNING: this function uses the nolock_printk() function, and the TXT0 lock MUST be 270 * taken by the caller function. 271 ********************************************************************************************* 272 * @ process_xp : extended pointer on process descriptor. 270 273 ********************************************************************************************/ 271 274 void process_display( xptr_t process_xp ); … … 379 382 380 383 /********************************************************************************************* 381 * This function implements the "fork" system call, and is called by the sys_fork() function .382 * It allocates memory and initializes a new "child" process descriptor, and the383 * associated "child" thread descriptor in the local cluster. This function can involve384 * up to three different clusters :385 * - the child (local) cluster can be any cluster defined by the sys_fork function.384 * This function implements the "fork" system call, and is called by the sys_fork() function, 385 * likely throuch the RPC_PROCESS_MAKE_FORK. 386 * It allocates memory and initializes a new "child" process descriptor, and the associated 387 * "child" thread descriptor in local cluster. It involves up to three different clusters : 388 * - the child (local) cluster can be any cluster selected by the sys_fork function. 386 389 * - the parent cluster must be the reference cluster for the parent process. 387 390 * - the client cluster containing the thread requesting the fork can be any cluster. … … 483 486 * It checks that there is an available slot in the local th_tbl[] array, 484 487 * allocates a new LTID, and registers the new thread in the th_tbl[]. 485 * WARNING : the lock protecting the th_tbl[] must be taken by the caller.488 * It takes the lock protecting exclusive access to the th_tbl[]. 486 489 ********************************************************************************************* 487 490 * @ process : pointer on the local process descriptor. … … 496 499 /********************************************************************************************* 497 500 * This function removes a thread registration from the local process descriptor. 498 * WARNING : the lock protecting the th_tbl[] must be taken by the caller.501 * It takes the lock protecting exclusive access to the th_tbl[]. 499 502 ********************************************************************************************* 500 503 * @ thread : local pointer on thread to be removed. 501 ********************************************************************************************/ 502 void process_remove_thread( struct thread_s * thread ); 504 * @ return true if the removed thread was the last registered thread. 505 ********************************************************************************************/ 506 bool_t process_remove_thread( struct thread_s * thread ); 503 507 504 508 … … 551 555 * When the process dentified by the <owner_xp> argument has the exclusive ownership of 552 556 * the TXT_RX terminal, this function transfer this ownership to another attached process. 553 * The process descriptor must be in the process owner cluster. 554 * This function does nothing if the <pid> process is not the owner. 557 * The process descriptor must be the process owner. 558 * This function does nothing if the process identified by the <process_xp> is not 559 * the TXT owner. 555 560 * - If the current owner is not the KSH process, the new owner is the KSH process. 556 * - If the <pid> process is thethe KSH process, the new owner is another attached process.561 * - If the current owner is the KSH process, the new owner is another attached process. 557 562 * - If there is no other attached process, the TXT has no more defined owner. 558 563 ********************************************************************************************* -
trunk/kernel/kern/scheduler.c
r440 r443 34 34 #include <scheduler.h> 35 35 36 36 37 /////////////////////////////////////////////////////////////////////////////////////////// 37 38 // Extern global variables 38 39 /////////////////////////////////////////////////////////////////////////////////////////// 39 40 40 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c file 41 extern uint32_t switch_save_sr[]; // allocated in kernel_init.c file 41 uint32_t idle_thread_count; 42 uint32_t idle_thread_count_active; 43 44 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c file 45 extern uint32_t switch_save_sr[]; // allocated in kernel_init.c file 42 46 43 47 //////////////////////////////// … … 50 54 51 55 sched->current = CURRENT_THREAD; 52 sched->idle = NULL; // initialized in kernel_init()53 sched->u_last = NULL; // initialized in sched_register_thread()54 sched->k_last = NULL; // initialized in sched_register_thread()56 sched->idle = NULL; // initialized in kernel_init() 57 sched->u_last = NULL; // initialized in sched_register_thread() 58 sched->k_last = NULL; // initialized in sched_register_thread() 55 59 56 60 // initialise threads lists … … 58 62 list_root_init( &sched->k_root ); 59 63 60 sched->req_ack_pending = false; // no pending request 64 sched->req_ack_pending = false; // no pending request 65 sched->trace = false; // context switches trace desactivated 61 66 62 67 } // end sched_init() … … 179 184 thread_t * thread; 180 185 process_t * process; 186 bool_t last_thread; 181 187 182 188 // get pointer on scheduler … … 237 243 238 244 // delete thread 239 thread_destroy( thread );245 last_thread = thread_destroy( thread ); 240 246 241 247 #if DEBUG_SCHED_HANDLE_SIGNALS 242 248 uint32_t cycle = (uint32_t)hal_get_cycles(); 243 249 if( DEBUG_SCHED_HANDLE_SIGNALS < cycle ) 244 printk("\n[DBG] %s : thread %x in proces %x (%x)deleted / cycle %d\n",245 __FUNCTION__ , thread , process->pid , process, cycle );250 printk("\n[DBG] %s : thread %x in proces %x on core[%x,%d] deleted / cycle %d\n", 251 __FUNCTION__ , thread->trdid , process->pid , local_cxy , thread->core->lid , cycle ); 246 252 #endif 247 253 // destroy process descriptor if no more threads 248 if( process->th_nr == 0)254 if( last_thread ) 249 255 { 250 256 // delete process … … 254 260 cycle = (uint32_t)hal_get_cycles(); 255 261 if( DEBUG_SCHED_HANDLE_SIGNALS < cycle ) 256 printk("\n[DBG] %s : process %x has beendeleted / cycle %d\n",257 __FUNCTION__ , process->pid , cycle );262 printk("\n[DBG] %s : process %x in cluster %x deleted / cycle %d\n", 263 __FUNCTION__ , process->pid , local_cxy , cycle ); 258 264 #endif 259 265 … … 277 283 278 284 #if (DEBUG_SCHED_YIELD & 0x1) 279 if( DEBUG_SCHED_YIELD < (uint32_t)hal_get_cycles())285 if( sched->trace ) 280 286 sched_display( core->lid ); 281 287 #endif … … 295 301 296 302 // check next thread kernel_stack overflow 297 assert( (next->signature == THREAD_SIGNATURE), 298 __FUNCTION__ , "kernel stack overflow for thread %x\n", next);303 assert( (next->signature == THREAD_SIGNATURE), __FUNCTION__ , 304 "kernel stack overflow for thread %x on core[%x,%d] \n", next, local_cxy, core->lid ); 299 305 300 306 // check next thread attached to same core as the calling thread 301 assert( (next->core == current->core), 302 __FUNCTION__ ,"next core %x != current core %x\n", next->core, current->core );307 assert( (next->core == current->core), __FUNCTION__ , 308 "next core %x != current core %x\n", next->core, current->core ); 303 309 304 310 // check next thread not blocked when type != IDLE … … 311 317 { 312 318 313 if( (local_cxy == 0X1) && (core->lid == 1) && ((uint32_t)current == 0xcc000) )314 printk("\n@@@@@ cc000 exit at cycle %d\n", (uint32_t)hal_get_cycles() );315 316 if( (local_cxy == 0X1) && (core->lid == 1) && ((uint32_t)next == 0xcc000) )317 printk("\n@@@@@ cc000 enter at cycle %d\n", (uint32_t)hal_get_cycles() );318 319 319 #if DEBUG_SCHED_YIELD 320 uint32_t cycle = (uint32_t)hal_get_cycles(); 321 if( DEBUG_SCHED_YIELD < cycle ) 320 if( sched->trace ) 322 321 printk("\n[DBG] %s : core[%x,%d] / cause = %s\n" 323 322 " thread %x (%s) (%x,%x) => thread %x (%s) (%x,%x) / cycle %d\n", 324 323 __FUNCTION__, local_cxy, core->lid, cause, 325 current, thread_type_str(current->type), current->process->pid, current->trdid, 326 next , thread_type_str(next->type) , next->process->pid , next->trdid , cycle);324 current, thread_type_str(current->type), current->process->pid, current->trdid,next , 325 thread_type_str(next->type) , next->process->pid , next->trdid , (uint32_t)hal_get_cycles() ); 327 326 #endif 328 327 … … 345 344 { 346 345 347 #if (DEBUG_SCHED_YIELD & 1) 348 uint32_t cycle = (uint32_t)hal_get_cycles(); 349 if( DEBUG_SCHED_YIELD < cycle ) 346 #if DEBUG_SCHED_YIELD 347 if( sched->trace ) 350 348 printk("\n[DBG] %s : core[%x,%d] / cause = %s\n" 351 349 " thread %x (%s) (%x,%x) continue / cycle %d\n", 352 __FUNCTION__, local_cxy, core->lid, cause, 353 current , thread_type_str(current->type), current->process->pid, current->trdid, cycle);350 __FUNCTION__, local_cxy, core->lid, cause, current, thread_type_str(current->type), 351 current->process->pid, current->trdid, (uint32_t)hal_get_cycles() ); 354 352 #endif 355 353 … … 389 387 390 388 nolock_printk("\n***** threads on core[%x,%d] / current %x / cycle %d\n", 391 389 local_cxy , core->lid, sched->current, (uint32_t)hal_get_cycles() ); 392 390 393 391 // display kernel threads -
trunk/kernel/kern/scheduler.h
r437 r443 50 50 struct thread_s * current; /*! pointer on current running thread */ 51 51 volatile bool_t req_ack_pending; /*! sequencialize ack requests when true */ 52 bool_t trace; /*! context switches trace activated if true */ 52 53 } 53 54 scheduler_t; -
trunk/kernel/kern/thread.c
r440 r443 142 142 cluster_t * local_cluster = LOCAL_CLUSTER; 143 143 144 #if DEBUG_THREAD_USER_INIT 145 uint32_t cycle = (uint32_t)hal_get_cycles(); 146 if( DEBUG_THREAD_USER_INIT < cycle ) 147 printk("\n[DBG] %s : thread %x enter to init thread %x in process %x / cycle %d\n", 148 __FUNCTION__, CURRENT_THREAD, thread, process->pid , cycle ); 149 #endif 150 144 151 // register new thread in process descriptor, and get a TRDID 145 152 error = process_register_thread( process, thread , &trdid ); … … 196 203 thread->signature = THREAD_SIGNATURE; 197 204 198 // FIXME call hal_thread_init() function to initialise the save_sr field 205 // FIXME define and call an architecture specific hal_thread_init() 206 // function to initialise the save_sr field 199 207 thread->save_sr = 0xFF13; 200 208 … … 204 212 // update DQDT 205 213 dqdt_update_threads( 1 ); 214 215 #if DEBUG_THREAD_USER_INIT 216 cycle = (uint32_t)hal_get_cycles(); 217 if( DEBUG_THREAD_USER_INIT < cycle ) 218 printk("\n[DBG] %s : thread %x exit after init of thread %x in process %x / cycle %d\n", 219 __FUNCTION__, CURRENT_THREAD, thread, process->pid , cycle ); 220 #endif 206 221 207 222 return 0; … … 227 242 uint32_t cycle = (uint32_t)hal_get_cycles(); 228 243 if( DEBUG_THREAD_USER_CREATE < cycle ) 229 printk("\n[DBG] %s : thread %x enter / process%x / cycle %d\n",230 __FUNCTION__, CURRENT_THREAD, pid , cycle );244 printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n", 245 __FUNCTION__, CURRENT_THREAD, pid , local_cxy , cycle ); 231 246 #endif 232 247 … … 240 255 return ENOMEM; 241 256 } 257 258 #if( DEBUG_THREAD_USER_CREATE & 1) 259 if( DEBUG_THREAD_USER_CREATE < cycle ) 260 printk("\n[DBG] %s : process descriptor = %x for process %x in cluster %x\n", 261 __FUNCTION__, process , pid , local_cxy ); 262 #endif 242 263 243 264 // select a target core in local cluster … … 256 277 core_lid = cluster_select_local_core(); 257 278 } 279 280 #if( DEBUG_THREAD_USER_CREATE & 1) 281 if( DEBUG_THREAD_USER_CREATE < cycle ) 282 printk("\n[DBG] %s : core[%x,%d] selected\n", 283 __FUNCTION__, local_cxy , core_lid ); 284 #endif 258 285 259 286 // allocate a stack from local VMM … … 282 309 return ENOMEM; 283 310 } 311 312 #if( DEBUG_THREAD_USER_CREATE & 1) 313 if( DEBUG_THREAD_USER_CREATE < cycle ) 314 printk("\n[DBG] %s : thread descriptor %x allocated\n", 315 __FUNCTION__, thread ); 316 #endif 284 317 285 318 // initialize thread descriptor … … 300 333 } 301 334 335 #if( DEBUG_THREAD_USER_CREATE & 1) 336 if( DEBUG_THREAD_USER_CREATE < cycle ) 337 printk("\n[DBG] %s : thread descriptor %x initialised / trdid = %x\n", 338 __FUNCTION__, thread , thread->trdid ); 339 #endif 340 302 341 // set DETACHED flag if required 303 342 if( attr->attributes & PT_ATTR_DETACH ) … … 327 366 cycle = (uint32_t)hal_get_cycles(); 328 367 if( DEBUG_THREAD_USER_CREATE < cycle ) 329 printk("\n[DBG] %s : thread %x exit / process %x / new_thread%x / core %d / cycle %d\n",330 __FUNCTION__, CURRENT_THREAD, pid, thread, core_lid, cycle );368 printk("\n[DBG] %s : thread %x exit / new_thread %x in process %x / core %d / cycle %d\n", 369 __FUNCTION__, CURRENT_THREAD, thread->trdid , pid , core_lid, cycle ); 331 370 #endif 332 371 … … 602 641 // has been released, using a cache of mmap requests. [AG] 603 642 /////////////////////////////////////////////////////////////////////////////////////// 604 voidthread_destroy( thread_t * thread )643 bool_t thread_destroy( thread_t * thread ) 605 644 { 606 645 reg_t save_sr; 646 bool_t last_thread; 607 647 608 648 process_t * process = thread->process; … … 616 656 #endif 617 657 618 assert( (thread->local_locks == 0) , __FUNCTION__ , "all local locks not released" ); 619 620 assert( (thread->remote_locks == 0) , __FUNCTION__ , "all remote locks not released" ); 658 assert( (thread->local_locks == 0) , __FUNCTION__ , 659 "local lock not released for thread %x in process %x", thread->trdid, process->pid ); 660 661 assert( (thread->remote_locks == 0) , __FUNCTION__ , 662 "remote lock not released for thread %x in process %x", thread->trdid, process->pid ); 621 663 622 664 // update intrumentation values … … 637 679 638 680 // remove thread from process th_tbl[] 639 process_remove_thread( thread );681 last_thread = process_remove_thread( thread ); 640 682 641 683 // update DQDT … … 654 696 __FUNCTION__, CURRENT_THREAD, thread, process->pid, cycle ); 655 697 #endif 698 699 return last_thread; 656 700 657 701 } // end thread_destroy() … … 1092 1136 hal_enable_irq( NULL ); 1093 1137 1094 if( CONFIG_THREAD_IDLE_MODE_SLEEP ) // force core to low-power mode 1138 // force core to low-power mode (optional) 1139 if( CONFIG_THREAD_IDLE_MODE_SLEEP ) 1095 1140 { 1096 1141 … … 1113 1158 1114 1159 } 1115 else // search a runable thread 1116 { 1117 sched_yield( "IDLE" ); 1118 } 1160 1161 // search a runable thread 1162 sched_yield( "IDLE" ); 1119 1163 } 1120 1164 } // end thread_idle() -
trunk/kernel/kern/thread.h
r440 r443 77 77 78 78 /*************************************************************************************** 79 * This defines the masks associated to the blocking causes.79 * This defines the thread blocking causes bit-vector. 80 80 **************************************************************************************/ 81 81 … … 278 278 279 279 /*************************************************************************************** 280 * This function is called by the kernel_init() function to initialize the IDLE thread .281 * It initializes an existing threaddescriptor from arguments values.280 * This function is called by the kernel_init() function to initialize the IDLE thread 281 * descriptor from arguments values. 282 282 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start. 283 283 *************************************************************************************** … … 296 296 297 297 /*************************************************************************************** 298 * This function releases the physical memory allocated for a thread in a given cluster. 299 * This include the thread descriptor itself, the associated CPU and FPU context, and 300 * the physical memory allocated for an user thread local stack. 298 * This function is called by the sched_handle_signals() function to releases 299 * the physical memory allocated for a thread in a given cluster, when this thread 300 * is marked for delete. This include the thread descriptor itself, the associated 301 * CPU and FPU context, and the physical memory allocated for an user thread local stack. 302 * The destroyed thread is removed from the local process th_tbl[] array, and returns 303 * true when the destroyed thread was the last thread registered in process. 301 304 *************************************************************************************** 302 305 * @ thread : pointer on the thread descriptor to release. 303 **************************************************************************************/ 304 void thread_destroy( thread_t * thread ); 306 * @ return true, if the thread was the last registerd thread in local process. 307 **************************************************************************************/ 308 bool_t thread_destroy( thread_t * thread ); 305 309 306 310 /*************************************************************************************** 307 311 * This function defines the code of the thread executed by all cores after kernel_init, 308 312 * or when no other thread is runnable for a given core. 309 * 310 * TODO: In the TSAR architecture, it enters an infinite loop, in wich it forces 311 * the core in sleep (low-power) mode. Any IRQ will force the core to exit this sleep 312 * mode, but no ISR is executed. 313 * TODO: We must analyse if we have the same behaviour for I86 architectures... 313 * It enter and infinite loop in wich: 314 * - it unmask the IRQs 315 * - it optionally calls the hal_core_sleep() function to reduce the power consumption 316 * (this behavior is controlled by the CONFIG_THREAD_IDLE_MODE_SLEEP flag). 317 * - it call the sched_yield() function to find another runnable thread. 318 * 319 * TODO: In the TSAR architecture the hal_core_sleep() function forces the core to 320 * low-power mode. Any IRQ will force the core to exit this low-power mode, but no ISR 321 * is executed. We must analyse if we have the same behaviour for I86 architectures... 314 322 **************************************************************************************/ 315 323 void thread_idle_func(); … … 357 365 /*************************************************************************************** 358 366 * This function is used by the four sys_thread_cancel(), sys_thread_exit(), 359 * sys_kill() and sys_exit() system calls to delete a given thread.367 * sys_kill() and sys_exit() system calls to mark for delete a given thread. 360 368 * It set the THREAD_BLOCKED_GLOBAL bit and set the the THREAD_FLAG_REQ_DELETE bit 361 369 * in the thread descriptor identified by the <thread_xp> argument, to ask the scheduler
Note: See TracChangeset
for help on using the changeset viewer.