Changeset 23 for trunk/kernel/kern/process.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/process.c
r14 r23 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (2016 )6 * Alain Greiner (2016,2017) 7 7 * 8 8 * Copyright (c) UPMC Sorbonne Universites … … 47 47 #include <process.h> 48 48 #include <elf.h> 49 #include <syscalls.h> 49 50 50 51 ////////////////////////////////////////////////////////////////////////////////////////// … … 103 104 pid_t ppid ) 104 105 { 105 // reset signal manager TODO [AG] 106 107 // reset the file descriptors array 106 // reset reference process vmm 107 vmm_init( process ); 108 109 // reset reference process file descriptors array 108 110 process_fd_init( process ); 109 111 110 // reset the process files structures and cd_lock112 // reset reference process files structures and cd_lock 111 113 process->vfs_root_xp = XPTR_NULL; 114 process->vfs_bin_xp = XPTR_NULL; 112 115 process->vfs_cwd_xp = XPTR_NULL; 113 process->vfs_bin_xp = XPTR_NULL; 114 115 spinlock_init( &process->cd_lock ); 116 remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) ); 116 117 117 118 // reset children list root … … 119 120 process->children_nr = 0; 120 121 121 // reset semaphore list root122 // reset semaphore / mutex / barrier / condvar list roots 122 123 xlist_root_init( XPTR( local_cxy , &process->sem_root ) ); 123 process->sem_nr = 0; 124 xlist_root_init( XPTR( local_cxy , &process->mutex_root ) ); 125 xlist_root_init( XPTR( local_cxy , &process->barrier_root ) ); 126 xlist_root_init( XPTR( local_cxy , &process->condvar_root ) ); 127 remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) ); 124 128 125 129 // register new process in the parent children list … … 128 132 xlist_add_first( root , entry ); 129 133 130 // reset th_tbl[] array 134 // reset th_tbl[] array as empty 131 135 uint32_t i; 132 136 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ ) … … 137 141 spinlock_init( &process->th_lock ); 138 142 139 // reset process VMM140 memset( &process->vmm , 0 , sizeof(vmm_t) );141 142 143 // initialize PID and PPID 143 144 process->pid = pid; 144 145 process->ppid = ppid; 145 146 146 // set ref_xp field and is_ref flag 147 process->is_ref = true; 147 // set ref_xp field 148 148 process->ref_xp = XPTR( local_cxy , process ); 149 149 … … 153 153 // register new process descriptor in owner cluster manager copies_list 154 154 cluster_process_copies_link( process ); 155 156 // initalise signal manager TODO [AG] 155 157 156 158 hal_wbflush(); … … 162 164 xptr_t reference_process_xp ) 163 165 { 164 // replicate the remote process descriptor in new process descriptor 165 xptr_t local_process_xp = XPTR( local_cxy , local_process ); 166 hal_remote_memcpy( local_process_xp , reference_process_xp , sizeof(process_t) ); 167 168 // initalise signal manager TODO [AG] 169 170 // initialise file descriptors array TODO [AG] 171 172 // initialise process files structures TODO [AG] 173 174 // set the ref_xp field and clear the is_ref flag 166 // get reference process cluster and local pointer 167 cxy_t ref_cxy = GET_CXY( reference_process_xp ); 168 process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp ); 169 170 // reset local process vmm 171 vmm_init( local_process ); 172 173 // reset process file descriptors array 174 process_fd_init( local_process ); 175 176 // reset vfs_root_xp / vfs_bin_xp / vfs_cwd_xp fields 177 local_process->vfs_root_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) ); 178 local_process->vfs_bin_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) ); 179 local_process->vfs_cwd_xp = XPTR_NULL; 180 181 // set the pid, ppid, ref_xp fields 182 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) ); 183 local_process->ppid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) ); 175 184 local_process->ref_xp = reference_process_xp; 176 local_process->is_ref = false;177 185 178 186 // reset children list root (not used in a process descriptor copy) … … 185 193 // reset semaphores list root (not used in a process descriptor copy) 186 194 xlist_root_init( XPTR( local_cxy , &local_process->sem_root ) ); 187 local_process->sem_nr = 0; 188 189 // initialize th_tbl[] array as empty 195 xlist_root_init( XPTR( local_cxy , &local_process->mutex_root ) ); 196 xlist_root_init( XPTR( local_cxy , &local_process->barrier_root ) ); 197 xlist_root_init( XPTR( local_cxy , &local_process->condvar_root ) ); 198 199 // reset th_tbl[] array as empty 190 200 uint32_t i; 191 201 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ ) … … 196 206 spinlock_init( &local_process->th_lock ); 197 207 198 // initialise process VMM TODO [AG]199 200 208 // register new process descriptor in local cluster manager local_list 201 209 cluster_process_local_link( local_process ); … … 203 211 // register new process descriptor in owner cluster manager copies_list 204 212 cluster_process_copies_link( local_process ); 213 214 // initalise signal manager TODO [AG] 205 215 206 216 hal_wbflush(); … … 223 233 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 224 234 235 // get the lock protecting the list of local process descriptors 236 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) ); 237 225 238 // remove the process descriptor from local_list in local cluster manager 226 spinlock_lock( &pmgr->local_lock );227 239 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); 228 spinlock_unlock( &pmgr->local_lock ); 240 241 // release the lock protecting the list of local process descriptors 242 remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) ); 229 243 230 244 // get extended pointer on copies_lock in owner cluster manager … … 243 257 // From this point, the process descriptor is unreachable 244 258 259 // close all open files and update dirty TODO [AG] 260 245 261 // release signal manager TODO [AG] 246 262 247 // delete all open file descriptors 248 process_fd_destroy( process ); 249 250 // Close bin file and decrease refcount for root and cwd 251 if( process->vfs_bin_xp != XPTR_NULL ) vfs_close( process->vfs_bin_xp , NULL ); 263 // Decrease refcount for bin file, root file and cwd file 264 vfs_file_count_down( process->vfs_bin_xp ); 252 265 vfs_file_count_down( process->vfs_root_xp ); 253 266 vfs_file_count_down( process->vfs_cwd_xp ); … … 325 338 326 339 327 328 329 330 340 /////////////////////////////////////////////// 331 341 process_t * process_get_local_copy( pid_t pid ) 332 342 { 333 343 error_t error; 334 bool_t found;335 list_entry_t * iter;336 p rocess_t * process; // pointer on local copy344 process_t * process_ptr; // local pointer on process 345 xptr_t process_xp; // extended pointer on process 346 pid_t process_pid; // process identifier 337 347 338 348 cluster_t * cluster = LOCAL_CLUSTER; 339 349 340 350 // get lock protecting local list of processes 341 spinlock_lock( &cluster->pmgr.local_lock);351 remote_spinlock_lock( XPTR( local_cxy , &cluster->pmgr.local_lock ) ); 342 352 343 353 // scan the local list of process descriptors to find the process 344 found = false; 345 LIST_FOREACH( &cluster->pmgr.local_root , iter ) 346 { 347 process = LIST_ELEMENT( iter , process_t , local_list ); 348 if( process->pid == pid ) 354 xptr_t iter; 355 bool_t found = false; 356 XLIST_FOREACH( XPTR( local_cxy , &cluster->pmgr.local_root ) , iter ) 357 { 358 process_xp = XLIST_ELEMENT( iter , process_t , local_list ); 359 process_ptr = (process_t *)GET_PTR( process_xp ); 360 process_pid = hal_remote_lw( XPTR( local_cxy , &process_ptr->pid ) ); 361 if( process_ptr->pid == pid ) 349 362 { 350 363 found = true; … … 354 367 355 368 // release lock protecting local list of processes 356 spinlock_unlock( &cluster->pmgr.local_lock);357 358 // allocate memory for a local process descriptor359 // and initialise it from reference if required369 remote_spinlock_unlock( XPTR( local_cxy , &cluster->pmgr.local_lock ) ); 370 371 // allocate memory for a new local process descriptor 372 // and initialise it from reference cluster if required 360 373 if( !found ) 361 374 { 362 375 // get extended pointer on reference process descriptor 363 xptr_t reference = cluster_get_reference_process_from_pid( pid ); 376 xptr_t ref_xp = cluster_get_reference_process_from_pid( pid ); 377 378 assert( (ref_xp != XPTR_NULL) , __FUNCTION__ , "illegal pid\n" ); 364 379 365 380 // allocate memory for local process descriptor 366 process = process_alloc();367 if( process == NULL ) return NULL;381 process_ptr = process_alloc(); 382 if( process_ptr == NULL ) return NULL; 368 383 369 384 // initialize local process descriptor copy 370 error = process_copy_init( process , reference);385 error = process_copy_init( process_ptr , ref_xp ); 371 386 if( error ) return NULL; 372 373 374 // register process in global copies_list 375 } 376 377 return process; 387 } 388 389 return process_ptr; 378 390 } // end process_get_local_copy() 379 391 … … 389 401 390 402 remote_spinlock_init( XPTR( local_cxy , &process->fd_array.lock ) ); 391 process->fd_array.max = CONFIG_PROCESS_FILE_MAX_NR; 392 process->fd_array.current 403 404 process->fd_array.current = 0; 393 405 394 406 // initialize array 395 for ( fd = 0 ; fd < process->fd_array.max; fd++ )407 for ( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ ) 396 408 { 397 409 process->fd_array.array[fd] = XPTR_NULL; … … 399 411 } 400 412 401 ////////////////////////////////////////////// 402 void process_fd_destroy( process_t * process ) 403 { 404 uint32_t fd; 405 406 // loop on all open file descriptors to close all open files 407 for( fd = 0 ; fd < process->fd_array.max ; fd++ ) 408 { 409 xptr_t file_xp = process->fd_array.array[fd]; 410 if ( file_xp != XPTR_NULL ) vfs_close( file_xp , NULL ); 411 } 413 414 ////////////////////////////// 415 bool_t process_fd_array_full() 416 { 417 // get extended pointer on reference process 418 xptr_t ref_xp = CURRENT_THREAD->process->ref_xp; 419 420 // get reference process cluster and local pointer 421 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 422 cxy_t ref_cxy = GET_CXY( ref_xp ); 423 424 // get number of open file descriptors from reference fd_array 425 uint32_t current = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->fd_array.current ) ); 426 427 return ( current >= CONFIG_PROCESS_FILE_MAX_NR ); 412 428 } 413 429 414 ///////////////////////////////////////////////////415 bool_t process_fd_array_full( process_t * process )416 {417 return ( process->fd_array.current >= process->fd_array.max);418 }419 420 430 ///////////////////////////////////////////////// 421 error_t process_fd_allocate( process_t * process, 422 xptr_t file_xp, 423 uint32_t * ret_fd ) 431 error_t process_fd_register( xptr_t file_xp, 432 uint32_t * file_id ) 424 433 { 425 434 bool_t found; 426 uint32_t fd; 427 428 remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) ); 435 uint32_t id; 436 xptr_t xp; 437 438 // get extended pointer on reference process 439 xptr_t ref_xp = CURRENT_THREAD->process->ref_xp; 440 441 // get reference process cluster and local pointer 442 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 443 cxy_t ref_cxy = GET_CXY( ref_xp ); 444 445 // take lock protecting reference fd_array 446 remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) ); 429 447 430 448 found = false; 431 449 432 for ( fd = 0; fd < process->fd_array.max; fd++ ) 433 { 434 if ( process->fd_array.array[fd] == XPTR_NULL ) 450 for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ ) 451 { 452 xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) ); 453 if ( xp == XPTR_NULL ) 435 454 { 436 455 found = true; 437 process->fd_array.array[fd] = file_xp;438 process->fd_array.current++;439 * ret_fd = fd;456 hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp ); 457 hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 ); 458 *file_id = id; 440 459 break; 441 460 } 442 461 } 443 462 444 remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) ); 463 // release lock protecting reference fd_array 464 remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) ); 445 465 446 466 if ( !found ) return EMFILE; 447 467 else return 0; 448 } 449 450 //////////////////////////////////////////////// 451 error_t process_fd_release( process_t * process, 452 uint32_t fd ) 453 { 454 if ( (fd < 0) || (fd > process->fd_array.max) ) return EBADF; 455 456 remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) ); 457 458 process->fd_array.array[fd] = XPTR_NULL; 459 process->fd_array.current--; 460 461 remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) ); 462 463 return 0; 464 } 465 466 /////////////////////////////////////// 467 void process_fd_copy( fd_array_t * dst, 468 fd_array_t * src ) 469 { 470 uint32_t fd; 471 xptr_t entry; 472 473 remote_spinlock_lock( XPTR( local_cxy , &src->lock ) ); 474 475 // loop on all entries in source process fd_array 476 for( fd = 0 ; fd < src->max ; fd++ ) 477 { 478 entry = src->array[fd]; 479 480 if( entry != XPTR_NULL ) 481 { 482 // increment file descriptor ref count 483 vfs_file_count_up( entry ); 484 485 // copy entry in destination process fd_array 486 dst->array[fd] = entry; 487 } 488 } 489 490 // release lock on source process fd_array 491 remote_spinlock_unlock( XPTR( local_cxy , &src->lock ) ); 492 } 468 469 } // end process_fd_register() 470 471 //////////////////////////////////////////////// 472 xptr_t process_fd_get_xptr( process_t * process, 473 uint32_t file_id ) 474 { 475 xptr_t file_xp; 476 477 // access local copy of process descriptor 478 file_xp = process->fd_array.array[file_id]; 479 480 if( file_xp == XPTR_NULL ) 481 { 482 // get reference process cluster and local pointer 483 xptr_t ref_xp = process->ref_xp; 484 cxy_t ref_cxy = GET_CXY( ref_xp ); 485 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 486 487 // access reference process descriptor 488 file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[file_id] ) ); 489 490 // update local fd_array if found 491 if( file_xp != XPTR_NULL ) 492 { 493 process->fd_array.array[file_id] = file_xp; 494 } 495 } 496 497 return file_xp; 498 499 } // end process_fd_get_xptr() 493 500 494 501 /////////////////////////////////////////// … … 510 517 remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) ); 511 518 512 // get number of entries in fd_array513 uint32_t max = hal_remote_lw( XPTR( src_cxy , &src_ptr->max ) );514 515 519 // loop on all entries in source process fd_array 516 for( fd = 0 ; fd < max; fd++ )520 for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ ) 517 521 { 518 522 entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) ); … … 609 613 pid = exec_info->pid; 610 614 611 if( CXY_FROM_PID( pid ) != local_cxy ) 612 { 613 printk("\n[PANIC] in %s : illegal process PID %x in cluster %x\n", 614 __FUNCTION__ , pid , local_cxy ); 615 hal_core_sleep(); 616 } 615 assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , "illegal PID\n" ); 617 616 618 617 exec_dmsg("\n[INFO] %s enters in cluster %x for process %x / path = %s\n", … … 677 676 } 678 677 679 // create "stack" vseg descriptor for associated main thread680 vseg_t * stack_vseg = vmm_create_vseg( process,681 0, // base defined by VMM682 0, // size defined by VMM683 VSEG_TYPE_STACK );684 if( stack_vseg == NULL )685 {686 printk("\n[ERROR] in %s : cannot create stack vseg for process %x / path = %s\n",687 __FUNCTION__, pid , path );688 process_destroy( process );689 return error;690 }691 692 678 // select a core in cluster 693 679 lid = cluster_select_local_core(); … … 695 681 696 682 // initialize pthread attributes for main thread 697 attr.pid = pid; 698 attr.entry_func = (void*)process->vmm.entry_point; 699 attr.entry_args = exec_info->args_pointers; 700 attr.flags = PT_FLAG_DETACH; // main thread always detached 701 attr.cxy = local_cxy; 702 attr.lid = lid; 703 704 // create and initialise thread descriptor, link thread & process 705 error = thread_user_create( &thread, 683 attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED; 684 attr.cxy = local_cxy; 685 attr.lid = lid; 686 687 // create and initialise thread descriptor 688 error = thread_user_create( pid, 689 (void *)process->vmm.entry_point, 690 exec_info->args_pointers, 706 691 &attr, 707 stack_vseg->min, 708 stack_vseg->max - stack_vseg->min ); 692 &thread ); 709 693 if( error ) 710 694 { … … 732 716 { 733 717 process_t * process_init; // process_init descriptor 734 thread_t * thread_init; // process_init main thread descriptor735 718 pid_t init_pid; // process_init pid 736 719 exec_info_t exec_info; // structure to be passed to process_make_exec() … … 779 762 process_zero.children_nr = 1; 780 763 781 // TODO open stdin / stdout / stderr pseudo-files 782 xptr_t stdin_xp; 783 xptr_t stdout_xp; 784 xptr_t stderr_xp; 785 786 // error1 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_RDONLY, &stdin_xp ); 787 // error2 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stdout_xp ); 788 // error3 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stderr_xp ); 764 // TODO create inodes for stdin / stdout / stderr pseudo-files 765 // these inodes should be created in the cluster containing the relevant TXT chdev 766 767 // open stdin / stdout / stderr pseudo-files 768 xptr_t stdin_xp; 769 xptr_t stdout_xp; 770 xptr_t stderr_xp; 771 uint32_t stdin_id; 772 uint32_t stdout_id; 773 uint32_t stderr_id; 774 775 error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id ); 776 error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id ); 777 error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id ); 789 778 790 779 if( error1 || error2 || error3 ) 791 780 { 792 if( !error1 ) vfs_close( stdin_xp , NULL);793 if( !error2 ) vfs_close( stdout_xp , NULL);794 if( !error3 ) vfs_close( stderr_xp , NULL);781 if( !error1 ) vfs_close( stdin_xp , stdin_id ); 782 if( !error2 ) vfs_close( stdout_xp , stdout_id ); 783 if( !error3 ) vfs_close( stderr_xp , stderr_id ); 795 784 796 785 printk("\n[PANIC] in %s : cannot open stdin/stdout/stderr in cluster %x\n", … … 799 788 } 800 789 801 // register stdin / stdout / stderr in the fd_array 3 first slots 802 process_init->fd_array.array[0] = stdin_xp; 803 process_init->fd_array.array[1] = stdout_xp; 804 process_init->fd_array.array[2] = stderr_xp; 805 process_init->fd_array.current = 3; 790 // check stdin / stdout / stderr indexes 791 if( (stdin_id != 0) || (stdout_id != 1) || (stderr_id != 2) ) 792 { 793 printk("\n[PANIC] in %s : bad indexes for stdin/stdout/stderr in cluster %x\n", 794 __FUNCTION__ , local_cxy ); 795 hal_core_sleep(); 796 } 806 797 807 798 // initialize the exec_info structure
Note: See TracChangeset
for help on using the changeset viewer.