Changeset 457 for trunk/kernel/kern/process.c
- Timestamp:
- Aug 2, 2018, 11:47:13 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/process.c
r450 r457 25 25 26 26 #include <kernel_config.h> 27 #include <hal_ types.h>27 #include <hal_kernel_types.h> 28 28 #include <hal_remote.h> 29 29 #include <hal_uspace.h> … … 89 89 void process_reference_init( process_t * process, 90 90 pid_t pid, 91 xptr_t parent_xp, 92 xptr_t model_xp ) 91 xptr_t parent_xp ) 93 92 { 94 93 cxy_t parent_cxy; 95 94 process_t * parent_ptr; 96 cxy_t model_cxy;97 process_t * model_ptr;98 95 xptr_t stdin_xp; 99 96 xptr_t stdout_xp; … … 110 107 chdev_t * chdev_ptr; 111 108 cxy_t chdev_cxy; 112 pid_t model_pid;113 109 pid_t parent_pid; 114 115 // get model process cluster and local pointer116 model_cxy = GET_CXY( model_xp );117 model_ptr = GET_PTR( model_xp );118 110 119 111 // get parent process cluster and local pointer … … 121 113 parent_ptr = GET_PTR( parent_xp ); 122 114 123 // get model_pid andparent_pid115 // get parent_pid 124 116 parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 125 model_pid = hal_remote_lw( XPTR( model_cxy , &model_ptr->pid ) );126 117 127 118 #if DEBUG_PROCESS_REFERENCE_INIT 128 119 uint32_t cycle = (uint32_t)hal_get_cycles(); 129 120 if( DEBUG_PROCESS_REFERENCE_INIT ) 130 printk("\n[DBG] %s : thread %x enter / pid = %x / ppid = %x / model_pid =%x / cycle %d\n",131 __FUNCTION__ , CURRENT_THREAD , pid , parent_pid , model_pid , cycle );121 printk("\n[DBG] %s : thread %x in process %x enter to initalialize process %x / cycle %d\n", 122 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid , pid , cycle ); 132 123 #endif 133 124 … … 146 137 cycle = (uint32_t)hal_get_cycles(); 147 138 if( DEBUG_PROCESS_REFERENCE_INIT ) 148 printk("\n[DBG] %s : thread %x / vmm empty for process %x / cycle %d\n",149 __FUNCTION__ , CURRENT_THREAD ,pid , cycle );139 printk("\n[DBG] %s : thread %x in process %x / vmm empty for process %x / cycle %d\n", 140 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid , cycle ); 150 141 #endif 151 142 … … 154 145 155 146 // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal. 156 // - if INIT (pid == 1) => link to kernel TXT[0] 157 // - if KSH[i] (model_pid == 1) => allocate a free TXT[i] 158 // - if USER process => same terminal as model 159 160 if( (pid == 1) || (model_pid == 1)) // INIT or KSH process 161 { 162 if (pid == 1 ) txt_id = 0; // INIT 163 else txt_id = process_txt_alloc(); // KSH[i] 164 165 // attach process to TXT[txt_id] 147 if( (pid == 1) || (parent_pid == 1)) // INIT or KSH process 148 { 149 // allocate a TXT channel 150 if( pid == 1 ) txt_id = 0; // INIT 151 else txt_id = process_txt_alloc(); // KSH 152 153 // attach process to TXT 166 154 process_txt_attach( process , txt_id ); 155 156 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) 157 cycle = (uint32_t)hal_get_cycles(); 158 if( DEBUG_PROCESS_REFERENCE_INIT ) 159 printk("\n[DBG] %s : thread %x in process %x / process %x attached to TXT%d / cycle %d\n", 160 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, txt_id, cycle ); 161 #endif 162 163 167 164 168 165 // build path to TXT_RX[i] and TXT_TX[i] chdevs … … 184 181 cycle = (uint32_t)hal_get_cycles(); 185 182 if( DEBUG_PROCESS_REFERENCE_INIT ) 186 printk("\n[DBG] %s : thread %x / stdin open for process %x / cycle %d\n",187 __FUNCTION__ , CURRENT_THREAD , pid, cycle );183 printk("\n[DBG] %s : thread %x in process %x / stdin open for process %x / cycle %d\n", 184 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle ); 188 185 #endif 189 186 … … 202 199 cycle = (uint32_t)hal_get_cycles(); 203 200 if( DEBUG_PROCESS_REFERENCE_INIT ) 204 printk("\n[DBG] %s : thread %x / stdout open for process %x / cycle %d\n",205 __FUNCTION__ , CURRENT_THREAD , pid, cycle );201 printk("\n[DBG] %s : thread %x in process %x / stdout open for process %x / cycle %d\n", 202 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle ); 206 203 #endif 207 204 … … 220 217 cycle = (uint32_t)hal_get_cycles(); 221 218 if( DEBUG_PROCESS_REFERENCE_INIT ) 222 printk("\n[DBG] %s : thread %x / stderr open for process %x / cycle %d\n",223 __FUNCTION__ , CURRENT_THREAD , pid, cycle );219 printk("\n[DBG] %s : thread %x in process %x / stderr open for process %x / cycle %d\n", 220 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle ); 224 221 #endif 225 222 … … 227 224 else // normal user process 228 225 { 229 // get extended pointer on stdin pseudo file in modelprocess230 file_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy , &model_ptr->fd_array.array[0] ) );231 232 // get extended pointer on modelprocess TXT chdev226 // get extended pointer on stdin pseudo file in parent process 227 file_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy , &parent_ptr->fd_array.array[0] ) ); 228 229 // get extended pointer on parent process TXT chdev 233 230 chdev_xp = chdev_from_file( file_xp ); 234 231 … … 243 240 process_txt_attach( process , txt_id ); 244 241 245 // copy all open files from modelprocess fd_array to this process242 // copy all open files from parent process fd_array to this process 246 243 process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ), 247 XPTR( model_cxy , &model_ptr->fd_array ) );244 XPTR( parent_cxy , &parent_ptr->fd_array ) ); 248 245 } 249 246 250 247 // initialize specific inodes root and cwd 251 process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy,252 & model_ptr->vfs_root_xp ) );253 process->vfs_cwd_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy,254 & model_ptr->vfs_cwd_xp ) );248 process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy, 249 &parent_ptr->vfs_root_xp ) ); 250 process->vfs_cwd_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy, 251 &parent_ptr->vfs_cwd_xp ) ); 255 252 vfs_inode_remote_up( process->vfs_root_xp ); 256 253 vfs_inode_remote_up( process->vfs_cwd_xp ); … … 469 466 //////////////////////////////////////// 470 467 void process_sigaction( pid_t pid, 471 uint32_t action_type )468 uint32_t type ) 472 469 { 473 470 cxy_t owner_cxy; // owner cluster identifier … … 479 476 xptr_t process_xp; // extended pointer on process copy 480 477 cxy_t process_cxy; // process copy cluster identifier 478 process_t * process_ptr; // local pointer on process copy 481 479 reg_t save_sr; // for critical section 482 480 rpc_desc_t rpc; // shared RPC descriptor 483 484 thread_t * client = CURRENT_THREAD; 481 thread_t * client; // pointer on client thread 482 xptr_t client_xp; // extended pointer on client thread 483 process_t * local; // pointer on process copy in local cluster 484 uint32_t remote_nr; // number of remote process copies 485 486 client = CURRENT_THREAD; 487 client_xp = XPTR( local_cxy , client ); 488 local = NULL; 489 remote_nr = 0; 485 490 486 491 #if DEBUG_PROCESS_SIGACTION 487 492 uint32_t cycle = (uint32_t)hal_get_cycles(); 488 493 if( DEBUG_PROCESS_SIGACTION < cycle ) 489 printk("\n[DBG] %s : thread %x enter to %s process %x / cycle %d\n", 490 __FUNCTION__ , client, process_action_str( action_type ) , pid , cycle ); 494 printk("\n[DBG] %s : thread %x in process %x enter to %s process %x / cycle %d\n", 495 __FUNCTION__ , client->trdid, client->process->pid, 496 process_action_str( type ) , pid , cycle ); 491 497 #endif 492 498 … … 503 509 504 510 // check action type 505 assert( (( action_type == DELETE_ALL_THREADS ) ||506 ( action_type == BLOCK_ALL_THREADS ) ||507 ( action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );511 assert( ((type == DELETE_ALL_THREADS ) || 512 (type == BLOCK_ALL_THREADS ) || 513 (type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" ); 508 514 509 // allocate a - shared - RPC descriptor in client thread stack 510 // it can be shared because all parallel, non-blocking, server threads 511 // use the same input arguments, and use the shared RPC response field 512 513 // the client thread makes the following sequence: 514 // 1. mask interrupts 515 // 2. block itself 516 // 3. send RPC requests to all copies 517 // 4. unmask interrupts 518 // 5. deschedule 515 516 // The client thread send parallel RPCs to all remote clusters containing 517 // target process copies, wait all responses, and then handles directly the 518 // threads in local cluster, when required. 519 // The client thread allocates a - shared - RPC descriptor in the stack, 520 // because all parallel, non-blocking, server threads use the same input 521 // arguments, and use the shared RPC response field 519 522 520 523 // mask IRQs 521 524 hal_disable_irq( &save_sr); 522 525 523 // client register blocking condition foritself524 thread_block( XPTR( local_cxy , client ), THREAD_BLOCKED_RPC );526 // client thread blocks itself 527 thread_block( client_xp , THREAD_BLOCKED_RPC ); 525 528 526 529 // take the lock protecting the copies … … 533 536 rpc.thread = client; 534 537 rpc.lid = client->core->lid; 535 rpc.args[0] = action_type;538 rpc.args[0] = type; 536 539 rpc.args[1] = pid; 537 540 538 // send RPCs to all clusters containing process copiess 541 // scan list of process copies 542 // to send RPCs to remote copies 539 543 XLIST_FOREACH( root_xp , iter_xp ) 540 544 { 541 // atomically increment responses counter 542 hal_atomic_add( (void *)&rpc.responses , 1 ); 543 545 // get extended pointers and cluster on process 544 546 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 545 547 process_cxy = GET_CXY( process_xp ); 548 process_ptr = GET_PTR( process_xp ); 549 550 if( process_cxy == local_cxy ) // process is local 551 { 552 local = process_ptr; 553 } 554 else // process is remote 555 { 556 // update number of remote process copies 557 remote_nr++; 558 559 // atomically increment responses counter 560 hal_atomic_add( (void *)&rpc.responses , 1 ); 546 561 547 562 #if DEBUG_PROCESS_SIGACTION 548 563 if( DEBUG_PROCESS_SIGACTION < cycle ) 549 printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n", 550 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy ); 551 #endif 552 // call RPC in target cluster 553 rpc_process_sigaction_client( process_cxy , &rpc ); 554 } 555 564 printk("\n[DBG] %s : thread %x in process %x handles remote process %x in cluster %x\n", 565 __FUNCTION__, client->trdid, client->process->pid, pid , process_cxy ); 566 #endif 567 // call RPC in target cluster 568 rpc_process_sigaction_client( process_cxy , &rpc ); 569 } 570 } // end list of copies 571 556 572 // release the lock protecting process copies 557 573 remote_spinlock_unlock( lock_xp ); … … 560 576 hal_restore_irq( save_sr); 561 577 562 // client thread deschedule : will be unblocked by the last RPC server thread 563 sched_yield("blocked on rpc_process_sigaction"); 578 // - if there is remote process copies, the client thread deschedules, 579 // (it will be unblocked by the last RPC server thread). 580 // - if there is no remote copies, the client thread unblock itself. 581 if( remote_nr ) 582 { 583 sched_yield("blocked on rpc_process_sigaction"); 584 } 585 else 586 { 587 thread_unblock( client_xp , THREAD_BLOCKED_RPC ); 588 } 589 590 // handle the local process copy if required 591 if( local != NULL ) 592 { 593 594 #if DEBUG_PROCESS_SIGACTION 595 if( DEBUG_PROCESS_SIGACTION < cycle ) 596 printk("\n[DBG] %s : thread %x in process %x handles local process %x in cluster %x\n", 597 __FUNCTION__, client->trdid, client->process->pid, pid , local_cxy ); 598 #endif 599 if (type == DELETE_ALL_THREADS ) process_delete_threads ( local , client_xp ); 600 else if(type == BLOCK_ALL_THREADS ) process_block_threads ( local , client_xp ); 601 else if(type == UNBLOCK_ALL_THREADS ) process_unblock_threads( local ); 602 } 564 603 565 604 #if DEBUG_PROCESS_SIGACTION 566 605 cycle = (uint32_t)hal_get_cycles(); 567 606 if( DEBUG_PROCESS_SIGACTION < cycle ) 568 printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n", 569 __FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle ); 607 printk("\n[DBG] %s : thread %x in process %x exit after %s process %x / cycle %d\n", 608 __FUNCTION__, client->trdid, client->process->pid, 609 process_action_str( type ), pid, cycle ); 570 610 #endif 571 611 … … 1100 1140 uint32_t cycle = (uint32_t)hal_get_cycles(); 1101 1141 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1102 printk("\n[DBG] %s : thread %x enter for process %x/ cluster %x / cycle %d\n",1103 __FUNCTION__, CURRENT_THREAD , parent_pid, local_cxy, cycle );1142 printk("\n[DBG] %s : thread %x in process %x enter / cluster %x / cycle %d\n", 1143 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, local_cxy, cycle ); 1104 1144 #endif 1105 1145 … … 1123 1163 } 1124 1164 1165 #if DEBUG_PROCESS_MAKE_FORK 1166 cycle = (uint32_t)hal_get_cycles(); 1167 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1168 printk("\n[DBG] %s : thread %x in process %x allocated process %x / cycle %d\n", 1169 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle ); 1170 #endif 1171 1125 1172 // initializes child process descriptor from parent process descriptor 1126 1173 process_reference_init( process, 1127 1174 new_pid, 1128 parent_process_xp,1129 1175 parent_process_xp ); 1130 1176 … … 1132 1178 cycle = (uint32_t)hal_get_cycles(); 1133 1179 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1134 printk("\n[DBG] %s : thread %x created child_process %x / child_pid %x / cycle %d\n", 1135 __FUNCTION__, CURRENT_THREAD, process, new_pid, cycle ); 1136 #endif 1180 printk("\n[DBG] %s : thread %x in process %x initialized child_process %x / cycle %d\n", 1181 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle ); 1182 #endif 1183 1184 // give TXT ownership to child process 1185 process_txt_set_ownership( XPTR( local_cxy , process ) ); 1137 1186 1138 1187 // copy VMM from parent descriptor to child descriptor … … 1151 1200 cycle = (uint32_t)hal_get_cycles(); 1152 1201 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1153 printk("\n[DBG] %s : thread %x copied VMM from parent %x to child %x / cycle %d\n", 1154 __FUNCTION__ , CURRENT_THREAD , parent_pid, new_pid, cycle ); 1155 #endif 1202 printk("\n[DBG] %s : thread %x in process %x copied VMM from parent %x to child %x / cycle %d\n", 1203 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1204 parent_pid, new_pid, cycle ); 1205 #endif 1206 1207 // parent process gives TXT ownership to child process if required 1208 if( process_txt_is_owner(parent_process_xp) ) 1209 { 1210 process_txt_set_ownership( XPTR( local_cxy , process ) ); 1211 1212 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1213 cycle = (uint32_t)hal_get_cycles(); 1214 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1215 printk("\n[DBG] %s : thread %x in process %x gives TXT from parent %x to child %x / cycle %d\n", 1216 __FUNCTION__ , CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1217 parent_pid, new_pid, cycle ); 1218 #endif 1219 1220 } 1156 1221 1157 1222 // update extended pointer on .elf file … … 1178 1243 cycle = (uint32_t)hal_get_cycles(); 1179 1244 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1180 printk("\n[DBG] %s : thread %x created child thread %x on core[%x,%d] / cycle %d\n", 1181 __FUNCTION__ , CURRENT_THREAD, thread, local_cxy, thread->core->lid, cycle ); 1245 printk("\n[DBG] %s : thread %x in process %x created main thread %x on core[%x,%d] / cycle %d\n", 1246 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1247 thread, local_cxy, thread->core->lid, cycle ); 1182 1248 #endif 1183 1249 … … 1200 1266 cycle = (uint32_t)hal_get_cycles(); 1201 1267 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1202 printk("\n[DBG] %s : thread %x set COW in parent and child / cycle %d\n",1203 __FUNCTION__ , CURRENT_THREAD, cycle );1268 printk("\n[DBG] %s : thread %x in process %x set COW in parent and child / cycle %d\n", 1269 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle ); 1204 1270 #endif 1205 1271 … … 1222 1288 cycle = (uint32_t)hal_get_cycles(); 1223 1289 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1224 printk("\n[DBG] %s : thread %x exit/ cycle %d\n",1225 __FUNCTION__, CURRENT_THREAD , cycle );1290 printk("\n[DBG] %s : thread %x in process %x exit / created process %x / cycle %d\n", 1291 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle ); 1226 1292 #endif 1227 1293 … … 1229 1295 1230 1296 } // end process_make_fork() 1231 1232 1297 1233 1298 ///////////////////////////////////////////////////// 1234 1299 error_t process_make_exec( exec_info_t * exec_info ) 1235 1300 { 1236 char * path; // pathname to .elf file 1237 pid_t pid; // old_process PID, given to new_process 1238 pid_t temp_pid; // temporary PID / given to old_process 1239 process_t * old_process; // local pointer on old process 1240 thread_t * old_thread; // local pointer on old thread 1241 process_t * new_process; // local pointer on new process 1242 thread_t * new_thread; // local pointer on new thread 1243 xptr_t parent_xp; // extended pointer on parent process 1244 process_t * parent_ptr; // local pointer on parent process 1245 cxy_t parent_cxy; // parent process cluster identifier 1246 xptr_t children_lock_xp; // extended pointer on children lock in parent 1247 xptr_t children_root_xp; // extended pointer on children root in parent 1248 xptr_t children_nr_xp; // extended pointer on children number in parent 1249 thread_t * parent_main_ptr; // local pointer on parent main thread 1250 xptr_t parent_main_xp; // extended pointer on parent main thread 1251 pthread_attr_t attr; // new thread attributes 1252 lid_t lid; // selected core local index 1301 thread_t * thread; // local pointer on this thread 1302 process_t * process; // local pointer on this process 1303 pid_t pid; // this process identifier 1253 1304 error_t error; // value returned by called functions 1254 1255 // get old_thread, old_process & PID1256 old_thread = CURRENT_THREAD;1257 old_process = old_thread->process;1258 pid = old_process->pid;1259 1260 // get .elf pathname from exec_info 1261 path = exec_info->path;1262 1263 // this function must be executed by a thread running in owner cluster1264 assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__, 1265 "local_cluster must be owner_cluster\n" ); 1266 1267 a ssert( (LTID_FROM_TRDID( old_thread->trdid ) == 0) , __FUNCTION__,1268 "must be called by the main thread\n" );1269 1305 char * path; // path to .elf file 1306 xptr_t file_xp; // extended pointer on .elf file descriptor 1307 uint32_t file_id; // file index in fd_array 1308 uint32_t args_nr; // number of main thread arguments 1309 char ** args_pointers; // array of pointers on main thread arguments 1310 1311 // get thread, process & PID 1312 thread = CURRENT_THREAD; 1313 process = thread->process; 1314 pid = process->pid; 1315 1316 // get relevant infos from exec_info 1317 path = exec_info->path; 1318 args_nr = exec_info->args_nr; 1319 args_pointers = exec_info->args_pointers; 1320 1270 1321 #if DEBUG_PROCESS_MAKE_EXEC 1271 1322 uint32_t cycle = (uint32_t)hal_get_cycles(); 1272 1323 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1273 1324 printk("\n[DBG] %s : thread %x in process %x enters / path %s / cycle %d\n", 1274 __FUNCTION__, old_thread->trdid, pid, path, cycle ); 1275 #endif 1276 1277 // get parent process pointers 1278 parent_xp = old_process->parent_xp; 1279 parent_cxy = GET_CXY( parent_xp ); 1280 parent_ptr = GET_PTR( parent_xp ); 1281 1325 __FUNCTION__, thread->trdid, pid, path, cycle ); 1326 #endif 1327 1328 // open the file identified by <path> 1329 file_xp = XPTR_NULL; 1330 file_id = -1; 1331 error = vfs_open( process, 1332 path, 1333 O_RDONLY, 1334 0, 1335 &file_xp, 1336 &file_id ); 1337 if( error ) 1338 { 1339 printk("\n[ERROR] in %s : failed to open file <%s>\n", __FUNCTION__ , path ); 1340 return -1; 1341 } 1342 1282 1343 #if (DEBUG_PROCESS_MAKE_EXEC & 1) 1283 1344 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1284 printk("\n[DBG] %s : thread %x in process %x get parent process %x in cluster %x\n", 1285 __FUNCTION__, old_thread->trdid, pid, parent_ptr, parent_cxy ); 1286 #endif 1287 1288 // get extended pointers on parent children_root, children_lock and children_nr 1289 children_root_xp = XPTR( parent_cxy , &parent_ptr->children_root ); 1290 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock ); 1291 children_nr_xp = XPTR( parent_cxy , &parent_ptr->children_nr ); 1292 1293 // get pointers on the parent process main thread 1294 parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[0] ) ); 1295 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 1296 1297 // allocate memory for new_process descriptor 1298 new_process = process_alloc(); 1299 1300 if( new_process == NULL ) 1301 { 1302 printk("\n[ERROR] in %s : cannot allocate process for %s\n", __FUNCTION__ , path ); 1345 printk("\n[DBG] %s : open file <%s>\n", __FUNCTION__, path ); 1346 #endif 1347 1348 // delete all threads other than this main thread in all clusters 1349 process_sigaction( pid , DELETE_ALL_THREADS ); 1350 1351 // reset local process VMM 1352 vmm_destroy( process ); 1353 1354 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1355 cycle = (uint32_t)hal_get_cycles(); 1356 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1357 printk("\n[DBG] %s : thread %x in process %x / reset VMM / cycle %d\n", 1358 __FUNCTION__, thread->trdid, pid, cycle ); 1359 #endif 1360 1361 // re-initialize the VMM (kentry/args/envs vsegs registration) 1362 error = vmm_init( process ); 1363 if( error ) 1364 { 1365 printk("\n[ERROR] in %s : cannot initialise VMM for %s\n", __FUNCTION__ , path ); 1366 vfs_close( file_xp , file_id ); 1367 // FIXME restore old process VMM 1303 1368 return -1; 1304 1369 } 1305 1306 // get a temporary PID for old_process 1307 error = cluster_pid_alloc( old_process , &temp_pid ); 1308 if( error ) 1309 { 1310 printk("\n[ERROR] in %s : cannot get PID in cluster %x\n", 1311 __FUNCTION__ , local_cxy ); 1312 process_free( new_process ); 1313 return -1; 1314 } 1315 1316 // set temporary PID to old_process 1317 old_process->pid = temp_pid; 1318 1319 // initialize new process descriptor 1320 process_reference_init( new_process, 1321 pid, 1322 parent_xp, // parent_process_xp 1323 XPTR(local_cxy , old_process) ); // model_process 1324 1325 // give TXT ownership to new_process 1326 process_txt_set_ownership( XPTR( local_cxy , new_process) ); 1327 1370 1328 1371 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1329 1372 cycle = (uint32_t)hal_get_cycles(); 1330 1373 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1331 printk("\n[DBG] %s : thread %x in process %x created new process %x\n",1332 __FUNCTION__ , old_thread->trdid, pid, new_process);1333 #endif 1334 1335 // register code & data vsegs as well as entry-point in newprocess VMM,1374 printk("\n[DBG] %s : thread %x in process %x / kentry/args/envs vsegs registered / cycle %d\n", 1375 __FUNCTION__, thread->trdid, pid, cycle ); 1376 #endif 1377 1378 // register code & data vsegs as well as entry-point in process VMM, 1336 1379 // and register extended pointer on .elf file in process descriptor 1337 error = elf_load_process( path , new_process ); 1338 1380 error = elf_load_process( file_xp , process ); 1339 1381 if( error ) 1340 1382 { 1341 1383 printk("\n[ERROR] in %s : failed to access <%s>\n", __FUNCTION__ , path ); 1342 process_txt_set_ownership( XPTR( local_cxy , old_process) ); 1343 process_txt_detach( XPTR( local_cxy , new_process) ); 1344 process_destroy( new_process ); 1345 old_process->pid = pid; 1384 vfs_close( file_xp , file_id ); 1385 // FIXME restore old process VMM 1346 1386 return -1; 1347 1387 } … … 1350 1390 cycle = (uint32_t)hal_get_cycles(); 1351 1391 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1352 printk("\n[DBG] %s : thread %x registered code/data vsegs in new process %x / cycle %d\n", 1353 __FUNCTION__, old_thread , new_process->pid , cycle ); 1354 #endif 1355 1356 // select a core in local cluster to execute the main thread 1357 lid = cluster_select_local_core(); 1358 1359 // initialize pthread attributes for main thread 1360 attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED; 1361 attr.cxy = local_cxy; 1362 attr.lid = lid; 1363 1364 // create and initialize main thread in local cluster 1365 error = thread_user_create( pid, 1366 (void *)new_process->vmm.entry_point, 1367 exec_info->args_pointers, 1368 &attr, 1369 &new_thread ); 1370 if( error ) 1371 { 1372 printk("\n[ERROR] in %s : cannot create thread for %s\n", __FUNCTION__ , path ); 1373 process_txt_set_ownership( XPTR( local_cxy , old_process) ); 1374 process_txt_detach( XPTR( local_cxy , new_process) ); 1375 process_destroy( new_process ); 1376 old_process->pid = pid; 1392 printk("\n[DBG] %s : thread %x in process %x / code/data vsegs registered / cycle %d\n", 1393 __FUNCTION__, thread->trdid, pid, cycle ); 1394 #endif 1395 1396 // update the existing main thread descriptor... and jump to user code 1397 error = thread_user_exec( (void *)process->vmm.entry_point, 1398 args_nr, 1399 args_pointers ); 1400 if( error ) 1401 { 1402 printk("\n[ERROR] in %s : cannot reset main thread for %s\n", __FUNCTION__ , path ); 1403 vfs_close( file_xp , file_id ); 1404 // FIXME restore old process VMM 1377 1405 return -1; 1378 } 1379 1380 // check main thread LTID 1381 assert( (LTID_FROM_TRDID(new_thread->trdid) == 0) , __FUNCTION__ , 1382 "main thread must have LTID == 0\n" ); 1383 1384 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1385 cycle = (uint32_t)hal_get_cycles(); 1386 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1387 printk("\n[DBG] %s : thread %x created new_process main thread %x / cycle %d\n", 1388 __FUNCTION__ , old_thread , new_thread , cycle ); 1389 #endif 1390 1391 // register new_process in parent children list 1392 remote_spinlock_lock( children_lock_xp ); 1393 xlist_add_last( children_root_xp , XPTR( local_cxy , &new_process->children_list ) ); 1394 hal_remote_atomic_add( children_nr_xp , 1 ); 1395 remote_spinlock_unlock( children_lock_xp ); 1396 1397 // activate new thread 1398 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 1399 1400 // detach old_process from TXT 1401 process_txt_detach( XPTR( local_cxy , old_process ) ); 1402 1403 // block old_thread 1404 thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL ); 1405 1406 // atomically update old_process termination state 1407 hal_atomic_or( &old_process->term_state , PROCESS_TERM_EXIT ); 1408 1409 // take the children lock and unblock the parent process main thread 1410 remote_spinlock_lock( children_lock_xp ); 1411 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 1412 remote_spinlock_unlock( children_lock_xp ); 1413 1414 hal_fence(); 1415 1416 #if DEBUG_PROCESS_MAKE_EXEC 1417 cycle = (uint32_t)hal_get_cycles(); 1418 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1419 printk("\n[DBG] %s : old thread %x blocked for delete / new thread %x activated / cycle %d\n", 1420 __FUNCTION__ , old_thread , new_thread , cycle ); 1421 #endif 1422 1406 } 1407 1408 assert( false, __FUNCTION__, "we should not execute this code"); 1409 1423 1410 return 0; 1424 1411 1425 1412 } // end process_make_exec() 1413 1426 1414 1427 1415 /////////////////////////////////////////////// … … 1474 1462 pthread_attr_t attr; // main thread attributes 1475 1463 lid_t lid; // selected core local index for main thread 1464 xptr_t file_xp; // extended pointer on .elf file descriptor 1465 uint32_t file_id; // file index in fd_array 1476 1466 error_t error; 1477 1467 … … 1479 1469 uint32_t cycle = (uint32_t)hal_get_cycles(); 1480 1470 if( DEBUG_PROCESS_INIT_CREATE < cycle ) 1481 printk("\n[DBG] %s : thread %x enter / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 1471 printk("\n[DBG] %s : thread %x in process %x enter / cycle %d\n", 1472 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle ); 1482 1473 #endif 1483 1474 1484 1475 // allocates memory for process descriptor from local cluster 1485 1476 process = process_alloc(); 1486 if( process == NULL ) 1487 { 1488 printk("\n[PANIC] in %s : no memory for process descriptor in cluster %x\n", 1489 __FUNCTION__, local_cxy ); 1490 } 1477 1478 assert( (process != NULL), __FUNCTION__, 1479 "no memory for process descriptor in cluster %x\n", local_cxy ); 1491 1480 1492 1481 // get PID from local cluster 1493 1482 error = cluster_pid_alloc( process , &pid ); 1494 if( error ) 1495 { 1496 printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n", 1497 __FUNCTION__, local_cxy ); 1498 process_free( process ); 1499 } 1500 1501 // check allocated PID 1502 assert( (pid == 1) , __FUNCTION__ , "process INIT must be first process in cluster 0\n" ); 1483 1484 assert( (error == 0), __FUNCTION__, 1485 "cannot allocate PID in cluster %x\n", local_cxy ); 1486 1487 assert( (pid == 1) , __FUNCTION__, 1488 "process INIT must be first process in cluster 0\n" ); 1503 1489 1504 1490 // initialize process descriptor / parent is local process_zero 1505 1491 process_reference_init( process, 1506 1492 pid, 1507 XPTR( local_cxy , &process_zero ), // parent 1508 XPTR( local_cxy , &process_zero ) ); // model 1493 XPTR( local_cxy , &process_zero ) ); 1494 1495 // open the file identified by CONFIG_PROCESS_INIT_PATH 1496 file_xp = XPTR_NULL; 1497 file_id = -1; 1498 error = vfs_open( process, 1499 CONFIG_PROCESS_INIT_PATH, 1500 O_RDONLY, 1501 0, 1502 &file_xp, 1503 &file_id ); 1504 1505 assert( (error == 0), __FUNCTION__, 1506 "failed to open file <%s>\n", CONFIG_PROCESS_INIT_PATH ); 1509 1507 1510 1508 // register "code" and "data" vsegs as well as entry-point 1511 1509 // in process VMM, using information contained in the elf file. 1512 if( elf_load_process( CONFIG_PROCESS_INIT_PATH , process ) ) 1513 { 1514 printk("\n[PANIC] in %s : cannot access .elf file / path = %s\n", 1515 __FUNCTION__, CONFIG_PROCESS_INIT_PATH ); 1516 process_destroy( process ); 1517 } 1510 error = elf_load_process( file_xp , process ); 1511 1512 assert( (error == 0), __FUNCTION__, 1513 "cannot access .elf file <%s>\n", CONFIG_PROCESS_INIT_PATH ); 1518 1514 1519 1515 // get extended pointers on process_zero children_root, children_lock … … 1541 1537 &attr, 1542 1538 &thread ); 1543 if( error ) 1544 { 1545 printk("\n[PANIC] in %s : cannot create main thread / path = %s\n", 1546 __FUNCTION__, CONFIG_PROCESS_INIT_PATH ); 1547 process_destroy( process ); 1548 } 1549 1550 // check main thread index 1551 assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1539 1540 assert( (error == 0), __FUNCTION__, 1541 "cannot create main thread for <%s>\n", CONFIG_PROCESS_INIT_PATH ); 1542 1543 assert( (thread->trdid == 0), __FUNCTION__, 1544 "main thread must have index 0 for <%s>\n", CONFIG_PROCESS_INIT_PATH ); 1552 1545 1553 1546 // activate thread … … 1559 1552 cycle = (uint32_t)hal_get_cycles(); 1560 1553 if( DEBUG_PROCESS_INIT_CREATE < cycle ) 1561 printk("\n[DBG] %s : thread %x exit / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 1554 printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n", 1555 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle ); 1562 1556 #endif 1563 1557 … … 1702 1696 xptr_t lock_xp; // extended pointer on list lock in chdev 1703 1697 1704 #if DEBUG_PROCESS_TXT1705 uint32_t cycle = (uint32_t)hal_get_cycles();1706 if( DEBUG_PROCESS_TXT < cycle )1707 printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d / cycle %d\n",1708 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle );1709 #endif1710 1711 1698 // check process is in owner cluster 1712 1699 assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ , … … 1732 1719 1733 1720 #if DEBUG_PROCESS_TXT 1734 cycle = (uint32_t)hal_get_cycles();1721 uint32_t cycle = (uint32_t)hal_get_cycles(); 1735 1722 if( DEBUG_PROCESS_TXT < cycle ) 1736 printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n", 1737 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle ); 1723 printk("\n[DBG] %s : thread %x in process %x attached process %x to TXT %d / cycle %d\n", 1724 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1725 process->pid, txt_id , cycle ); 1738 1726 #endif 1739 1727 … … 1755 1743 process_cxy = GET_CXY( process_xp ); 1756 1744 process_ptr = GET_PTR( process_xp ); 1745 1746 // check process descriptor in owner cluster 1757 1747 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1758 1759 // check process descriptor in owner cluster1760 1748 assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ , 1761 1749 "process descriptor not in owner cluster" ); 1762 1763 #if DEBUG_PROCESS_TXT1764 uint32_t cycle = (uint32_t)hal_get_cycles();1765 if( DEBUG_PROCESS_TXT < cycle )1766 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",1767 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );1768 #endif1769 1750 1770 1751 // release TXT ownership (does nothing if not TXT owner) … … 1788 1769 1789 1770 #if DEBUG_PROCESS_TXT 1790 cycle = (uint32_t)hal_get_cycles();1771 uint32_t cycle = (uint32_t)hal_get_cycles(); 1791 1772 uint32_t txt_id = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) ); 1792 1773 if( DEBUG_PROCESS_TXT < cycle ) 1793 printk("\n[DBG] %s : thread %x exit / process %x detached from TXT %d / cycle %d\n", 1794 __FUNCTION__, CURRENT_THREAD, process_pid, txt_id, cycle ); 1774 printk("\n[DBG] %s : thread %x in process %x detached process %x from TXT %d / cycle %d\n", 1775 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1776 process_pid, txt_id, cycle ); 1795 1777 #endif 1796 1778 … … 1811 1793 process_cxy = GET_CXY( process_xp ); 1812 1794 process_ptr = GET_PTR( process_xp ); 1813 1814 // get process PID1815 1795 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1816 1796 … … 1818 1798 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1819 1799 "process descriptor not in owner cluster\n" ); 1820 1821 #if DEBUG_PROCESS_TXT1822 uint32_t cycle = (uint32_t)hal_get_cycles();1823 if( DEBUG_PROCESS_TXT < cycle )1824 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",1825 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );1826 #endif1827 1800 1828 1801 // get extended pointer on stdin pseudo file … … 1838 1811 1839 1812 #if DEBUG_PROCESS_TXT 1840 cycle = (uint32_t)hal_get_cycles(); 1813 uint32_t cycle = (uint32_t)hal_get_cycles(); 1814 uint32_t txt_id = hal_remote_lw( XPTR( txt_cxy , &txt_ptr->channel ) ); 1841 1815 if( DEBUG_PROCESS_TXT < cycle ) 1842 printk("\n[DBG] %s : thread %x exit forprocess %x / cycle %d\n",1843 __FUNCTION__, CURRENT_THREAD , process_pid, cycle );1816 printk("\n[DBG] %s : thread %x in process %x give TXT %d to process %x / cycle %d\n", 1817 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, process_pid, cycle ); 1844 1818 #endif 1845 1819 … … 1865 1839 cxy_t current_cxy; // cluster for current process 1866 1840 1841 #if DEBUG_PROCESS_TXT 1842 uint32_t cycle; 1843 #endif 1844 1867 1845 // get pointers on process in owner cluster 1868 1846 process_cxy = GET_CXY( process_xp ); 1869 1847 process_ptr = GET_PTR( process_xp ); 1870 1871 // get process PID1872 1848 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1873 1849 … … 1875 1851 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1876 1852 "process descriptor not in owner cluster\n" ); 1877 1878 #if DEBUG_PROCESS_TXT1879 uint32_t cycle = (uint32_t)hal_get_cycles();1880 if( DEBUG_PROCESS_TXT < cycle )1881 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",1882 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );1883 #endif1884 1853 1885 1854 // get extended pointer on stdin pseudo file … … 1895 1864 txt_id = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) ); 1896 1865 1897 #if( DEBUG_PROCESS_TXT & 1 )1898 if( DEBUG_PROCESS_TXT < cycle )1899 printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n",1900 __FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) );1901 #endif1902 1903 1866 // transfer ownership only if process is the TXT owner 1904 1867 if( (owner_xp == process_xp) && (txt_id > 0) ) … … 1913 1876 if( process_get_ppid( process_xp ) != 1 ) // process is not KSH 1914 1877 { 1915 1916 #if( DEBUG_PROCESS_TXT & 1 )1917 if( DEBUG_PROCESS_TXT < cycle )1918 printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ );1919 #endif1920 1878 // scan attached process list to find KSH process 1921 1879 XLIST_FOREACH( root_xp , iter_xp ) … … 1934 1892 1935 1893 #if DEBUG_PROCESS_TXT 1936 cycle = (uint32_t)hal_get_cycles(); 1894 cycle = (uint32_t)hal_get_cycles(); 1895 uint32_t ksh_pid = hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ); 1937 1896 if( DEBUG_PROCESS_TXT < cycle ) 1938 printk("\n[DBG] %s : thread %x exit / process %x to KSH process%x / cycle %d\n",1939 __FUNCTION__, CURRENT_THREAD , process_pid,1940 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle);1897 printk("\n[DBG] %s : thread %x in process %x release TXT %d to KSH %x / cycle %d\n", 1898 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, ksh_pid, cycle ); 1899 process_txt_display( txt_id ); 1941 1900 #endif 1942 1901 return; … … 1954 1913 else // process is KSH 1955 1914 { 1956 1957 #if( DEBUG_PROCESS_TXT & 1 )1958 if( DEBUG_PROCESS_TXT < cycle )1959 printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ );1960 #endif1961 1962 1915 // scan attached process list to find another process 1963 1916 XLIST_FOREACH( root_xp , iter_xp ) … … 1976 1929 1977 1930 #if DEBUG_PROCESS_TXT 1978 cycle = (uint32_t)hal_get_cycles(); 1931 cycle = (uint32_t)hal_get_cycles(); 1932 uint32_t new_pid = hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ); 1979 1933 if( DEBUG_PROCESS_TXT < cycle ) 1980 printk("\n[DBG] %s : thread %x exit / KSH process %xto process %x / cycle %d\n",1981 __FUNCTION__, CURRENT_THREAD , process_pid,1982 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle);1934 printk("\n[DBG] %s : thread %x in process %x release TXT %d to process %x / cycle %d\n", 1935 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, new_pid, cycle ); 1936 process_txt_display( txt_id ); 1983 1937 #endif 1984 1938 return; … … 1995 1949 cycle = (uint32_t)hal_get_cycles(); 1996 1950 if( DEBUG_PROCESS_TXT < cycle ) 1997 printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n", 1998 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1951 printk("\n[DBG] %s : thread %x in process %x release TXT %d to nobody / cycle %d\n", 1952 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, cycle ); 1953 process_txt_display( txt_id ); 1999 1954 #endif 2000 1955 return; … … 2007 1962 cycle = (uint32_t)hal_get_cycles(); 2008 1963 if( DEBUG_PROCESS_TXT < cycle ) 2009 printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n", 2010 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1964 printk("\n[DBG] %s : thread %x in process %d does nothing (not TXT owner) / cycle %d\n", 1965 __FUNCTION__, CURRENT_THREAD->trdid, process_pid, cycle ); 1966 process_txt_display( txt_id ); 2011 1967 #endif 2012 1968 … … 2014 1970 } // end process_txt_transfer_ownership() 2015 1971 1972 1973 ////////////////////////////////////////////////// 1974 uint32_t process_txt_is_owner( xptr_t process_xp ) 1975 { 1976 // get local pointer and cluster of process in owner cluster 1977 cxy_t process_cxy = GET_CXY( process_xp ); 1978 process_t * process_ptr = GET_PTR( process_xp ); 1979 1980 // check owner cluster 1981 pid_t process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1982 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1983 "process descriptor not in owner cluster\n" ); 1984 1985 // get extended pointer on stdin pseudo file 1986 xptr_t file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1987 1988 // get pointers on TXT chdev 1989 xptr_t txt_xp = chdev_from_file( file_xp ); 1990 cxy_t txt_cxy = GET_CXY( txt_xp ); 1991 chdev_t * txt_ptr = GET_PTR( txt_xp ); 1992 1993 // get extended pointer on TXT_RX owner process 1994 xptr_t owner_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) ); 1995 1996 return (process_xp == owner_xp); 1997 1998 } // end process_txt_is_owner() 2016 1999 2017 2000 //////////////////////////////////////////////// … … 2023 2006 2024 2007 return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) ); 2025 } 2008 2009 } // end process_txt_get_owner() 2026 2010 2027 2011 ///////////////////////////////////////////
Note: See TracChangeset
for help on using the changeset viewer.