Changeset 428 for trunk/kernel/kern/process.c
- Timestamp:
- Jan 29, 2018, 6:08:07 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note: See TracChangeset
for help on using the changeset viewer.