Changeset 428 for trunk/kernel
- Timestamp:
- Jan 29, 2018, 6:08:07 PM (7 years ago)
- Location:
- trunk/kernel/kern
- Files:
-
- 6 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/chdev.c
r418 r428 276 276 } // end chdev_sequencial_server() 277 277 278 //////////////////////////////////////// 279 xptr_t chdev_from_file( xptr_t file_xp ) 280 { 281 cxy_t file_cxy; 282 vfs_file_t * file_ptr; 283 uint32_t inode_type; 284 vfs_inode_t * inode_ptr; 285 chdev_t * chdev_ptr; 286 287 // get cluster and local pointer on remote file descriptor 288 // associated inode and chdev are stored in same cluster as the file desc. 289 file_cxy = GET_CXY( file_xp ); 290 file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 291 292 // get inode type from file descriptor 293 inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) ); 294 inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 295 296 assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ , 297 "inode type %d is not INODE_TYPE_DEV", inode_type ); 298 299 // get chdev local pointer from inode extension 300 chdev_ptr = (chdev_t *)hal_remote_lpt( XPTR( file_cxy , &inode_ptr->extend ) ); 301 302 return XPTR( file_cxy , chdev_ptr ); 303 304 } // end chdev_from_file() 305 278 306 //////////////////////// 279 307 void chdev_dir_display() 280 308 { 281 cxy_t iob_cxy = GET_CXY( chdev_dir.iob ); 282 chdev_t * iob_ptr = (chdev_t *)GET_PTR( chdev_dir.iob ); 283 uint32_t iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) ); 284 285 cxy_t pic_cxy = GET_CXY( chdev_dir.pic ); 286 chdev_t * pic_ptr = (chdev_t *)GET_PTR( chdev_dir.pic ); 287 uint32_t pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) ); 288 289 cxy_t txt0_tx_cxy = GET_CXY( chdev_dir.txt_tx[0] ); 290 chdev_t * txt0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] ); 291 uint32_t txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) ); 292 293 cxy_t txt0_rx_cxy = GET_CXY( chdev_dir.txt_rx[0] ); 294 chdev_t * txt0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] ); 295 uint32_t txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) ); 296 297 cxy_t txt1_tx_cxy = GET_CXY( chdev_dir.txt_tx[1] ); 298 chdev_t * txt1_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] ); 299 uint32_t txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) ); 300 301 cxy_t txt1_rx_cxy = GET_CXY( chdev_dir.txt_rx[1] ); 302 chdev_t * txt1_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] ); 303 uint32_t txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) ); 304 305 cxy_t txt2_tx_cxy = GET_CXY( chdev_dir.txt_tx[2] ); 306 chdev_t * txt2_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] ); 307 uint32_t txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) ); 308 309 cxy_t txt2_rx_cxy = GET_CXY( chdev_dir.txt_rx[2] ); 310 chdev_t * txt2_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] ); 311 uint32_t txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) ); 312 313 cxy_t ioc_cxy = GET_CXY( chdev_dir.ioc[0] ); 314 chdev_t * ioc_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[0] ); 315 uint32_t ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) ); 316 317 cxy_t fbf_cxy = GET_CXY( chdev_dir.fbf[0] ); 318 chdev_t * fbf_ptr = (chdev_t *)GET_PTR( chdev_dir.fbf[0] ); 319 uint32_t fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) ); 320 321 cxy_t nic0_rx_cxy = GET_CXY( chdev_dir.nic_rx[0] ); 322 chdev_t * nic0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] ); 323 uint32_t nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) ); 324 325 cxy_t nic0_tx_cxy = GET_CXY( chdev_dir.nic_tx[0] ); 326 chdev_t * nic0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] ); 327 uint32_t nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) ); 328 329 printk("\n***** external chdev directory in cluster %x\n" 330 " - iob : cxy = %X / ptr = %X / base = %X\n" 331 " - pic : cxy = %X / ptr = %X / base = %X\n" 332 " - ioc : cxy = %X / ptr = %X / base = %X\n" 333 " - fbf : cxy = %X / ptr = %X / base = %X\n" 334 " - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n" 335 " - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n" 336 " - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n" 337 " - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n" 338 " - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n" 339 " - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n" 340 " - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n" 341 " - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n", 342 local_cxy, 343 iob_cxy , iob_ptr , iob_base , 344 pic_cxy , pic_ptr , pic_base , 345 ioc_cxy , ioc_ptr , ioc_base , 346 fbf_cxy , fbf_ptr , fbf_base , 347 txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base , 348 txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base , 349 txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base , 350 txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base , 351 txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base , 352 txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base , 353 nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base , 354 nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base ); 309 uint32_t i; 310 cxy_t cxy; 311 chdev_t * ptr; 312 uint32_t base; 313 reg_t save_sr; 314 315 // get pointers on TXT0 chdev 316 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 317 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 318 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 319 320 // get extended pointer on remote TXT0 chdev lock 321 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 322 323 // get TXT0 lock in busy waiting mode 324 remote_spinlock_lock_busy( lock_xp , &save_sr ); 325 326 // header 327 nolock_printk("\n***** external chdevs directory *****\n"); 328 329 // IOB 330 cxy = GET_CXY( chdev_dir.iob ); 331 ptr = GET_PTR( chdev_dir.iob ); 332 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 333 nolock_printk(" - iob : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base); 334 335 // PIC 336 cxy = GET_CXY( chdev_dir.pic ); 337 ptr = GET_PTR( chdev_dir.pic ); 338 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 339 nolock_printk(" - pic : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base); 340 341 // TXT 342 for( i = 0 ; i < LOCAL_CLUSTER->nb_txt_channels ; i++ ) 343 { 344 cxy = GET_CXY( chdev_dir.txt_rx[i] ); 345 ptr = GET_PTR( chdev_dir.txt_rx[i] ); 346 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 347 nolock_printk(" - txt_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 348 349 cxy = GET_CXY( chdev_dir.txt_tx[i] ); 350 ptr = GET_PTR( chdev_dir.txt_tx[i] ); 351 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 352 nolock_printk(" - txt_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 353 } 354 355 // IOC 356 for( i = 0 ; i < LOCAL_CLUSTER->nb_ioc_channels ; i++ ) 357 { 358 cxy = GET_CXY( chdev_dir.ioc[i] ); 359 ptr = GET_PTR( chdev_dir.ioc[i] ); 360 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 361 nolock_printk(" - ioc[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 362 } 363 364 // FBF 365 for( i = 0 ; i < LOCAL_CLUSTER->nb_fbf_channels ; i++ ) 366 { 367 cxy = GET_CXY( chdev_dir.fbf[i] ); 368 ptr = GET_PTR( chdev_dir.fbf[i] ); 369 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 370 nolock_printk(" - fbf[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 371 } 372 373 // NIC 374 for( i = 0 ; i < LOCAL_CLUSTER->nb_nic_channels ; i++ ) 375 { 376 cxy = GET_CXY( chdev_dir.nic_rx[i] ); 377 ptr = GET_PTR( chdev_dir.nic_rx[i] ); 378 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 379 nolock_printk(" - nic_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 380 381 cxy = GET_CXY( chdev_dir.nic_tx[i] ); 382 ptr = GET_PTR( chdev_dir.nic_tx[i] ); 383 base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) ); 384 nolock_printk(" - nic_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base); 385 } 386 387 // release lock 388 remote_spinlock_unlock_busy( lock_xp , save_sr ); 355 389 356 390 } // end chdev_dir_display() -
trunk/kernel/kern/chdev.h
r407 r428 28 28 #include <hal_types.h> 29 29 #include <xlist.h> 30 #include <metafs.h>31 30 #include <remote_spinlock.h> 32 31 #include <dev_iob.h> … … 35 34 #include <dev_pic.h> 36 35 #include <dev_fbf.h> 36 #include <dev_txt.h> 37 37 38 38 /****************************************************************************************** … … 115 115 * One kernel thread, in charge of handling the commands registered in the waiting queue 116 116 * of client threads is associated to each chdev descriptor (not for ICU, PIC, IOB). 117 * For each device type ***, the specific extension s aredefined in the "dev_***.h" file.117 * For each device type ***, the specific extension is defined in the "dev_***.h" file. 118 118 *****************************************************************************************/ 119 119 … … 136 136 uint32_t irq_id; /*! associated IRQ index in local ICU */ 137 137 138 metafs_t node; /*! Metafs node associated with this device */139 140 138 remote_spinlock_t wait_lock; /*! lock protecting exclusive access to queue */ 141 139 xlist_entry_t wait_root; /*! root of waiting threads queue */ … … 148 146 pic_extend_t pic; /*! PIC specific extension */ 149 147 fbf_extend_t fbf; /*! FBF specific extension */ 148 txt_extend_t txt; /*! TXT specific extension */ 150 149 } 151 150 ext; … … 239 238 240 239 /****************************************************************************************** 240 * This function returns an extended pointer on the chdev associated to a pseudo file 241 * descriptor (type INODE_TYPE_DEV) identified by the <file_xp> argument. 242 * It can be called by a thread running in any cluster. 243 * It enters kernel panic if the inode has not the expected type. 244 ****************************************************************************************** 245 * @ file_xp : extended pointer on the pseudo file descriptor. 246 * @ return an extended pointer on chdev. 247 *****************************************************************************************/ 248 xptr_t chdev_from_file( xptr_t file_xp ); 249 250 /****************************************************************************************** 241 251 * This function displays the local copy of the external chdevs directory. 242 252 * (global variable replicated in all clusters) … … 244 254 void chdev_dir_display(); 245 255 246 247 248 256 #endif /* _CHDEV_H_ */ -
trunk/kernel/kern/cluster.c
r416 r428 55 55 error_t cluster_init( struct boot_info_s * info ) 56 56 { 57 error_t error; 58 lpid_t lpid; // local process_index 59 lid_t lid; // local core index 57 error_t error; 58 lpid_t lpid; // local process_index 59 lid_t lid; // local core index 60 uint32_t i; // index in loop on external peripherals 61 boot_device_t * dev; // pointer on external peripheral 62 uint32_t func; // external peripheral functionnal type 60 63 61 64 cluster_t * cluster = LOCAL_CLUSTER; … … 69 72 cluster->io_cxy = info->io_cxy; 70 73 74 // initialize external peripherals channels 75 for( i = 0 ; i < info->ext_dev_nr ; i++ ) 76 { 77 dev = &info->ext_dev[i]; 78 func = FUNC_FROM_TYPE( dev->type ); 79 if( func == DEV_FUNC_TXT ) cluster->nb_txt_channels = dev->channels; 80 if( func == DEV_FUNC_NIC ) cluster->nb_nic_channels = dev->channels; 81 if( func == DEV_FUNC_IOC ) cluster->nb_ioc_channels = dev->channels; 82 if( func == DEV_FUNC_FBF ) cluster->nb_fbf_channels = dev->channels; 83 } 84 71 85 // initialize cluster local parameters 72 86 cluster->cores_nr = info->cores_nr; … … 199 213 200 214 //////////////////////////////////////////////////////////////////////////////////// 201 // Process managementrelated functions215 // Process related functions 202 216 //////////////////////////////////////////////////////////////////////////////////// 203 217 … … 336 350 remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , & irq_state ); 337 351 338 xlist_add_ first( XPTR( local_cxy , &pm->local_root ),339 352 xlist_add_last( XPTR( local_cxy , &pm->local_root ), 353 XPTR( local_cxy , &process->local_list ) ); 340 354 pm->local_nr++; 341 355 … … 417 431 } 418 432 419 //////////////////////////////////////////////////////////////////////////////////////// 420 // TODO Il me semble que la seule chose que fait ce kernel thread à chaque réveil 421 // est de mettre à jour la DQDT, et de se rendormir... A-t-on besoin d'un thread ? [AG] 422 ////////////////////////////////////////////////////////////////////////////////////////// 423 424 #if 0 425 void * cluster_manager_thread( void * arg ) 426 { 427 register struct dqdt_cluster_s * root; 428 register struct cluster_s * root_home; 429 430 register uint32_t tm_start; 431 register uint32_t tm_end; 432 register uint32_t cpu_id; 433 struct cluster_s * cluster; 434 struct thread_s * this; 435 struct event_s event; 436 struct alarm_info_s info; 437 register uint32_t cntr; 438 register bool_t isRootMgr; 439 register uint32_t period; 440 441 cpu_enable_all_irq( NULL ); 442 443 cluster = arg; 444 this = CURRENT_THREAD; 445 cpu_id = cpu_get_id(); 446 root = dqdt_root; 447 root_home = dqdt_root->home; 448 isRootMgr = (cluster == root_home) ? true : false; 449 cntr = 0; 450 period = (isRootMgr) ? 451 CONFIG_DQDT_ROOTMGR_PERIOD * MSEC_PER_TICK : 452 CONFIG_DQDT_MGR_PERIOD * MSEC_PER_TICK; 453 454 event_set_senderId(&event, this); 455 event_set_priority(&event, E_CHR); 456 event_set_handler(&event, &manager_alarm_event_handler); 457 458 info.event = &event; 459 thread_preempt_disable(CURRENT_THREAD); 460 461 // infinite loop 462 while(1) 463 { 464 tm_start = cpu_time_stamp(); 465 dqdt_update(); 466 tm_end = cpu_time_stamp(); 467 468 if(isRootMgr) 469 { 470 if((cntr % 10) == 0) 471 { 472 printk(INFO, "INFO: cpu %d, DQDT update ended [ %u - %u ]\n", 473 cpu_id, 474 tm_end, 475 tm_end - tm_start); 476 477 dqdt_print_summary(root); 478 } 479 } 480 481 alarm_wait( &info , period ); 482 sched_sleep(this); 483 cntr ++; 484 } 485 486 return NULL; 487 } // end cluster_manager_thread() 488 489 ////////////////////////////////////////// 490 EVENT_HANDLER(manager_alarm_event_handler) 491 { 492 struct thread_s *manager; 493 494 manager = event_get_senderId(event); 495 496 thread_preempt_disable(CURRENT_THREAD); 497 498 //printk(INFO, "%s: cpu %d [%u]\n", __FUNCTION__, cpu_get_id(), cpu_time_stamp()); 499 500 sched_wakeup(manager); 501 502 thread_preempt_enable(CURRENT_THREAD); 503 504 return 0; 505 } 506 507 /////////////////////////////////////////////// 508 EVENT_HANDLER(cluster_key_create_event_handler) 509 { 510 struct cluster_s *cluster; 511 struct thread_s *sender; 512 ckey_t *ckey; 513 uint32_t key; 514 515 sender = event_get_senderId(event); 516 ckey = event_get_argument(event); 517 cluster = current_cluster; 518 key = cluster->next_key; 519 520 while((key < CLUSTER_TOTAL_KEYS_NR) && (cluster->keys_tbl[key] != NULL)) 521 key ++; 522 523 if(key < CLUSTER_TOTAL_KEYS_NR) 524 { 525 ckey->val = key; 526 cluster->keys_tbl[key] = (void *) 0x1; // Reserved 527 cluster->next_key = key; 528 event_set_error(event, 0); 529 } 530 else 531 event_set_error(event, ENOSPC); 532 533 sched_wakeup(sender); 534 return 0; 535 } 536 537 /////////////////////////////////////////////// 538 EVENT_HANDLER(cluster_key_delete_event_handler) 539 { 540 struct cluster_s *cluster; 541 struct thread_s *sender; 542 ckey_t *ckey; 543 uint32_t key; 544 545 sender = event_get_senderId(event); 546 ckey = event_get_argument(event); 547 cluster = current_cluster; 548 key = ckey->val; 549 550 if(key < cluster->next_key) 551 cluster->next_key = key; 552 553 cluster->keys_tbl[key] = NULL; 554 event_set_error(event, 0); 555 556 sched_wakeup(sender); 557 return 0; 558 } 559 560 #define _CKEY_CREATE 0x0 561 #define _CKEY_DELETE 0x1 562 563 error_t cluster_do_key_op(ckey_t *key, uint32_t op) 564 { 565 struct event_s event; 566 struct thread_s *this; 567 struct cluster_s *cluster; 568 struct cpu_s *cpu; 569 570 this = CURRENT_THREAD; 571 572 event_set_priority(&event, E_FUNC); 573 event_set_senderId(&event, this); 574 event_set_argument(&event, key); 575 576 if(op == _CKEY_CREATE) 577 event_set_handler(&event, cluster_key_create_event_handler); 578 else 579 event_set_handler(&event, cluster_key_delete_event_handler); 580 581 cluster = current_cluster; 582 cpu = cluster->bscluster->bscpu; 583 event_send(&event, &cpu->re_listner); 584 585 sched_sleep(this); 586 587 return event_get_error(&event); 588 } 589 590 error_t cluster_key_create(ckey_t *key) 591 { 592 return cluster_do_key_op(key, _CKEY_CREATE); 593 } 594 595 error_t cluster_key_delete(ckey_t *key) 596 { 597 return cluster_do_key_op(key, _CKEY_DELETE); 598 } 599 600 void* cluster_getspecific(ckey_t *key) 601 { 602 struct cluster_s *cluster; 603 604 cluster = current_cluster; 605 return cluster->keys_tbl[key->val]; 606 } 607 608 void cluster_setspecific(ckey_t *key, void *val) 609 { 610 struct cluster_s *cluster; 611 612 cluster = current_cluster; 613 cluster->keys_tbl[key->val] = val; 614 } 615 #endif 433 /////////////////////////////////////////// 434 void cluster_processes_display( cxy_t cxy ) 435 { 436 xptr_t root_xp; 437 xptr_t iter_xp; 438 xptr_t process_xp; 439 440 // get extended pointer on root of process in cluster cxy 441 root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root ); 442 443 // skip one line 444 printk("\n"); 445 446 // loop on all reference processes in cluster cxy 447 XLIST_FOREACH( root_xp , iter_xp ) 448 { 449 process_xp = XLIST_ELEMENT( iter_xp , process_t , local_list ); 450 process_display( process_xp ); 451 } 452 } // end cluster_processes_display() 453 454 -
trunk/kernel/kern/cluster.h
r416 r428 96 96 typedef struct cluster_s 97 97 { 98 spinlock_t kcm_lock; /*! local, protect creation of KCM allocators*/98 spinlock_t kcm_lock; /*! local, protect creation of KCM allocators */ 99 99 100 100 // global parameters 101 uint32_t paddr_width; /*! numer of bits in physical address */ 102 uint32_t x_width; /*! number of bits to code x_size (can be 0) */ 103 uint32_t y_width; /*! number of bits to code y_size (can be 0) */ 104 uint32_t x_size; /*! number of clusters in a row (can be 1) */ 105 uint32_t y_size; /*! number of clusters in a column (can be 1) */ 106 cxy_t io_cxy; /*! io cluster identifier */ 107 uint32_t dqdt_root_level; /*! index of root node in dqdt_tbl[] */ 101 uint32_t paddr_width; /*! numer of bits in physical address */ 102 uint32_t x_width; /*! number of bits to code x_size (can be 0) */ 103 uint32_t y_width; /*! number of bits to code y_size (can be 0) */ 104 uint32_t x_size; /*! number of clusters in a row (can be 1) */ 105 uint32_t y_size; /*! number of clusters in a column (can be 1) */ 106 cxy_t io_cxy; /*! io cluster identifier */ 107 uint32_t dqdt_root_level; /*! index of root node in dqdt_tbl[] */ 108 uint32_t nb_txt_channels; /*! number of TXT channels */ 109 uint32_t nb_nic_channels; /*! number of NIC channels */ 110 uint32_t nb_ioc_channels; /*! number of IOC channels */ 111 uint32_t nb_fbf_channels; /*! number of FBF channels */ 108 112 109 113 // local parameters 110 uint32_t cores_nr; /*! actual number of cores in cluster*/111 uint32_t ram_size; /*! physical memory size*/112 uint32_t ram_base; /*! physical memory base (local address)*/114 uint32_t cores_nr; /*! actual number of cores in cluster */ 115 uint32_t ram_size; /*! physical memory size */ 116 uint32_t ram_base; /*! physical memory base (local address) */ 113 117 114 118 core_t core_tbl[CONFIG_MAX_LOCAL_CORES]; /*! embedded cores */ 115 119 116 list_entry_t dev_root; /*! root of list of devices in cluster*/120 list_entry_t dev_root; /*! root of list of devices in cluster */ 117 121 118 122 // memory allocators 119 ppm_t ppm; /*! embedded kernel page manager */ 120 khm_t khm; /*! embedded kernel heap manager */ 121 kcm_t kcm; /*! embedded kernel cache manager (for KCMs) */ 123 ppm_t ppm; /*! embedded kernel page manager */ 124 khm_t khm; /*! embedded kernel heap manager */ 125 kcm_t kcm; /*! embedded kernel cache manager (for KCMs) */ 126 122 127 kcm_t * kcm_tbl[KMEM_TYPES_NR]; /*! pointers on allocated KCMs */ 123 128 124 129 // RPC 125 remote_fifo_t rpc_fifo; /*! RPC fifo (one per cluster)*/126 uint32_t rpc_threads; /*! current number of RPC threads in cluster*/130 remote_fifo_t rpc_fifo; /*! RPC fifo (one per cluster) */ 131 uint32_t rpc_threads; /*! current number of RPC threads in cluster */ 127 132 128 133 // DQDT 129 int32_t pages_var; /*! pages number increment from last DQQT update*/130 int32_t threads_var; /*! threads number increment from last DQDT update*/134 int32_t pages_var; /*! pages number increment from last DQQT updt */ 135 int32_t threads_var; /*! threads number increment from last DQDT updt */ 131 136 132 137 dqdt_node_t dqdt_tbl[CONFIG_DQDT_LEVELS_NR]; /*! embedded DQDT nodes in cluster */ … … 196 201 * This function allocates a new PID in local cluster, that becomes the process owner. 197 202 * It registers the process descriptor extended pointer in the local processs manager 198 * pref_tbl[] array. This function is called by the process_make_fork() function, 203 * pref_tbl[] array. The process descriptor itself is not modified. 204 * This function is called by the process_make_fork() function, 199 205 * by the process_make_exec() function, and by the process_init_create() function. 200 206 ****************************************************************************************** … … 255 261 void cluster_process_copies_unlink( struct process_s * process ); 256 262 263 /********************************************************************************************* 264 * This function displays on the kernel terminal TXT0 all user processes registered 265 * in the cluster defined by the <cxy> argument. 266 * It can be called by a thread running in any cluster, because is use remote accesses 267 * to scan the xlist of registered processes. 268 ********************************************************************************************* 269 * @ cxy : cluster identifier. 270 ********************************************************************************************/ 271 void cluster_processes_display( cxy_t cxy ); 272 257 273 258 274 … … 262 278 263 279 /****************************************************************************************** 264 * This function increments the "cores_in_kernel" variable in cluster descriptor.265 *****************************************************************************************/266 void cluster_core_kernel_enter();267 268 /******************************************************************************************269 * This function decrements the "cores_in_kernel" variable in cluster descriptor.270 *****************************************************************************************/271 void cluster_core_kernel_exit();272 273 /******************************************************************************************274 280 * This function returns the core local index that has the lowest usage in local cluster. 275 281 *****************************************************************************************/ -
trunk/kernel/kern/do_syscall.c
r409 r428 36 36 static int sys_undefined() 37 37 { 38 panic("undefined system call");38 assert( false , __FUNCTION__ , "undefined system call" ); 39 39 return 0; 40 40 } … … 91 91 sys_exec, // 37 92 92 sys_stat, // 38 93 sys_ trace,// 3993 sys_wait, // 39 94 94 95 95 sys_get_config, // 40 96 96 sys_get_core, // 41 97 97 sys_get_cycle, // 42 98 sys_ get_sched,// 4399 sys_ panic,// 4498 sys_display, // 43 99 sys_undefined, // 44 100 100 sys_thread_sleep, // 45 101 101 sys_thread_wakeup, // 46 102 sys_trace, // 47 103 sys_fg, // 48 102 104 }; 103 105 … … 146 148 else if( index == SYS_EXEC ) return "EXEC"; // 37 147 149 else if( index == SYS_STAT ) return "STAT"; // 38 148 else if( index == SYS_ TRACE ) return "TRACE";// 39150 else if( index == SYS_WAIT ) return "WAIT"; // 39 149 151 150 152 else if( index == SYS_GET_CONFIG ) return "GET_CONFIG"; // 40 151 153 else if( index == SYS_GET_CORE ) return "GET_CORE"; // 41 152 154 else if( index == SYS_GET_CYCLE ) return "GET_CYCLE"; // 42 153 else if( index == SYS_GET_SCHED ) return "GET_SCHED"; // 43 154 else if( index == SYS_PANIC ) return "PANIC"; // 44 155 else if( index == SYS_SLEEP ) return "SLEEP"; // 45 156 else if( index == SYS_WAKEUP ) return "WAKEUP"; // 46 155 else if( index == SYS_DISPLAY ) return "DISPLAY"; // 43 156 else if( index == SYS_THREAD_SLEEP ) return "THREAD_SLEEP"; // 45 157 else if( index == SYS_THREAD_WAKEUP ) return "THREAD_WAKEUP"; // 46 158 else if( index == SYS_TRACE ) return "TRACE"; // 47 159 else if( index == SYS_FG ) return "FG"; // 48 157 160 158 161 else return "undefined"; -
trunk/kernel/kern/kernel_init.c
r409 r428 205 205 if (func == DEV_FUNC_TXT ) 206 206 { 207 assert( (channels > 0) , __FUNCTION__ , 208 "numner of TXT channels cannot be 0\n"); 209 210 // initializes TXT0 basic fields 207 assert( (channels > 0) , __FUNCTION__ , "number of TXT channels cannot be 0\n"); 208 209 // initializes TXT_TX[0] chdev 211 210 txt0_chdev.func = func; 212 211 txt0_chdev.impl = impl; … … 366 365 uint32_t directions; // number of directions (1 or 2) 367 366 uint32_t rx; // direction index (0 or 1) 368 uint32_t first_channel; // used in loop on channels for TXT369 367 chdev_t * chdev; // local pointer on one channel_device descriptor 370 368 uint32_t ext_chdev_gid; // global index of external chdev … … 388 386 if((func == DEV_FUNC_NIC) || (func == DEV_FUNC_TXT)) directions = 2; 389 387 else directions = 1; 390 391 // The TXT0 chdev has already been created392 if (func == DEV_FUNC_TXT) first_channel = 1;393 else first_channel = 0;394 388 395 389 // do nothing for ROM, that does not require a device descriptor. … … 412 406 413 407 // loops on channels 414 for( channel = first_channel; channel < channels ; channel++ )408 for( channel = 0 ; channel < channels ; channel++ ) 415 409 { 416 410 // loop on directions 417 411 for( rx = 0 ; rx < directions ; rx++ ) 418 412 { 413 // skip TXT_TX[0] chdev that has already been created & registered 414 if( (func == DEV_FUNC_TXT) && (channel == 0) && (rx == 0) ) continue; 415 419 416 // compute target cluster for chdev[func,channel,direction] 420 417 uint32_t offset = ext_chdev_gid % ( info->x_size * info->y_size ); … … 587 584 else if((func == DEV_FUNC_NIC) && (is_rx != 0)) ptr = &iopic_input.nic_rx[channel]; 588 585 else if( func == DEV_FUNC_IOB ) ptr = &iopic_input.iob; 589 else panic("illegal source device for IOPIC input" );586 else assert( false , __FUNCTION__ , "illegal source device for IOPIC input" ); 590 587 591 588 // set one entry in all "iopic_input" structures … … 796 793 if( error ) 797 794 { 798 panic("illegal core identifiers gid = %x / cxy = %x / lid = %d", 799 core_lid , core_cxy , core_lid ); 795 assert( false , __FUNCTION__ , 796 "illegal core identifiers gid = %x / cxy = %x / lid = %d", 797 core_lid , core_cxy , core_lid ); 800 798 } 801 799 … … 807 805 if( error ) 808 806 { 809 panic("cannot initialise cluster %x", local_cxy ); 807 assert( false , __FUNCTION__ , 808 "cannot initialise cluster %x", local_cxy ); 810 809 } 811 810 } … … 831 830 832 831 // all CP0s initialize the process_zero descriptor 833 if( core_lid == 0 ) process_zero_ init( &process_zero );832 if( core_lid == 0 ) process_zero_create( &process_zero ); 834 833 835 834 // CP0 in cluster 0 initializes the PIC chdev, … … 900 899 if( error ) 901 900 { 902 panic("core[%x][%d] cannot initialize idle thread",903 901 assert( false , __FUNCTION__ , 902 "core[%x][%d] cannot initialize idle thread", local_cxy , core_lid ); 904 903 } 905 904 … … 965 964 else 966 965 { 967 panic("root FS must be FATFS"); 966 assert( false , __FUNCTION__ , 967 "root FS must be FATFS" ); 968 968 } 969 969 … … 1113 1113 1114 1114 ///////////////////////////////////////////////////////////////////////////////// 1115 // STEP 8 : CP0 in I/O cluster creates the first user process (process_init) 1116 ///////////////////////////////////////////////////////////////////////////////// 1117 1118 if( (core_lid == 0) && (local_cxy == io_cxy) ) 1119 { 1120 process_init_create(); 1115 // STEP 8 : CP0 in cluster 0 creates the first user process (process_init) 1116 ///////////////////////////////////////////////////////////////////////////////// 1117 1118 if( (core_lid == 0) && (local_cxy == 0) ) 1119 { 1120 1121 #if CONFIG_KINIT_DEBUG 1122 vfs_display( vfs_root_inode_xp ); 1123 #endif 1124 1125 process_init_create(); 1121 1126 } 1122 1127 … … 1127 1132 ///////////////////////////////////////////////////////////////////////////////// 1128 1133 1129 #if CONFIG_KINIT_DEBUG1130 sched_display( core_lid );1131 #endif1132 1133 1134 if( (core_lid == 0) && (local_cxy == 0) ) 1134 1135 kinit_dmsg("\n[DBG] %s : exit barrier 8 : process init created / cycle %d\n", … … 1144 1145 1145 1146 #if CONFIG_KINIT_DEBUG 1146 1147 vfs_display( vfs_root_inode_xp );1148 1147 1149 1148 printk("\n\n***** memory fooprint for main kernel objects\n\n" -
trunk/kernel/kern/printk.c
r408 r428 383 383 } 384 384 385 /////////////////////////////////386 void _panic( char * format , ... )387 {388 va_list args;389 uint32_t save_sr;390 391 // get pointers on TXT0 chdev392 xptr_t txt0_xp = chdev_dir.txt_tx[0];393 cxy_t txt0_cxy = GET_CXY( txt0_xp );394 chdev_t * txt0_ptr = GET_PTR( txt0_xp );395 396 // get extended pointer on remote TXT0 chdev lock397 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );398 399 // get TXT0 lock in busy waiting mode400 remote_spinlock_lock_busy( lock_xp , &save_sr );401 402 // call kernel_printf on TXT0, in busy waiting mode403 va_start( args , format );404 kernel_printf( format , &args );405 va_end( args );406 407 // release lock408 remote_spinlock_unlock_busy( lock_xp , save_sr );409 410 hal_disable_irq( NULL );411 412 while (1)413 {414 hal_core_sleep();415 }416 }417 418 385 //////////////////////////////////// 419 386 void assert( bool_t condition, -
trunk/kernel/kern/printk.h
r415 r428 83 83 84 84 /********************************************************************************** 85 * This function displays a message and forces the calling core in sleeping mode.86 **********************************************************************************87 * @ format : formatted string88 *********************************************************************************/89 void _panic( char* format, ... );90 91 /**********************************************************************************92 85 * This function displays a formated message on kernel TXT0 terminal, 93 86 * and forces the calling core in sleeping mode if a Boolean condition is false. … … 126 119 void putl( uint64_t val ); 127 120 128 129 #define panic(fmt, ...) _panic("\n[PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__)130 121 131 122 /////////////////////////////////////////////////////////////////////////////////// -
trunk/kernel/kern/process.c
r416 r428 39 39 #include <core.h> 40 40 #include <thread.h> 41 #include <chdev.h> 41 42 #include <list.h> 42 43 #include <string.h> … … 56 57 ////////////////////////////////////////////////////////////////////////////////////////// 57 58 58 extern process_t process_zero; 59 extern process_t process_zero; // allocated in kernel_init.c 60 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 59 61 60 62 ////////////////////////////////////////////////////////////////////////////////////////// … … 84 86 } 85 87 86 /////////////////////////////////////////////87 void process_zero_init( process_t * process )88 {89 // initialize PID, PPID anf PREF90 process->pid = 0;91 process->ppid = 0;92 process->ref_xp = XPTR( local_cxy , process );93 94 // reset th_tbl[] array as empty95 uint32_t i;96 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )97 {98 process->th_tbl[i] = NULL;99 }100 process->th_nr = 0;101 spinlock_init( &process->th_lock );102 103 hal_fence();104 105 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n",106 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid );107 108 } // end process_zero_init()109 110 88 ///////////////////////////////////////////////// 111 89 void process_reference_init( process_t * process, 112 90 pid_t pid, 113 pid_t ppid,91 xptr_t parent_xp, 114 92 xptr_t model_xp ) 115 93 { 94 cxy_t parent_cxy; 95 process_t * parent_ptr; 116 96 cxy_t model_cxy; 117 97 process_t * model_ptr; 118 error_t error1;119 error_t error2;120 error_t error3;121 98 xptr_t stdin_xp; 122 99 xptr_t stdout_xp; … … 126 103 uint32_t stderr_id; 127 104 error_t error; 128 129 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / ppid = %x\n", 130 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid , ppid ); 105 uint32_t txt_id; 106 char rx_path[40]; 107 char tx_path[40]; 108 xptr_t chdev_xp; 109 chdev_t * chdev_ptr; 110 cxy_t chdev_cxy; 111 pid_t model_pid; 112 pid_t parent_pid; 131 113 132 114 // get model process cluster and local pointer … … 134 116 model_ptr = (process_t *)GET_PTR( model_xp ); 135 117 136 // initialize PID, PPID, and REF 137 process->pid = pid; 138 process->ppid = ppid; 139 process->ref_xp = XPTR( local_cxy , process ); 118 // get parent process cluster and local pointer 119 parent_cxy = GET_CXY( parent_xp ); 120 parent_ptr = (process_t *)GET_PTR( parent_xp ); 121 122 // get model_pid and parent_pid 123 parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 124 model_pid = hal_remote_lw( XPTR( model_cxy , &model_ptr->pid ) ); 125 126 process_dmsg("\n[DBG] %s : core[%x,%d] enters / pid = %x / ppid = %x / model_pid = %x\n", 127 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid , parent_pid , model_pid ); 128 129 // initialize PID, REF_XP, PARENT_XP, and STATE 130 process->pid = pid; 131 process->ref_xp = XPTR( local_cxy , process ); 132 process->parent_xp = parent_xp; 133 process->state = PROCESS_STATE_RUNNING; 140 134 141 135 // initialize vmm as empty … … 143 137 assert( (error == 0) , __FUNCTION__ , "cannot initialize VMM\n" ); 144 138 145 146 process_dmsg("\n[DBG] %s : core[%x,%d] / vmm empty for process %x\n", 139 process_dmsg("\n[DBG] %s : core[%x,%d] / vmm inialised as empty for process %x\n", 147 140 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 148 141 … … 150 143 process_fd_init( process ); 151 144 152 // create stdin / stdout / stderr pseudo-files 153 if( ppid == 0 ) // process_init 154 { 155 error1 = vfs_open( process, 156 CONFIG_INIT_STDIN, 145 // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal. 146 // - if INIT (pid == 1) => link to kernel TXT[0] 147 // - if KSH[i] (model_pid == 1) => allocate a free TXT[i] 148 // - if USER process => same terminal as model 149 150 if( (pid == 1) || (model_pid == 1)) // INIT or KSH process 151 { 152 if (pid == 1 ) txt_id = 0; // INIT 153 else txt_id = process_txt_alloc(); // KSH[i] 154 155 // attach process to TXT[txt_id] 156 process_txt_attach( process , txt_id ); 157 158 // build path to TXT_RX[i] and TXT_TX[i] chdevs 159 snprintf( rx_path , 40 , "/dev/external/txt%d_rx", txt_id ); 160 snprintf( tx_path , 40 , "/dev/external/txt%d_tx", txt_id ); 161 162 // create stdin pseudo file 163 error = vfs_open( process, 164 rx_path, 157 165 O_RDONLY, 158 166 0, // FIXME chmod … … 160 168 &stdin_id ); 161 169 162 error2 = vfs_open( process, 163 CONFIG_INIT_STDOUT, 170 assert( (error == 0) , __FUNCTION__ , "cannot open stdin pseudo file" ); 171 assert( (stdin_id == 0) , __FUNCTION__ , "stdin index must be 0" ); 172 173 // create stdout pseudo file 174 error = vfs_open( process, 175 tx_path, 164 176 O_WRONLY, 165 177 0, // FIXME chmod … … 167 179 &stdout_id ); 168 180 169 error3 = vfs_open( process, 170 CONFIG_INIT_STDERR, 181 assert( (error == 0) , __FUNCTION__ , "cannot open stdout pseudo file" ); 182 assert( (stdout_id == 1) , __FUNCTION__ , "stdout index must be 1" ); 183 184 // create stderr pseudo file 185 error = vfs_open( process, 186 tx_path, 171 187 O_WRONLY, 172 188 0, // FIXME chmod 173 189 &stderr_xp, 174 190 &stderr_id ); 175 } 176 else // any other process 177 { 178 error1 = vfs_open( process, 179 CONFIG_USER_STDIN, 180 O_RDONLY, 181 0, // FIXME chmod 182 &stdin_xp, 183 &stdin_id ); 184 185 error2 = vfs_open( process, 186 CONFIG_USER_STDOUT, 187 O_WRONLY, 188 0, // FIXME chmod 189 &stdout_xp, 190 &stdout_id ); 191 192 error3 = vfs_open( process, 193 CONFIG_USER_STDERR, 194 O_WRONLY, 195 0, // FIXME chmod 196 &stderr_xp, 197 &stderr_id ); 198 } 199 200 assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ , 201 "cannot open stdin/stdout/stderr pseudo files\n"); 202 203 assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ , 204 "bad indexes : stdin %d / stdout %d / stderr %d \n", stdin_id , stdout_id , stderr_id ); 191 192 assert( (error == 0) , __FUNCTION__ , "cannot open stderr pseudo file" ); 193 assert( (stderr_id == 2) , __FUNCTION__ , "stderr index must be 2" ); 194 195 } 196 else // normal user process 197 { 198 // get extended pointer on model process TXT chdev 199 chdev_xp = chdev_from_file( model_ptr->fd_array.array[0] ); 200 201 // get cluster and local pointer on chdev 202 chdev_cxy = GET_CXY( chdev_xp ); 203 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 204 205 // get TXT terminal index 206 txt_id = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) ); 207 208 // attach process to TXT[txt_id] 209 process_txt_attach( process , txt_id ); 210 211 // copy all open files from model process fd_array to this process 212 process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ), 213 XPTR( model_cxy , &model_ptr->fd_array ) ); 214 } 205 215 206 216 // initialize specific inodes root and cwd … … 214 224 remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) ); 215 225 216 // copy all open file descriptors (other than stdin / stdout / stderr) 217 process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ), 218 XPTR( model_cxy , &model_ptr->fd_array ) ); 219 220 process_dmsg("\n[DBG] %s : core[%x,%d] / fd array for process %x\n", 226 process_dmsg("\n[DBG] %s : core[%x,%d] / fd array initialised for process %x\n", 221 227 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 222 228 … … 224 230 xlist_root_init( XPTR( local_cxy , &process->children_root ) ); 225 231 process->children_nr = 0; 232 remote_spinlock_init( XPTR( local_cxy , &process->children_lock ) ); 226 233 227 234 // reset semaphore / mutex / barrier / condvar list roots … … 256 263 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 257 264 258 } // process_reference 265 } // process_reference_init() 259 266 260 267 ///////////////////////////////////////////////////// … … 268 275 process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp ); 269 276 270 // set the pid, ppid, ref_xp fields in local process 271 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) ); 272 local_process->ppid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) ); 273 local_process->ref_xp = reference_process_xp; 274 275 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x in cluster %x\n", 277 // initialize PID, REF_XP, PARENT_XP, and STATE 278 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) ); 279 local_process->parent_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->parent_xp ) ); 280 local_process->ref_xp = reference_process_xp; 281 local_process->state = PROCESS_STATE_RUNNING; 282 283 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n", 276 284 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid ); 277 285 … … 291 299 xlist_root_init( XPTR( local_cxy , &local_process->children_root ) ); 292 300 local_process->children_nr = 0; 293 294 // reset brothers list (not used in a process descriptor copy) 295 xlist_entry_init( XPTR( local_cxy , &local_process->brothers_list ) ); 301 remote_spinlock_init( XPTR( local_cxy , &local_process->children_lock ) ); 302 303 // reset children_list (not used in a process descriptor copy) 304 xlist_entry_init( XPTR( local_cxy , &local_process->children_list ) ); 296 305 297 306 // reset semaphores list root (not used in a process descriptor copy) … … 318 327 hal_fence(); 319 328 320 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x in cluster %x\n",329 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n", 321 330 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid ); 322 331 … … 328 337 void process_destroy( process_t * process ) 329 338 { 330 if( process->th_nr != 0 ) 331 { 332 panic("process %x in cluster %x has still active threads", 333 process->pid , local_cxy ); 334 } 339 xptr_t parent_xp; 340 process_t * parent_ptr; 341 cxy_t parent_cxy; 342 xptr_t parent_thread_xp; 343 xptr_t children_lock_xp; 344 xptr_t copies_lock_xp; 345 346 assert( (process->th_nr == 0) , __FUNCTION__ , 347 "process %x in cluster %x has still active threads", process->pid , local_cxy ); 348 349 process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x\n", 350 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid ); 335 351 336 352 // get local process manager pointer 337 353 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 338 354 339 // remove the process descriptorfrom local_list in cluster manager355 // remove process from local_list in cluster manager 340 356 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) ); 341 357 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); … … 343 359 344 360 // get extended pointer on copies_lock in owner cluster manager 345 cxy_t owner_cxy 346 lpid_t lpid 347 xptr_t copies_lock= XPTR( owner_cxy , &pmgr->copies_lock[lpid] );348 349 // remove the local process descriptorfrom copies_list350 remote_spinlock_lock( copies_lock );361 cxy_t owner_cxy = CXY_FROM_PID( process->pid ); 362 lpid_t lpid = LPID_FROM_PID( process->pid ); 363 copies_lock_xp = XPTR( owner_cxy , &pmgr->copies_lock[lpid] ); 364 365 // remove local process from copies_list 366 remote_spinlock_lock( copies_lock_xp ); 351 367 xlist_unlink( XPTR( local_cxy , &process->copies_list ) ); 352 remote_spinlock_unlock( copies_lock ); 368 remote_spinlock_unlock( copies_lock_xp ); 369 370 // for reference process only 371 if( XPTR( local_cxy , process ) == process->ref_xp ) 372 { 373 // remove reference process from txt_list 374 process_txt_detach( process ); 375 376 // get pointers on parent process 377 parent_xp = process->parent_xp; 378 parent_cxy = GET_CXY( parent_xp ); 379 parent_ptr = GET_PTR( parent_xp ); 380 381 // get extended pointer on children_lock in parent process 382 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock ); 383 384 // remove process from children_list 385 remote_spinlock_lock( children_lock_xp ); 386 xlist_unlink( XPTR( local_cxy , &process->children_list ) ); 387 remote_spinlock_unlock( children_lock_xp ); 388 389 // get extende pointer on parent main thread 390 parent_thread_xp = XPTR( parent_cxy , 391 hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[1] ))); 392 393 // unblock parent process main thread 394 thread_unblock( parent_thread_xp , THREAD_BLOCKED_WAIT ); 395 } 353 396 354 397 // release the process PID to cluster manager 355 398 cluster_pid_release( process->pid ); 356 399 357 hal_fence();358 359 // From this point, the process descriptor is unreachable360 361 400 // FIXME close all open files and update dirty [AG] 362 401 363 // Decrease refcount for bin file, root file and cwd file402 // decrease refcount for bin file, root file and cwd file 364 403 if( process->vfs_bin_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_bin_xp ); 365 404 if( process->vfs_root_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_root_xp ); … … 371 410 // release memory allocated to process descriptor 372 411 process_free( process ); 412 413 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n", 414 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid ); 373 415 374 416 } // end process_destroy() … … 401 443 rpc_desc_t rpc; // rpc descriptor allocated in stack 402 444 403 sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n",445 process_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n", 404 446 __FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy ); 405 447 … … 415 457 416 458 // check owner cluster 417 assert( (owner_cxy == local_cxy) , __FUNCTION__ , 418 "must be executed in the owner cluster\n" ); 459 assert( (owner_cxy == local_cxy) , __FUNCTION__ , "must be executed in owner cluster\n" ); 419 460 420 461 // get number of remote copies … … 425 466 assert( ((action_type == DELETE_ALL_THREADS ) || 426 467 (action_type == BLOCK_ALL_THREADS ) || 427 (action_type == UNBLOCK_ALL_THREADS )), 428 __FUNCTION__ , "illegal action type" ); 468 (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" ); 429 469 430 470 // initialise rpc descriptor … … 434 474 rpc.thread = client; 435 475 436 // get extended pointers on copies root , copies lock, and number of copies476 // get extended pointers on copies root and lock 437 477 root_xp = XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] ); 438 478 lock_xp = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ); … … 452 492 { 453 493 454 sigaction_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n",494 process_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n", 455 495 __FUNCTION__ , process_cxy ); 456 496 … … 477 517 } 478 518 479 sigaction_dmsg("\n[DBG] %s : make action in owner cluster %x\n",519 process_dmsg("\n[DBG] %s : make action in owner cluster %x\n", 480 520 __FUNCTION__ , local_cxy ); 481 521 482 522 483 523 // call directly the relevant function in local owner cluster 484 if (action_type == DELETE_ALL_THREADS ) process_delete ( process , client_xp );485 else if (action_type == BLOCK_ALL_THREADS ) process_block ( process , client_xp );486 else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock ( process );487 488 sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n",524 if (action_type == DELETE_ALL_THREADS ) process_delete_threads ( process , client_xp ); 525 else if (action_type == BLOCK_ALL_THREADS ) process_block_threads ( process , client_xp ); 526 else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock_threads( process ); 527 528 process_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n", 489 529 __FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy ); 490 530 491 531 } // end process_sigaction() 492 532 493 //////////////////////////////////////// 494 void process_block ( process_t * process,495 xptr_t client_xp )533 //////////////////////////////////////////////// 534 void process_block_threads( process_t * process, 535 xptr_t client_xp ) 496 536 { 497 537 thread_t * target; // pointer on target thread … … 524 564 525 565 // - if the target thread is the client thread, we do nothing, 526 // and simply decrement the responses counter.566 // and we simply decrement the responses counter. 527 567 // - if the calling thread and the target thread are on the same core, 528 // we block the target thread, we don't ask ask anything to thescheduler,529 // and simply decrement the responses counter.568 // we block the target thread, we don't need confirmation from scheduler, 569 // and we simply decrement the responses counter. 530 570 // - if the calling thread and the target thread are not running on the same 531 571 // core, we ask the target scheduler to acknowlege the blocking … … 559 599 } 560 600 561 // getlock protecting process th_tbl[]601 // release lock protecting process th_tbl[] 562 602 spinlock_unlock( &process->th_lock ); 563 603 … … 575 615 __FUNCTION__ , process->pid , local_cxy , count ); 576 616 577 } // end process_block ()578 579 /////////////////////////////////////////// 580 void process_unblock ( process_t * process )617 } // end process_block_threads() 618 619 /////////////////////////////////////////////////// 620 void process_unblock_threads( process_t * process ) 581 621 { 582 622 thread_t * target; // pointer on target thead … … 605 645 } 606 646 607 // getlock protecting process th_tbl[]647 // release lock protecting process th_tbl[] 608 648 spinlock_unlock( &process->th_lock ); 609 649 … … 611 651 __FUNCTION__ , process->pid , local_cxy , count ); 612 652 613 } // end process_unblock ()614 615 ///////////////////////////////////////// 616 void process_delete ( process_t * process,617 xptr_t client_xp )653 } // end process_unblock_threads() 654 655 ///////////////////////////////////////////////// 656 void process_delete_threads( process_t * process, 657 xptr_t client_xp ) 618 658 { 619 659 thread_t * target; // pointer on target thread 620 660 uint32_t ltid; // index in process th_tbl 621 661 uint32_t count; // request counter 622 thread_t * requester; // pointer on calling thread623 662 624 663 sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n", 625 664 __FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() ); 626 627 // get calling thread pointer628 requester = CURRENT_THREAD;629 665 630 666 // get lock protecting process th_tbl[] … … 649 685 } 650 686 651 // getlock protecting process th_tbl[]687 // release lock protecting process th_tbl[] 652 688 spinlock_unlock( &process->th_lock ); 653 689 … … 655 691 __FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() ); 656 692 657 } // end process_delete ()693 } // end process_delete_threads() 658 694 659 695 /////////////////////////////////////////////// … … 779 815 remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) ); 780 816 781 if ( !found ) return EMFILE;817 if ( !found ) return -1; 782 818 else return 0; 783 819 } … … 831 867 remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) ); 832 868 833 // loop on all entries other than 834 // the three first entries: stdin/stdout/stderr 835 for( fd = 3 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ ) 869 // loop on all fd_array entries 870 for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ ) 836 871 { 837 872 entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) ); … … 862 897 { 863 898 ltid_t ltid; 864 bool_t found ;899 bool_t found = false; 865 900 866 901 assert( (process != NULL) , __FUNCTION__ , "process argument is NULL" ); … … 868 903 assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" ); 869 904 905 // take lock protecting th_tbl 906 spinlock_lock( &process->th_lock ); 907 870 908 // search a free slot in th_tbl[] 871 // 0 is not a valid ltid value 872 found = false; 873 for( ltid = 1 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ ) 909 for( ltid = 0 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ ) 874 910 { 875 911 if( process->th_tbl[ltid] == NULL ) … … 890 926 } 891 927 928 929 // release lock protecting th_tbl 930 hal_fence(); 931 spinlock_unlock( &process->th_lock ); 932 892 933 return (found) ? 0 : ENOMEM; 893 934 … … 903 944 // get thread local index 904 945 ltid_t ltid = LTID_FROM_TRDID( thread->trdid ); 946 947 // take lock protecting th_tbl 948 spinlock_lock( &process->th_lock ); 949 950 assert( (process->th_nr) , __FUNCTION__ , "process th_nr cannot be 0\n" ); 905 951 906 952 // remove thread from th_tbl[] 907 953 process->th_tbl[ltid] = NULL; 908 954 process->th_nr--; 955 956 hal_fence(); 957 958 // release lock protecting th_tbl 959 spinlock_unlock( &process->th_lock ); 909 960 910 961 } // process_remove_thread() … … 921 972 pid_t parent_pid; // process identifier for parent process 922 973 xptr_t ref_xp; // extended pointer on reference process 974 xptr_t vfs_bin_xp; // extended pointer on .elf file 923 975 error_t error; 924 976 … … 927 979 process_t * parent_process_ptr = (process_t *)GET_PTR( parent_process_xp ); 928 980 929 // get parent process PID 930 parent_pid = hal_remote_lw( XPTR( parent_process_cxy , &parent_process_ptr->pid ) ); 931 981 // get parent process PID and extended pointer on .elf file 982 parent_pid = hal_remote_lw (XPTR( parent_process_cxy , &parent_process_ptr->pid)); 983 vfs_bin_xp = hal_remote_lwd(XPTR( parent_process_cxy , &parent_process_ptr->vfs_bin_xp)); 984 932 985 // check parent process is the reference 933 986 ref_xp = hal_remote_lwd( XPTR( parent_process_cxy , &parent_process_ptr->ref_xp ) ); … … 947 1000 } 948 1001 949 fork_dmsg("\n[DBG] %s : core[%x,%d] c hild process descriptor allocatedat cycle %d\n",950 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );1002 fork_dmsg("\n[DBG] %s : core[%x,%d] created child process %x at cycle %d\n", 1003 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process, (uint32_t)hal_get_cycles() ); 951 1004 952 1005 // allocate a child PID from local cluster 953 1006 error = cluster_pid_alloc( process , &new_pid ); 954 if( (error != 0) || (new_pid == 0) )1007 if( error ) 955 1008 { 956 1009 printk("\n[ERROR] in %s : cannot get PID in cluster %x\n", … … 960 1013 } 961 1014 962 fork_dmsg("\n[DBG] %s : core[%x, %d] child process PID allocated= %x at cycle %d\n",1015 fork_dmsg("\n[DBG] %s : core[%x, %d] child process PID = %x at cycle %d\n", 963 1016 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_pid , (uint32_t)hal_get_cycles() ); 964 1017 … … 966 1019 process_reference_init( process, 967 1020 new_pid, 968 parent_p id,1021 parent_process_xp, 969 1022 parent_process_xp ); 970 1023 … … 987 1040 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); 988 1041 1042 // update extended pointer on .elf file 1043 process->vfs_bin_xp = vfs_bin_xp; 1044 989 1045 // create child thread descriptor from parent thread descriptor 990 1046 error = thread_user_fork( parent_thread_xp, … … 1000 1056 } 1001 1057 1058 // check main thread index 1059 assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1060 1002 1061 fork_dmsg("\n[DBG] %s : core[%x,%d] child thread created at cycle %d\n", 1003 1062 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); … … 1018 1077 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); 1019 1078 1020 // update children list in parent process 1021 xlist_add_last( XPTR( parent_process_cxy , &parent_process_ptr->children_root ), 1022 XPTR( local_cxy , &process->brothers_list ) ); 1023 hal_remote_atomic_add( XPTR( parent_process_cxy, 1024 &parent_process_ptr->children_nr), 1 ); 1025 1026 // vmm_display( process , true ); 1027 // vmm_display( parent_process_ptr , true ); 1028 // sched_display( 0 ); 1079 // get extended pointers on parent children_root, children_lock and children_nr 1080 xptr_t children_root_xp = XPTR( parent_process_cxy , &parent_process_ptr->children_root ); 1081 xptr_t children_lock_xp = XPTR( parent_process_cxy , &parent_process_ptr->children_lock ); 1082 xptr_t children_nr_xp = XPTR( parent_process_cxy , &parent_process_ptr->children_nr ); 1083 1084 // register process in parent children list 1085 remote_spinlock_lock( children_lock_xp ); 1086 xlist_add_last( children_root_xp , XPTR( local_cxy , &process->children_list ) ); 1087 hal_remote_atomic_add( children_nr_xp , 1 ); 1088 remote_spinlock_unlock( children_lock_xp ); 1029 1089 1030 1090 // return success … … 1032 1092 *child_pid = new_pid; 1033 1093 1094 1034 1095 fork_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n", 1035 1096 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); … … 1044 1105 { 1045 1106 char * path; // pathname to .elf file 1107 pid_t pid; // old_process PID given to new_process 1108 pid_t temp_pid; // temporary PID given to old_process 1046 1109 process_t * old_process; // local pointer on old process 1047 1110 process_t * new_process; // local pointer on new process 1048 pid_t old_pid; // old process identifier 1049 pid_t new_pid; // new (temporary) process identifier 1050 thread_t * old_thread; // pointer on new thread 1051 thread_t * new_thread; // pointer on new thread 1111 thread_t * new_thread; // local pointer on main thread 1052 1112 pthread_attr_t attr; // main thread attributes 1053 1113 lid_t lid; // selected core local index … … 1056 1116 // get .elf pathname and PID from exec_info 1057 1117 path = exec_info->path; 1058 old_pid= exec_info->pid;1118 pid = exec_info->pid; 1059 1119 1060 1120 // this function must be executed by a thread running in owner cluster 1061 assert( (CXY_FROM_PID( old_pid ) == local_cxy), __FUNCTION__, 1062 "local cluster %x is not owner for process %x\n", local_cxy, old_pid ); 1063 1064 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n", 1065 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, old_pid , path ); 1066 1067 // get old process and thread local pointers 1068 old_process = (process_t *)cluster_get_local_process_from_pid( old_pid ); 1069 old_thread = CURRENT_THREAD; 1121 assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__, 1122 "local cluster %x is not owner for process %x\n", local_cxy, pid ); 1123 1124 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / %s / cycle %d\n", 1125 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path, (uint32_t)hal_get_cycles() ); 1126 1127 // get old_process local pointer 1128 old_process = (process_t *)cluster_get_local_process_from_pid( pid ); 1070 1129 1071 1130 if( old_process == NULL ) … … 1075 1134 } 1076 1135 1077 // allocate memory for newprocess descriptor1136 // allocate memory for new_process descriptor 1078 1137 new_process = process_alloc(); 1079 1138 1080 1139 if( new_process == NULL ) 1081 1140 { 1082 printk("\n[ERROR] in %s : cannot allocate new process descriptor\n", __FUNCTION__ ); 1141 printk("\n[ERROR] in %s : cannot allocate process descriptor in cluster %x\n", 1142 __FUNCTION__ , local_cxy ); 1083 1143 return -1; 1084 1144 } 1085 1145 1086 // get a (temporary) PID for newprocess1087 error = cluster_pid_alloc( new_process , &new_pid );1088 1089 if( error )1090 {1091 printk("\n[ERROR] in %s : cannot allocate a temporary PID\n", __FUNCTION__ );1092 process_ destroy( new_process );1146 // get a new PID for old_process 1147 error = cluster_pid_alloc( old_process , &temp_pid ); 1148 if( error ) 1149 { 1150 printk("\n[ERROR] in %s : cannot get PID in cluster %x\n", 1151 __FUNCTION__ , local_cxy ); 1152 process_free( new_process ); 1093 1153 return -1; 1094 1154 } 1155 1156 // request blocking for all threads in old_process (but the calling thread) 1157 process_sigaction( old_process , BLOCK_ALL_THREADS ); 1158 1159 // request destruction for all threads in old_process (but the calling thread) 1160 process_sigaction( old_process , DELETE_ALL_THREADS ); 1161 1162 exec_dmsg("\n[DBG] %s : core[%x,%d] marked old threads for destruction / cycle %d\n", 1163 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , (uint32_t)hal_get_cycles() ); 1164 1165 // set new PID to old_process 1166 old_process->pid = temp_pid; 1095 1167 1096 1168 // initialize new process descriptor 1097 1169 process_reference_init( new_process, 1098 new_pid, // temporary PID 1099 old_process->ppid, // same parent 1100 XPTR( local_cxy , old_process ) ); 1101 1102 exec_dmsg("\n[DBG] %s : core[%x,%d] created new process %x / path = %s\n", 1103 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_pid, path ); 1104 1105 // register "code" and "data" vsegs as well as entry-point 1106 // in new process VMM, using information contained in the elf file. 1170 pid, 1171 old_process->parent_xp, // parent_process_xp 1172 XPTR(local_cxy , old_process) ); // model_process_xp 1173 1174 // give TXT ownership to new_process 1175 process_txt_set_ownership( XPTR( local_cxy , new_process ) ); 1176 1177 exec_dmsg("\n[DBG] %s : core[%x,%d] initialised new process %x / cycle %d \n", 1178 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_process, (uint32_t)hal_get_cycles() ); 1179 1180 // register code & data vsegs as well as entry-point in new process VMM, 1181 // and register extended pointer on .elf file in process descriptor 1107 1182 if( elf_load_process( path , new_process ) ) 1108 1183 { 1109 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n", 1110 __FUNCTION__, new_pid , path ); 1111 cluster_pid_release( new_pid ); 1184 printk("\n[ERROR] in %s : failed to access .elf file for path %s\n", 1185 __FUNCTION__ , path ); 1112 1186 process_destroy( new_process ); 1113 1187 return -1; 1114 1188 } 1115 1189 1116 exec_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",1117 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path);1190 exec_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered in new process %x / cycle %d\n", 1191 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_process, (uint32_t)hal_get_cycles() ); 1118 1192 1119 1193 // select a core in local cluster to execute the main thread … … 1125 1199 attr.lid = lid; 1126 1200 1127 // create and initialize thread descriptor1128 error = thread_user_create( new_pid,1201 // create and initialize main thread in local cluster 1202 error = thread_user_create( pid, 1129 1203 (void *)new_process->vmm.entry_point, 1130 1204 exec_info->args_pointers, … … 1133 1207 if( error ) 1134 1208 { 1135 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n", 1136 __FUNCTION__, new_pid , path ); 1137 cluster_pid_release( new_pid ); 1209 printk("\n[ERROR] in %s : cannot create thread for process %x\n", 1210 __FUNCTION__ , new_process ); 1138 1211 process_destroy( new_process ); 1139 1212 return -1; 1140 1213 } 1141 1214 1142 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x\n", 1143 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_thread->trdid ); 1144 1145 // update children list rooted in parent process 1146 xlist_replace( XPTR( local_cxy , &old_process->brothers_list ) , 1147 XPTR( local_cxy , &new_process->brothers_list ) ); 1148 1149 // request blocking for all threads in old process (but the calling thread) 1150 process_sigaction( old_process , BLOCK_ALL_THREADS ); 1151 1152 // request destruction for all threads in old process (but the calling thread) 1153 process_sigaction( old_process , DELETE_ALL_THREADS ); 1154 1155 // update PID for both processes 1156 new_process->pid = old_pid; 1157 old_process->pid = 0xFFFFFFFF; 1158 1159 // release temporary PID 1160 cluster_pid_release( new_pid ); 1161 1215 // check main thread index 1216 assert( (new_thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1217 1218 exec_dmsg("\n[DBG] %s : core[%x,%d] created new_process main thread / cycle %d\n", 1219 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); 1220 1221 // get pointers on parent process 1222 xptr_t parent_xp = new_process->parent_xp; 1223 process_t * parent_ptr = GET_PTR( parent_xp ); 1224 cxy_t parent_cxy = GET_CXY( parent_xp ); 1225 1226 // get extended pointers on parent children_root, children_lock and children_nr 1227 xptr_t root_xp = XPTR( parent_cxy , &parent_ptr->children_root ); 1228 xptr_t lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock ); 1229 xptr_t nr_xp = XPTR( parent_cxy , &parent_ptr->children_nr ); 1230 1231 // register new_process in parent children list 1232 remote_spinlock_lock( lock_xp ); 1233 xlist_add_last( root_xp , XPTR( local_cxy , &new_process->children_list ) ); 1234 hal_remote_atomic_add( nr_xp , 1 ); 1235 remote_spinlock_unlock( lock_xp ); 1236 1237 exec_dmsg("\n[DBG] %s : core[%x,%d] updated parent process children list / cycle %d\n", 1238 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); 1239 1240 // block and mark calling thread for deletion 1241 // only when it is an user thread 1242 thread_t * this = CURRENT_THREAD; 1243 if( this->type == THREAD_USER ) 1244 { 1245 thread_block( this , THREAD_BLOCKED_GLOBAL ); 1246 hal_atomic_or( &this->flags , THREAD_FLAG_REQ_DELETE ); 1247 } 1248 1162 1249 // activate new thread 1163 1250 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 1164 1251 1165 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n", 1166 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 1167 1168 // set BLOCKED_GLOBAL bit 1169 thread_block( old_thread , THREAD_BLOCKED_GLOBAL ); 1170 1171 // set REQ_DELETE flag 1172 hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE ); 1173 1174 // deschedule 1175 sched_yield("suicide after exec"); 1176 1177 // never executed but required by compiler 1252 hal_fence(); 1253 1254 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s / cycle %d\n", 1255 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path , (uint32_t)hal_get_cycles() ); 1256 1178 1257 return 0; 1179 1258 … … 1188 1267 "must execute in owner cluster" ); 1189 1268 1269 thread_t * this = CURRENT_THREAD; 1270 1190 1271 kill_dmsg("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d\n", 1191 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );1192 1193 // get pointer on local process descriptor1272 __FUNCTION__, local_cxy, this->core->lid, pid , sig_id ); 1273 1274 // get pointer on local target process descriptor 1194 1275 process_t * process = process_get_local_copy( pid ); 1195 1276 … … 1205 1286 switch( sig_id ) 1206 1287 { 1207 case SIGSTOP: // block all threads in all clusters1288 case SIGSTOP: 1208 1289 { 1290 // block all threads in all clusters 1209 1291 process_sigaction( process , BLOCK_ALL_THREADS ); 1292 1293 // remove TXT ownership to target process 1294 process_txt_reset_ownership( XPTR( local_cxy , process ) ); 1210 1295 } 1211 1296 break; … … 1217 1302 case SIGKILL: // block all threads, then delete all threads 1218 1303 { 1219 // block all threads (but the calling thread)1304 // block all threads in all clusters 1220 1305 process_sigaction( process , BLOCK_ALL_THREADS ); 1306 1307 // remove TXT ownership to target process 1308 process_txt_reset_ownership( XPTR( local_cxy , process ) ); 1221 1309 1222 1310 // delete all threads (but the calling thread) … … 1224 1312 1225 1313 // delete the calling thread if required 1226 thread_t * this = CURRENT_THREAD; 1227 1228 if( this->process == process ) 1314 if( CURRENT_THREAD->process == process ) 1229 1315 { 1230 1316 // set REQ_DELETE flag … … 1238 1324 } 1239 1325 1240 //@@@1241 sched_display( 0 );1242 //@@@1243 1244 1326 kill_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d \n", 1245 1327 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id ); … … 1280 1362 } // end process_make_exit() 1281 1363 1364 /////////////////////////////////////////////// 1365 void process_zero_create( process_t * process ) 1366 { 1367 1368 process_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n", 1369 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() ); 1370 1371 // initialize PID, REF_XP, PARENT_XP, and STATE 1372 process->pid = 0; 1373 process->ref_xp = XPTR( local_cxy , process ); 1374 process->parent_xp = XPTR_NULL; 1375 process->state = PROCESS_STATE_RUNNING; 1376 1377 // reset th_tbl[] array as empty 1378 uint32_t i; 1379 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ ) 1380 { 1381 process->th_tbl[i] = NULL; 1382 } 1383 process->th_nr = 0; 1384 spinlock_init( &process->th_lock ); 1385 1386 // reset children list as empty 1387 xlist_root_init( XPTR( local_cxy , &process->children_root ) ); 1388 remote_spinlock_init( XPTR( local_cxy , &process->children_lock ) ); 1389 process->children_nr = 0; 1390 1391 hal_fence(); 1392 1393 process_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n", 1394 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , (uint32_t)hal_get_cycles() ); 1395 1396 } // end process_zero_init() 1397 1282 1398 ////////////////////////// 1283 1399 void process_init_create() 1284 1400 { 1285 process_t * process; // local pointer on process _initdescriptor1401 process_t * process; // local pointer on process descriptor 1286 1402 pid_t pid; // process_init identifier 1287 1403 thread_t * thread; // local pointer on main thread … … 1290 1406 error_t error; 1291 1407 1292 kinit_dmsg("\n[DBG] %s : core[%x,%d] enters\n",1408 process_dmsg("\n[DBG] %s : core[%x,%d] enters at cycle %d\n", 1293 1409 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid ); 1294 1410 … … 1307 1423 printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n", 1308 1424 __FUNCTION__, local_cxy ); 1309 process_destroy( process ); 1310 } 1311 1312 assert( (LPID_FROM_PID(pid) == 1) , __FUNCTION__ , "LPID must be 1 for process_init" ); 1425 process_free( process ); 1426 } 1427 1428 // check allocated PID 1429 assert( (pid == 1) , __FUNCTION__ , "process INIT must be first process in cluster 0\n" ); 1313 1430 1314 1431 // initialize process descriptor / parent is local process_zero 1315 1432 process_reference_init( process, 1316 1433 pid, 1317 0,1318 XPTR( local_cxy , &process_zero ) ); 1319 1320 kinit_dmsg("\n[DBG] %s : core[%x,%d] / process initialised\n",1434 XPTR( local_cxy , &process_zero ), // parent 1435 XPTR( local_cxy , &process_zero ) ); // model 1436 1437 process_dmsg("\n[DBG] %s : core[%x,%d] / initialisation done\n", 1321 1438 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid ); 1322 1439 … … 1330 1447 } 1331 1448 1332 kinit_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",1449 process_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n", 1333 1450 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, CONFIG_PROCESS_INIT_PATH ); 1451 1452 // get extended pointers on process_zero children_root, children_lock 1453 xptr_t children_root_xp = XPTR( local_cxy , &process_zero.children_root ); 1454 xptr_t children_lock_xp = XPTR( local_cxy , &process_zero.children_lock ); 1455 1456 // register process INIT in parent local process_zero 1457 remote_spinlock_lock( children_lock_xp ); 1458 xlist_add_last( children_root_xp , XPTR( local_cxy , &process->children_list ) ); 1459 hal_atomic_add( &process_zero.children_nr , 1 ); 1460 remote_spinlock_unlock( children_lock_xp ); 1334 1461 1335 1462 // select a core in local cluster to execute the main thread … … 1354 1481 } 1355 1482 1483 // check main thread index 1484 assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1485 1356 1486 // activate thread 1357 1487 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL ); … … 1359 1489 hal_fence(); 1360 1490 1361 kinit_dmsg("\n[DBG] %s : core[%x,%d] exit / main thread = %x\n",1491 process_dmsg("\n[DBG] %s : core[%x,%d] exit / main thread = %x\n", 1362 1492 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, thread ); 1363 1493 1364 1494 } // end process_init_create() 1365 1495 1496 ////////////////////////////////////////// 1497 char * process_state_str( uint32_t state ) 1498 { 1499 if ( state == PROCESS_STATE_RUNNING ) return "RUNNING"; 1500 else if( state == PROCESS_STATE_KILLED ) return "KILLED"; 1501 else if( state == PROCESS_STATE_EXITED ) return "EXITED"; 1502 else return "undefined"; 1503 } 1504 1505 ///////////////////////////////////////// 1506 void process_display( xptr_t process_xp ) 1507 { 1508 process_t * process_ptr; 1509 cxy_t process_cxy; 1510 xptr_t parent_xp; // extended pointer on parent process 1511 process_t * parent_ptr; 1512 cxy_t parent_cxy; 1513 1514 pid_t pid; 1515 pid_t ppid; 1516 uint32_t state; 1517 xptr_t ref_xp; 1518 uint32_t th_nr; 1519 1520 xptr_t txt_file_xp; // extended pointer on TXT_RX pseudo file 1521 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1522 chdev_t * chdev_ptr; 1523 cxy_t chdev_cxy; 1524 xptr_t owner_xp; // extended pointer on TXT owner process 1525 1526 xptr_t elf_file_xp; // extended pointer on .elf file 1527 cxy_t elf_file_cxy; 1528 vfs_file_t * elf_file_ptr; 1529 vfs_inode_t * elf_inode_ptr; // local pointer on .elf inode 1530 1531 char txt_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1532 char elf_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1533 1534 // get cluster and local pointer on process 1535 process_ptr = GET_PTR( process_xp ); 1536 process_cxy = GET_CXY( process_xp ); 1537 1538 // check reference process 1539 ref_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->ref_xp ) ); 1540 assert( (process_xp == ref_xp) , __FUNCTION__ , "process is not the reference\n"); 1541 1542 // get PID and state 1543 pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1544 state = hal_remote_lw( XPTR( process_cxy , &process_ptr->state ) ); 1545 1546 // get PPID 1547 parent_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) ); 1548 parent_cxy = GET_CXY( parent_xp ); 1549 parent_ptr = GET_PTR( parent_xp ); 1550 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 1551 1552 // get number of threads 1553 th_nr = hal_remote_lw( XPTR( process_cxy , &process_ptr->th_nr ) ); 1554 1555 // get TXT name and process owner 1556 txt_file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1557 1558 assert( (txt_file_xp != XPTR_NULL) , __FUNCTION__ , 1559 "process must be attached to one TXT terminal\n" ); 1560 1561 chdev_xp = chdev_from_file( txt_file_xp ); 1562 chdev_cxy = GET_CXY( chdev_xp ); 1563 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 1564 hal_remote_strcpy( XPTR( local_cxy , txt_name ) , 1565 XPTR( chdev_cxy , chdev_ptr->name ) ); 1566 owner_xp = (xptr_t)hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) ); 1567 1568 // get process .elf name 1569 elf_file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->vfs_bin_xp ) ); 1570 1571 elf_file_cxy = GET_CXY( elf_file_xp ); 1572 elf_file_ptr = (vfs_file_t *)GET_PTR( elf_file_xp ); 1573 elf_inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( elf_file_cxy , &elf_file_ptr->inode ) ); 1574 vfs_inode_get_name( XPTR( elf_file_cxy , elf_inode_ptr ) , elf_name ); 1575 1576 // display process info 1577 if( owner_xp == process_xp ) 1578 { 1579 printk("PID %X | PPID %X | %s\t| %s (FG) | %X | %d | %s\n", 1580 pid, ppid, process_state_str(state), txt_name, process_ptr, th_nr, elf_name ); 1581 } 1582 else 1583 { 1584 printk("PID %X | PPID %X | %s\t| %s (BG) | %X | %d | %s\n", 1585 pid, ppid, process_state_str(state), txt_name, process_ptr, th_nr, elf_name ); 1586 } 1587 } // end process_display() 1588 1589 1590 //////////////////////////////////////////////////////////////////////////////////////// 1591 // Terminals related functions 1592 //////////////////////////////////////////////////////////////////////////////////////// 1593 1594 //////////////////////////// 1595 uint32_t process_txt_alloc() 1596 { 1597 uint32_t index; // TXT terminal index 1598 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1599 chdev_t * chdev_ptr; // local pointer on TXT_RX chdev 1600 cxy_t chdev_cxy; // TXT_RX chdev cluster 1601 xptr_t root_xp; // extended pointer on owner field in chdev 1602 1603 // scan the user TXT_RX chdevs (TXT0 is reserved for kernel) 1604 for( index = 1 ; index < LOCAL_CLUSTER->nb_txt_channels ; index ++ ) 1605 { 1606 // get pointers on TXT_RX[index] 1607 chdev_xp = chdev_dir.txt_rx[index]; 1608 chdev_cxy = GET_CXY( chdev_xp ); 1609 chdev_ptr = GET_PTR( chdev_xp ); 1610 1611 // get extended pointer on root of attached process 1612 root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root ); 1613 1614 // return free TXT index if found 1615 if( xlist_is_empty( root_xp ) ) return index; 1616 } 1617 1618 assert( false , __FUNCTION__ , "no free TXT terminal found" ); 1619 1620 return -1; 1621 1622 } // end process_txt_alloc() 1623 1624 ///////////////////////////////////////////// 1625 void process_txt_attach( process_t * process, 1626 uint32_t txt_id ) 1627 { 1628 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1629 cxy_t chdev_cxy; // TXT_RX chdev cluster 1630 chdev_t * chdev_ptr; // local pointer on TXT_RX chdev 1631 xptr_t root_xp; // extended pointer on list root in chdev 1632 xptr_t lock_xp; // extended pointer on list lock in chdev 1633 1634 process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x at cycle\n", 1635 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() ); 1636 1637 // check process is reference 1638 assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ , 1639 "process is not the reference descriptor" ); 1640 1641 // check terminal index 1642 assert( (txt_id < LOCAL_CLUSTER->nb_txt_channels) , 1643 __FUNCTION__ , "illegal TXT terminal index" ); 1644 1645 // get pointers on TXT_RX[txt_id] chdev 1646 chdev_xp = chdev_dir.txt_rx[txt_id]; 1647 chdev_cxy = GET_CXY( chdev_xp ); 1648 chdev_ptr = GET_PTR( chdev_xp ); 1649 1650 // get extended pointer on root & lock of attached process list 1651 root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root ); 1652 lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock ); 1653 1654 // insert process in attached process list 1655 remote_spinlock_lock( lock_xp ); 1656 xlist_add_last( root_xp , XPTR( local_cxy , &process->txt_list ) ); 1657 remote_spinlock_unlock( lock_xp ); 1658 1659 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x at cycle\n", 1660 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() ); 1661 1662 } // end process_txt_attach() 1663 1664 ////////////////////////////////////////////// 1665 void process_txt_detach( process_t * process ) 1666 { 1667 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1668 cxy_t chdev_cxy; // TXT_RX chdev cluster 1669 chdev_t * chdev_ptr; // local pointer on TXT_RX chdev 1670 xptr_t lock_xp; // extended pointer on list lock in chdev 1671 1672 process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x at cycle\n", 1673 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() ); 1674 1675 // check process is reference 1676 assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ , 1677 "process is not the reference descriptor" ); 1678 1679 // get extended pointer on TXT_RX chdev 1680 chdev_xp = chdev_from_file( process->fd_array.array[0] ); 1681 chdev_cxy = GET_CXY( chdev_xp ); 1682 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 1683 1684 // get extended pointer on lock of attached process list 1685 lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock ); 1686 1687 // unlink process from attached process list 1688 remote_spinlock_lock( lock_xp ); 1689 xlist_unlink( XPTR( local_cxy , &process->txt_list ) ); 1690 remote_spinlock_unlock( lock_xp ); 1691 1692 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x at cycle %d\n", 1693 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() ); 1694 1695 } // end process_txt_detach() 1696 1697 /////////////////////////////////////////////////// 1698 void process_txt_set_ownership( xptr_t process_xp ) 1699 { 1700 process_t * process_ptr; 1701 cxy_t process_cxy; 1702 xptr_t file_xp; 1703 xptr_t txt_xp; 1704 chdev_t * txt_ptr; 1705 cxy_t txt_cxy; 1706 1707 // get cluster and local pointer on process 1708 process_cxy = GET_CXY( process_xp ); 1709 process_ptr = (process_t *)GET_PTR( process_xp ); 1710 1711 // get extended pointer on stdin pseudo file 1712 file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1713 1714 // get pointers on TXT chdev 1715 txt_xp = chdev_from_file( file_xp ); 1716 txt_cxy = GET_CXY( txt_xp ); 1717 txt_ptr = (chdev_t *)GET_PTR( txt_xp ); 1718 1719 // set owner field in TXT chdev 1720 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , process_xp ); 1721 1722 } // end process_txt_set ownership() 1723 1724 ///////////////////////////////////////////////////// 1725 void process_txt_reset_ownership( xptr_t process_xp ) 1726 { 1727 process_t * process_ptr; 1728 cxy_t process_cxy; 1729 xptr_t parent_xp; // extended pointer on parent process 1730 process_t * parent_ptr; 1731 cxy_t parent_cxy; 1732 xptr_t file_xp; // extended pointer on TXT_RX pseudo file 1733 xptr_t txt_xp; // extended pointer on TXT_RX chdev 1734 chdev_t * txt_ptr; 1735 cxy_t txt_cxy; 1736 xptr_t owner_xp; // extended pointer on current TXT_RX owner 1737 xptr_t root_xp; // extended pointer on root of attached process list 1738 xptr_t iter_xp; // iterator for xlist 1739 xptr_t current_xp; // extended pointer on current process 1740 process_t * current_ptr; 1741 cxy_t current_cxy; 1742 pid_t ppid; 1743 1744 // get cluster and local pointer on process 1745 process_cxy = GET_CXY( process_xp ); 1746 process_ptr = (process_t *)GET_PTR( process_xp ); 1747 1748 // get extended pointer on stdin pseudo file 1749 file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1750 1751 // get pointers on TXT chdev 1752 txt_xp = chdev_from_file( file_xp ); 1753 txt_cxy = GET_CXY( txt_xp ); 1754 txt_ptr = (chdev_t *)GET_PTR( txt_xp ); 1755 1756 // get extended pointer on TXT_RX owner 1757 owner_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) ); 1758 1759 // transfer ownership to KSH if required 1760 if( owner_xp == process_xp ) 1761 { 1762 // get extended pointer on root of list of attached processes 1763 root_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.root ) ); 1764 1765 // scan attached process list to find KSH process 1766 XLIST_FOREACH( root_xp , iter_xp ) 1767 { 1768 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1769 current_cxy = GET_CXY( current_xp ); 1770 current_ptr = GET_PTR( current_xp ); 1771 parent_xp = hal_remote_lwd( XPTR( current_cxy , ¤t_ptr->parent_xp ) ); 1772 1773 parent_cxy = GET_CXY( parent_xp ); 1774 parent_ptr = GET_PTR( parent_xp ); 1775 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 1776 1777 if( ppid == 1 ) // current is KSH 1778 { 1779 // set owner field in TXT chdev 1780 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1781 return; 1782 } 1783 } 1784 } 1785 1786 assert( false , __FUNCTION__ , "KSH process not found" ); 1787 1788 } // end process_txt_reset_ownership() 1789 1790 1791 -
trunk/kernel/kern/process.h
r416 r428 54 54 55 55 /********************************************************************************************* 56 * This enum defines the actions that can be executed by the process_sig nal() function.56 * This enum defines the actions that can be executed by the process_sigaction() function. 57 57 ********************************************************************************************/ 58 58 … … 62 62 UNBLOCK_ALL_THREADS = 22, 63 63 DELETE_ALL_THREADS = 33, 64 }; 65 66 /********************************************************************************************* 67 * This enum defines the process states for ALMOS_MKH. 68 ********************************************************************************************/ 69 70 enum process_states 71 { 72 PROCESS_STATE_RUNNING = 0, /*! process is executing */ 73 PROCESS_STATE_STOPPED = 1, /*! process has been stopped by a signal */ 74 PROCESS_STATE_KILLED = 2, /*! process has been killed by a signal */ 75 PROCESS_STATE_EXITED = 3, /*! process terminated with an exit */ 64 76 }; 65 77 … … 102 114 * 4) The <sem_root>, <mutex_root>, <barrier_root>, <condvar_root>, and the associated 103 115 * <sync_lock>, that are dynamically allocated, are only defined in the reference cluster. 104 * 5) The <children_root>, and <children_nr> fields are only defined in the reference105 * cluster, and are undefined in other clusters.106 * 6) The < brothers_list>, <local_list>, <copies_list>, <th_tbl>, <th_nr>, <th_lock> fields116 * 5) The <children_root>, <children_nr>, <brothers_list>, and <txt_list> fields are only 117 * defined in the reference cluster, and are undefined in other clusters. 118 * 6) The <local_list>, <copies_list>, <th_tbl>, <th_nr>, <th_lock> fields 107 119 * are defined in all process descriptors copies. 108 120 ********************************************************************************************/ … … 115 127 116 128 xptr_t vfs_root_xp; /*! extended pointer on current VFS root inode */ 117 xptr_t vfs_bin_xp; /*! extended pointer on .elf file inode*/129 xptr_t vfs_bin_xp; /*! extended pointer on .elf file descriptor */ 118 130 pid_t pid; /*! process identifier */ 119 pid_t ppid; /*! parent process identifier */120 131 xptr_t ref_xp; /*! extended pointer on reference process */ 132 xptr_t parent_xp; /*! extended pointer on parent process */ 121 133 122 134 xptr_t vfs_cwd_xp; /*! extended pointer on current working dir inode */ … … 124 136 125 137 xlist_entry_t children_root; /*! root of the children process xlist */ 138 remote_spinlock_t children_lock; /*! lock protecting children process xlist */ 126 139 uint32_t children_nr; /*! number of children processes */ 127 140 128 xlist_entry_t brothers_list; /*! member of list of children of same parent */141 xlist_entry_t children_list; /*! member of list of children of same parent */ 129 142 xlist_entry_t local_list; /*! member of list of process in same cluster */ 130 143 xlist_entry_t copies_list; /*! member of list of copies of same process */ 144 xlist_entry_t txt_list; /*! member of list of processes sharing same TXT */ 131 145 132 146 spinlock_t th_lock; /*! lock protecting th_tbl[] concurrent access */ 133 147 uint32_t th_nr; /*! number of threads in this cluster */ 148 134 149 struct thread_s * th_tbl[CONFIG_THREAD_MAX_PER_CLUSTER]; /*! pointers on local threads */ 135 150 … … 138 153 xlist_entry_t barrier_root; /*! root of the process barrier list */ 139 154 xlist_entry_t condvar_root; /*! root of the process condvar list */ 140 141 155 remote_spinlock_t sync_lock; /*! lock protecting sem,mutex,barrier,condvar lists */ 156 157 uint32_t state; /*! RUNNING / STOPPED / KILLED / EXITED */ 158 159 bool_t txt_owner; /*! current TXT owner */ 142 160 } 143 161 process_t; … … 182 200 183 201 /********************************************************************************************* 202 * This function initialize, in each cluster, the kernel "process_zero", that is the owner 203 * of all kernel threads in a given cluster. It is called by the kernel_init() function. 204 * The process_zero descriptor is allocated as a global variable in file kernel_init.c 205 * Both the PID and PPID fields are set to zero, the ref_xp is the local process_zero, 206 * and the parent process is set to XPTR_NULL. The th_tbl[] is initialized as empty. 207 ********************************************************************************************* 208 * @ process : [in] pointer on local process descriptor to initialize. 209 ********************************************************************************************/ 210 void process_zero_create( process_t * process ); 211 212 /********************************************************************************************* 184 213 * This function allocates memory and initializes the "process_init" descriptor and the 185 214 * associated "thread_init" descriptor. It is called once at the end of the kernel 186 * initialisation procedure, by the kernel process in cluster_IO. 215 * initialisation procedure. Its local process identifier is 1, and parent process 216 * is the kernel process in cluster 0. 187 217 * The "process_init" is the first user process, and all other user processes will be forked 188 218 * from this process. The code executed by "process_init" is stored in a .elf file, whose 189 219 * pathname is defined by the CONFIG_PROCESS_INIT_PATH configuration variable. 190 * The process_init streams are defined by the CONFIG_INIT_[STDIN/STDOUT/STDERR] variables.191 * Its local process identifier is 1, and parent process is the local kernel process_zero.220 * The process_init does not use the [STDIN/STDOUT/STDERR] streams, but it is linked 221 * to kernel TXT0, because these streams must be defined for all user processes. 192 222 ********************************************************************************************/ 193 223 void process_init_create(); 194 224 195 225 /********************************************************************************************* 196 * This function initialize, in each cluster, the kernel "process_zero", that is the owner 197 * of all kernel threads in a given cluster. It is called by the kernel_init() function. 198 * Both the PID and PPID fields are set to zero, and the ref_xp is the local process_zero. 199 * The th_tbl[] is initialized as empty. 200 ********************************************************************************************* 201 * @ process : [in] pointer on local process descriptor to initialize. 202 ********************************************************************************************/ 203 void process_zero_init( process_t * process ); 204 205 /********************************************************************************************* 206 * This function initializes a local, reference user process descriptor from another process 207 * descriptor, defined by the <model_xp> argument. The <process> descriptor, the <pid>, and 208 * the <ppid> arguments must be previously defined by the caller. 209 * It can be called by two functions, depending on the process type: 210 * 1) if "process" is the "process_init", the parent is the kernel process. It is 211 * called once, by the process_init_create() function in cluster[xmax-1][ymax-1]. 212 * 2) if the caller is the process_make_fork() function, the model is generally a remote 213 * process, that is also the parent process. 214 215 * 3) if the caller is the process_make_exec() function, the model is always a local process, 216 * and the parent is the parent of the model process. DEPRECATED [AG] 217 218 * The following fields are initialised (for all process but process_zero). 219 * - It set the pid / ppid / ref_xp fields. 226 * This function initializes a local, reference, user process descriptor from another process 227 * descriptor, defined by the <model_xp> argument. The <process> and <pid> arguments must 228 * be previously allocated by he caller. This function can be called by three functions: 229 * 1) process_init_create() : process is the reference INIT process / pid = 1 / 230 * the parent and model process descriptors are both the kernel process_zero. 231 * 2) process_make_fork() : the model process descriptor is the (generally remote) 232 * parent process. 233 * 3) process_make exec() : the model process is the local old_process, the new_process 234 * parent is the same as the old_process parent. 235 * The following fields are initialised : 236 * - It set the pid / ppid / ref_xp / parent_xp / state fields. 220 237 * - It initializes the VMM (register the kentry, args, envs vsegs in VSL) 221 238 * - It initializes the FDT, defining the three pseudo files STDIN / STDOUT / STDERR. … … 230 247 * @ process : [in] pointer on local process descriptor to initialize. 231 248 * @ pid : [in] process identifier. 232 * @ p pid : [in] parent process identifier.233 * @ model_xp : [in] extended pointer on model process descriptor (local or remote).249 * @ parent_xp : [in] extended pointer on parent process descriptor. 250 * @ model_xp : [in] extended pointer on model process descriptor. 234 251 ********************************************************************************************/ 235 252 void process_reference_init( process_t * process, 236 253 pid_t pid, 237 pid_t ppid,254 xptr_t parent_xp, 238 255 xptr_t model_xp ); 239 256 … … 259 276 260 277 /********************************************************************************************* 261 * This function returns a printable string defining the action for process_signa().262 ********************************************************************************************* 263 * @ action_type : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS278 * This function returns a printable string defining the process state. 279 ********************************************************************************************* 280 * @ state : RUNNING / BLOCKED / EXITED / KILLED 264 281 * @ return a string pointer. 265 282 ********************************************************************************************/ 266 char * process_action_str( uint32_t action_type ); 283 char * process_state_str( uint32_t state ); 284 285 /********************************************************************************************* 286 * This debug function diplays on the kernel terminal TXT0 detailed informations on a 287 * reference process identified by the <process_xp> argument. 288 * It can be called by a thread running in any cluster. 289 ********************************************************************************************* 290 * @ process_xp : extended pointer on reference process. 291 ********************************************************************************************/ 292 void process_display( xptr_t process_xp ); 293 294 /********************************************************************************************* 295 * This function returns a printable string defining the sigaction type. 296 ********************************************************************************************* 297 * @ sigaction_type : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS 298 * @ return a string pointer. 299 ********************************************************************************************/ 300 char * process_action_str( uint32_t sigaction_type ); 267 301 268 302 /********************************************************************************************* … … 290 324 291 325 /********************************************************************************************* 292 * This function blocks all threads of a given user process in a given cluster. 326 * This function blocks all threads (but the client thread defined by the <client_xp> 327 * argument) for a given <process> in a given cluster. 293 328 * It loops on all local threads of the process, set the THREAD_BLOCKED_GLOBAL bit, 294 329 * and request the relevant schedulers to acknowledge the blocking, using IPI if required. 295 330 * The threads are not detached from the scheduler, and not detached from the local process. 296 331 * This function returns only when all blockable threads in cluster are actually blocked. 297 * WARNING : the client thread defined by the <client_xp> argument is NOT blocked.298 332 ********************************************************************************************* 299 333 * @ process : pointer on the target process descriptor. 300 334 * @ client_xp : extended pointer on the client thread, that should not be blocked. 301 335 ********************************************************************************************/ 302 void process_block ( process_t * process,303 xptr_t client_xp );336 void process_block_threads( process_t * process, 337 xptr_t client_xp ); 304 338 305 339 /********************************************************************************************* … … 308 342 * @ process : pointer on the process descriptor. 309 343 ********************************************************************************************/ 310 void process_unblock( process_t * process ); 311 312 /********************************************************************************************* 313 * This function delete all threads, of a given user process in a given cluster. 344 void process_unblock_threads( process_t * process ); 345 346 /********************************************************************************************* 347 * This function delete all threads, (but the client thread defined by the <client_xp> 348 * argument) for a given <process> in a given cluster. 314 349 * It loops on all local threads of the process, and set the THREAD_FLAG_REQ_DELETE bit. 315 350 * For each marked thread, the following actions will be done by the scheduler at the next … … 320 355 * - the memory allocated to the thread descriptor is released. 321 356 * - the memory allocated to the process descriptor is released, if it is the last thread. 322 * WARNING : the client thread defined by the <client_xp> argument is NOT deleted.323 357 ********************************************************************************************* 324 358 * @ process : pointer on the process descriptor. 325 359 * @ client_xp : extended pointer on the client thread, that should not be deleted. 326 360 ********************************************************************************************/ 327 void process_delete ( process_t * process,328 xptr_t client_xp );361 void process_delete_threads( process_t * process, 362 xptr_t client_xp ); 329 363 330 364 /********************************************************************************************* … … 509 543 510 544 545 /*************** Terminals related operations ********************************************/ 546 547 /********************************************************************************************* 548 * This function scan the set of user TXT terminals to find a free terminal 549 * (the list of attached processes is empty for a free TXT terminal). 550 * It is called only by the process_reference_init() function when creating a KSH process. 551 * It makes a kernel panic if no free TXT terminal is found. 552 * As a KSH process is never deleted, the allocated TXT terminal is never released. 553 ********************************************************************************************* 554 * @ return TXT terminal index if succes / kernel panic if no terminal found. 555 ********************************************************************************************/ 556 uint32_t process_txt_alloc(); 557 558 /********************************************************************************************* 559 * This function attach a reference process descriptor, identified by the <process> 560 * argument to a TXT terminal, identified by its <txt_id> channel index argument. 561 * It insert the process descriptor in the xlist rooted in the TXT_RX device. 562 * It is called by the process_reference_init() function. 563 ********************************************************************************************* 564 * @ process : local pointer on process descriptor. 565 * @ txt_id : TXT channel index. 566 ********************************************************************************************/ 567 void process_txt_attach( process_t * process, 568 uint32_t txt_id ); 569 570 /********************************************************************************************* 571 * This function detach a reference process descriptor, identified by the <process_xp> 572 * argument, from the list of process attached to a given TXT terminal. 573 * It is called when the process is killed. 574 ********************************************************************************************* 575 * @ process : local pointer on process descriptor. 576 ********************************************************************************************/ 577 void process_txt_detach( process_t * process ); 578 579 /********************************************************************************************* 580 * This function gives to a process identified by the <process_xp> argument, and attached 581 * to terminal TXT[i] the exclusive ownership of the TXT_RX[i] terminal. 582 ********************************************************************************************* 583 * @ process_xp : extended pointer on reference process descriptor. 584 ********************************************************************************************/ 585 void process_txt_set_ownership( xptr_t process_xp ); 586 587 /********************************************************************************************* 588 * When the process identified by the <process_xp> argument has the exclusive ownership 589 * of the TXT_RX[i] terminal, this function gives this ownership to the KSH[i] process. 590 * It does nothing if the process is not the owner. 591 ********************************************************************************************* 592 * @ process_xp : extended pointer on reference process descriptor. 593 ********************************************************************************************/ 594 void process_txt_reset_ownership( xptr_t process_xp ); 511 595 512 596 #endif /* _PROCESS_H_ */ -
trunk/kernel/kern/rpc.c
r416 r428 79 79 &rpc_sched_display_server, // 27 80 80 &rpc_vmm_set_cow_server, // 28 81 &rpc_ undefined,// 2981 &rpc_vmm_display_server, // 29 82 82 }; 83 83 … … 85 85 void __attribute__((noinline)) rpc_undefined() 86 86 { 87 panic("called in cluster %x", local_cxy );87 assert( false , __FUNCTION__ , "called in cluster %x", local_cxy ); 88 88 } 89 89 … … 1036 1036 1037 1037 // call relevant kernel function 1038 if (action == DELETE_ALL_THREADS ) process_delete ( process , client_xp );1039 else if (action == BLOCK_ALL_THREADS ) process_block ( process , client_xp );1040 else if (action == UNBLOCK_ALL_THREADS ) process_unblock ( process );1038 if (action == DELETE_ALL_THREADS ) process_delete_threads ( process , client_xp ); 1039 else if (action == BLOCK_ALL_THREADS ) process_block_threads ( process , client_xp ); 1040 else if (action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process ); 1041 1041 1042 1042 // decrement the responses counter in RPC descriptor, … … 2266 2266 2267 2267 // get input arguments from client RPC descriptor 2268 lid_t lid = (lid_t)hal_remote_lw ( XPTR(cxy , &desc->args[0]));2268 lid_t lid = (lid_t)hal_remote_lwd( XPTR(cxy , &desc->args[0])); 2269 2269 2270 2270 // call local kernel function … … 2321 2321 2322 2322 // get input arguments from client RPC descriptor 2323 process = (process_t *)(intptr_t)hal_remote_l pt( XPTR(cxy , &desc->args[0]));2323 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0])); 2324 2324 2325 2325 // call local kernel function … … 2331 2331 } 2332 2332 2333 2333 ///////////////////////////////////////////////////////////////////////////////////////// 2334 // [29] Marshaling functions attached to RPC_VMM_DISPLAY (blocking) 2335 ///////////////////////////////////////////////////////////////////////////////////////// 2336 2337 ///////////////////////////////////////////// 2338 void rpc_vmm_display_client( cxy_t cxy, 2339 process_t * process, 2340 bool_t detailed ) 2341 { 2342 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 2343 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 2344 CURRENT_THREAD->core->lid , hal_time_stamp() ); 2345 2346 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 2347 2348 // initialise RPC descriptor header 2349 rpc_desc_t rpc; 2350 rpc.index = RPC_VMM_DISPLAY; 2351 rpc.response = 1; 2352 rpc.blocking = true; 2353 2354 // set input arguments in RPC descriptor 2355 rpc.args[0] = (uint64_t)(intptr_t)process; 2356 rpc.args[1] = (uint64_t)detailed; 2357 2358 // register RPC request in remote RPC fifo (blocking function) 2359 rpc_send( cxy , &rpc ); 2360 2361 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 2362 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 2363 CURRENT_THREAD->core->lid , hal_time_stamp() ); 2364 } 2365 2366 //////////////////////////////////////// 2367 void rpc_vmm_display_server( xptr_t xp ) 2368 { 2369 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 2370 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 2371 CURRENT_THREAD->core->lid , hal_time_stamp() ); 2372 2373 process_t * process; 2374 bool_t detailed; 2375 2376 // get client cluster identifier and pointer on RPC descriptor 2377 cxy_t cxy = (cxy_t)GET_CXY( xp ); 2378 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 2379 2380 // get input arguments from client RPC descriptor 2381 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0])); 2382 detailed = (bool_t) hal_remote_lwd( XPTR(cxy , &desc->args[1])); 2383 2384 // call local kernel function 2385 vmm_display( process , detailed ); 2386 2387 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 2388 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 2389 CURRENT_THREAD->core->lid , hal_time_stamp() ); 2390 } 2391 2392 -
trunk/kernel/kern/rpc.h
r416 r428 90 90 RPC_SCHED_DISPLAY = 27, 91 91 RPC_VMM_SET_COW = 28, 92 RPC_VMM_DISPLAY = 29, 92 93 93 94 RPC_MAX_INDEX = 30, … … 698 699 void rpc_vmm_set_cow_server( xptr_t xp ); 699 700 701 /*********************************************************************************** 702 * [29] The RPC_VMM_DISPLAY allows any client thread to display the VMM state 703 * of a remote reference process identified by the <cxy> and <process> arguments. 704 * The type of display is defined by the <detailed> boolean argument. 705 *********************************************************************************** 706 * @ cxy : server cluster identifier. 707 * @ process : [in] local pointer on reference process descriptor. 708 * @ detailed : [in] detailed display if true. 709 **********************************************************************************/ 710 void rpc_vmm_display_client( cxy_t cxy, 711 struct process_s * process, 712 bool_t detailed ); 713 714 void rpc_vmm_display_server( xptr_t xp ); 715 716 700 717 #endif -
trunk/kernel/kern/scheduler.c
r416 r428 86 86 87 87 // release lock 88 hal_fence(); 88 89 spinlock_unlock( &sched->lock ); 89 90 … … 181 182 list_entry_t * iter; 182 183 thread_t * thread; 183 184 // printk("\n@@@ %s : current thread %x enter at cycle %d\n", 185 // __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() ); 184 process_t * process; 186 185 187 186 scheduler_t * sched = &core->scheduler; … … 212 211 if( thread->flags & THREAD_FLAG_REQ_DELETE ) 213 212 { 214 215 sched_dmsg("\n[DBG] %s : current thread %x delete thread %x at cycle %d\n", 216 __FUNCTION__ , CURRENT_THREAD , thread , hal_time_stamp() ); 213 // get thread process descriptor 214 process = thread->process; 217 215 218 216 // release FPU if required … … 223 221 thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) ); 224 222 225 // detach thread from process226 process_remove_thread( thread );227 228 // remove thread from scheduler223 // remove thread from scheduler (scheduler lock already taken) 224 uint32_t threads_nr = sched->u_threads_nr; 225 assert( (threads_nr != 0) , __FUNCTION__ , "u_threads_nr cannot be 0\n" ); 226 sched->u_threads_nr = threads_nr - 1; 229 227 list_unlink( &thread->sched_list ); 230 sched->u_threads_nr--; 231 if( sched->u_threads_nr == 0 ) sched->u_last = NULL; 232 233 // release memory allocated to thread 228 if( threads_nr == 1 ) sched->u_last = NULL; 229 230 // delete thread 234 231 thread_destroy( thread ); 235 232 233 sched_dmsg("\n[DBG] %s : thread %x deleted thread %x / cycle %d\n", 234 __FUNCTION__ , CURRENT_THREAD , thread , (uint32_t)hal_get_cycles() ); 235 236 236 // destroy process descriptor if no more threads 237 if (thread->process->th_nr == 0) process_destroy( thread->process ); 237 if( process->th_nr == 0 ) 238 { 239 // delete process 240 process_destroy( process ); 241 242 sched_dmsg("\n[DBG] %s : thread %x deleted process %x / cycle %d\n", 243 __FUNCTION__ , CURRENT_THREAD , process , (uint32_t)hal_get_cycles() ); 244 245 } 238 246 } 239 247 } 240 248 241 249 // release lock 250 hal_fence(); 242 251 spinlock_unlock( &sched->lock ); 243 244 // printk("\n@@@ %s : current thread %x exit at cycle %d\n",245 // __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() );246 252 247 253 } // end sched_handle_requests() … … 277 283 278 284 // check next thread not blocked when type != IDLE 279 assert( ( next->blocked == 0) || (next->type = THREAD_IDLE) , __FUNCTION__ ,285 assert( ((next->blocked == 0) || (next->type == THREAD_IDLE)) , __FUNCTION__ , 280 286 "next thread %x (%s) is blocked on core[%x,%d]\n", 281 287 next->trdid , thread_type_str(next->type) , local_cxy , core->lid ); … … 310 316 { 311 317 312 sched_dmsg("\n[DBG] %s : core[%x,%d] / cause = %s\n" 318 #if( CONFIG_SCHED_DEBUG & 0x1 ) 319 if( hal_time_stamp() > CONFIG_SCHED_DEBUG ) 320 printk("\n[DBG] %s : core[%x,%d] / cause = %s\n" 313 321 " thread %x (%s) (%x,%x) continue / cycle %d\n", 314 322 __FUNCTION__, local_cxy, core->lid, cause, 315 323 current, thread_type_str(current->type), current->process->pid, current->trdid, 316 324 (uint32_t)hal_get_cycles() ); 325 #endif 317 326 318 327 } … … 355 364 remote_spinlock_lock_busy( lock_xp , &save_sr ); 356 365 357 nolock_printk("\n***** scheduler state for core[%x,%d] at cycle %d\n" 358 "kernel_threads = %d / user_threads = %d / current = (%x,%x)\n", 359 local_cxy , core->lid, hal_time_stamp(), 360 sched->k_threads_nr, sched->u_threads_nr, 366 nolock_printk("\n***** scheduler state for core[%x,%d] / cycle %d / current = (%x,%x)\n", 367 local_cxy , core->lid, (uint32_t)hal_get_cycles(), 361 368 sched->current->process->pid , sched->current->trdid ); 362 369 -
trunk/kernel/kern/scheduler.h
r416 r428 59 59 60 60 /********************************************************************************************* 61 * This function register a new thread in a given core scheduler.61 * This function atomically register a new thread in a given core scheduler. 62 62 ********************************************************************************************* 63 63 * @ core : local pointer on the core descriptor. -
trunk/kernel/kern/thread.c
r418 r428 141 141 142 142 // register new thread in process descriptor, and get a TRDID 143 spinlock_lock( &process->th_lock );144 143 error = process_register_thread( process, thread , &trdid ); 145 spinlock_unlock( &process->th_lock );146 144 147 145 if( error ) … … 228 226 229 227 assert( (attr != NULL) , __FUNCTION__, "pthread attributes must be defined" ); 228 229 thread_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x\n", 230 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid ); 230 231 231 232 // get process descriptor local copy … … 290 291 vseg->min, 291 292 vseg->max - vseg->min ); 292 293 293 if( error ) 294 294 { … … 326 326 dqdt_local_update_threads( 1 ); 327 327 328 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / trdid = %x / process %x / core = %d\n", 329 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, 330 thread->trdid , process->pid , core_lid ); 328 thread_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / trdid = %x / core = %d\n", 329 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, thread->trdid, core_lid ); 331 330 332 331 *new_thread = thread; … … 371 370 372 371 // get relevant fields from parent thread 373 func = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func ));374 args = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args ));375 base = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base ));376 size = (uint32_t)hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->u_stack_size ));377 flags = hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->flags ));378 uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone ));372 func = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func )); 373 args = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args )); 374 base = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base )); 375 size = (uint32_t)hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->u_stack_size )); 376 flags = hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->flags )); 377 uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone_current )); 379 378 380 379 vpn_base = base >> CONFIG_PPM_PAGE_SHIFT; … … 419 418 420 419 // update uzone pointer in child thread descriptor 421 child_ptr->uzone = (char *)((intptr_t)uzone +422 (intptr_t)child_ptr -423 (intptr_t)parent_ptr );420 child_ptr->uzone_current = (char *)((intptr_t)uzone + 421 (intptr_t)child_ptr - 422 (intptr_t)parent_ptr ); 424 423 425 424 … … 515 514 thread_t * thread; // pointer on new thread descriptor 516 515 517 thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type % / cycle %d\n",516 thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type %s / cycle %d\n", 518 517 __FUNCTION__ , local_cxy , core_lid , thread_type_str( type ) , hal_time_stamp() ); 519 518 … … 615 614 if ( thread->type == THREAD_USER ) hal_fpu_context_destroy( thread ); 616 615 617 // release FPU if required 618 // TODO This should be done before calling thread_destroy() 616 // release FPU ownership if required 619 617 hal_disable_irq( &save_sr ); 620 618 if( core->fpu_owner == thread ) … … 626 624 627 625 // remove thread from process th_tbl[] 628 // TODO This should be done before calling thread_destroy() 629 ltid_t ltid = LTID_FROM_TRDID( thread->trdid ); 630 631 spinlock_lock( &process->th_lock ); 632 process->th_tbl[ltid] = XPTR_NULL; 633 process->th_nr--; 634 spinlock_unlock( &process->th_lock ); 626 process_remove_thread( thread ); 635 627 636 628 // update local DQDT … … 814 806 815 807 thread_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n", 816 __FUNCTION__, local_cxy, killer->trdid , target 808 __FUNCTION__, local_cxy, killer->trdid , target->trdid ); 817 809 818 810 // set the global blocked bit in target thread descriptor. … … 844 836 845 837 thread_dmsg("\n[DBG] %s : killer thread %x exit for target thread %x\n", 846 __FUNCTION__, local_cxy, killer->trdid , target 838 __FUNCTION__, local_cxy, killer->trdid , target->trdid ); 847 839 848 840 } // end thread_kill() -
trunk/kernel/kern/thread.h
r418 r428 73 73 #define THREAD_FLAG_SCHED 0x0004 /*! Scheduling required for this thread */ 74 74 #define THREAD_FLAG_REQ_ACK 0x0008 /*! Acknowledge required from scheduler */ 75 #define THREAD_FLAG_REQ_DELETE 0x0010 /*! Destruction required by scheduler*/75 #define THREAD_FLAG_REQ_DELETE 0x0010 /*! Destruction required from scheduler */ 76 76 77 77 /*************************************************************************************** … … 89 89 #define THREAD_BLOCKED_RPC 0x0200 /*! thread wait RPC completion */ 90 90 #define THREAD_BLOCKED_DEV_ISR 0x0400 /*! thread DEV wait ISR */ 91 #define THREAD_BLOCKED_WAIT 0x0800 /*! thread parent wait child termination */ 91 92 92 93 /*************************************************************************************** … … 123 124 * thread is registered in the local copy of the process descriptor. 124 125 * 125 * WARNING : Don't modify the first 3fields order, as this order is used by the126 * WARNING : Don't modify the first 4 fields order, as this order is used by the 126 127 * hal_kentry assembly code for the TSAR architecture. 127 128 **************************************************************************************/ … … 133 134 void * cpu_context; /*! pointer on CPU context switch */ 134 135 void * fpu_context; /*! pointer on FPU context switch */ 135 void * uzone; /*! used by hal_do_syscakl & hal_do_except */ 136 void * uzone_current; /*! used by hal_do_syscall & hal_do_except */ 137 void * uzone_previous; /*! used by hal_do_syscall & hal_do_except */ 136 138 137 139 intptr_t k_stack_base; /*! kernel stack base address */ … … 150 152 uint32_t remote_locks; /*! number of remote locks owned by thread */ 151 153 152 remote_spinlock_t *join_lock; /*! lock protecting the join/exit */154 remote_spinlock_t join_lock; /*! lock protecting the join/exit */ 153 155 void * join_value; /*! exit_value used in case of join */ 154 156 xptr_t join_xp; /*! extended pointer on joining thread */ … … 193 195 xlist_entry_t wait_list; /*! member of threads blocked on same cond */ 194 196 195 #if CONFIG_LOCKS_DEBUG196 197 list_entry_t locks_root; /*! root of list of locks taken */ 197 198 xlist_entry_t xlocks_root; /*! root of xlist of remote locks taken */ 198 #endif199 199 200 200 thread_info_t info; /*! embedded thread_info_t */
Note: See TracChangeset
for help on using the changeset viewer.