Changeset 625 for trunk/kernel/kern
- Timestamp:
- Apr 10, 2019, 10:09:39 AM (6 years ago)
- Location:
- trunk/kernel/kern
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/chdev.c
r619 r625 138 138 uint32_t server_lid; // core running the server thread local index 139 139 xptr_t lock_xp; // extended pointer on lock protecting the chdev state 140 uint32_t save_sr; // for critical section141 140 142 141 #if (DEBUG_SYS_READ & 1) … … 177 176 uint32_t rx_cycle = (uint32_t)hal_get_cycles(); 178 177 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) ) 179 printk("\n[%s] client [%x,%x] enter for RX / server[%x,%x] / cycle %d\n",178 printk("\n[%s] client thread[%x,%x] enter for RX / server[%x,%x] / cycle %d\n", 180 179 __FUNCTION__, this->process->pid, this->trdid, server_pid, server_trdid, rx_cycle ); 181 180 #endif … … 184 183 uint32_t tx_cycle = (uint32_t)hal_get_cycles(); 185 184 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) ) 186 printk("\n[%s] client [%x,%x] enter for TX / server[%x,%x] / cycle %d\n",185 printk("\n[%s] client thread[%x,%x] enter for TX / server[%x,%x] / cycle %d\n", 187 186 __FUNCTION__, this->process->pid, this->trdid, server_pid, server_trdid, tx_cycle ); 188 187 #endif … … 194 193 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 195 194 196 // build extended pointer on server thread blocked state197 xptr_t blocked_xp = XPTR( chdev_cxy , &server_ptr->blocked );198 199 195 // build extended pointer on lock protecting chdev waiting queue 200 196 lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock ); 201 197 202 // TODO the hal_disable_irq() / hal_restore_irq() 203 // in the sequence below is probably useless, as it is 204 // already done by the busylock_acquire() / busylock_release() 205 // => remove it [AG] october 2018 206 207 // critical section for the following sequence: 198 // The following actions execute in critical section, 199 // because the lock_acquire / lock_release : 208 200 // (1) take the lock protecting the chdev state 209 // (2) block the client thread 210 // (3) unblock the server thread if required 211 // (4) register client thread in server queue 212 // (5) send IPI to force server scheduling 213 // (6) release the lock protecting waiting queue 214 // (7) deschedule 215 216 // enter critical section 217 hal_disable_irq( &save_sr ); 218 219 // take the lock protecting chdev queue 201 // (2) register client thread in server queue 202 // (3) unblock the server thread and block client thread 203 // (4) send IPI to force server scheduling 204 // (5) release the lock protecting waiting queue 205 206 // 1. take the lock protecting chdev queue 220 207 remote_busylock_acquire( lock_xp ); 221 208 222 // block current thread 223 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_IO ); 224 225 #if (DEBUG_CHDEV_CMD_TX & 1) 226 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) ) 227 printk("\n[%s] client thread[%x,%x] blocked\n", 228 __FUNCTION__, this->process->pid, this->trdid ); 229 #endif 230 231 #if (DEBUG_CHDEV_CMD_RX & 1) 232 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) ) 233 printk("\n[%s] client thread[%x,%x] blocked\n", 234 __FUNCTION__, this->process_pid, this->trdid ); 235 #endif 236 237 // unblock server thread if required 238 if( hal_remote_l32( blocked_xp ) & THREAD_BLOCKED_IDLE ) 239 thread_unblock( server_xp , THREAD_BLOCKED_IDLE ); 240 241 #if (DEBUG_CHDEV_CMD_TX & 1) 242 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) ) 243 printk("\n[%s] TX server thread[%x,%x] unblocked\n", 244 __FUNCTION__, server_pid, server_trdid ); 245 #endif 246 247 #if (DEBUG_CHDEV_CMD_RX & 1) 248 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) ) 249 printk("\n[%s] RX server thread[%x,%x] unblocked\n", 250 __FUNCTION__, server_pid, server_trdid ); 251 #endif 252 253 // register client thread in waiting queue 209 // 2. register client thread in waiting queue 254 210 xlist_add_last( root_xp , list_xp ); 255 211 … … 266 222 #endif 267 223 268 // send IPI to core running the server thread when server core != client core 224 // 3. client thread unblocks server thread and blocks itself 225 thread_unblock( server_xp , THREAD_BLOCKED_IDLE ); 226 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_IO ); 227 228 #if (DEBUG_CHDEV_CMD_TX & 1) 229 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) ) 230 printk("\n[%s] client thread[%x,%x] unblock server thread[%x,%x] and block itsef\n", 231 __FUNCTION__, this->process->pid, this->trdid, server_pid, server_trdid ); 232 #endif 233 234 #if (DEBUG_CHDEV_CMD_RX & 1) 235 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) ) 236 printk("\n[%s] client thread[%x,%x] unblock server thread[%x,%x] and block itsef\n", 237 __FUNCTION__, this->process->pid, this->trdid, server_pid, server_trdid ); 238 #endif 239 240 // 4. send IPI to core running the server thread when server core != client core 269 241 if( (server_lid != this->core->lid) || (local_cxy != chdev_cxy) ) 270 242 { … … 285 257 } 286 258 287 // release lock protecting chdev queue259 // 5. release lock protecting chdev queue 288 260 remote_busylock_release( lock_xp ); 289 261 290 262 // deschedule 291 263 sched_yield("blocked on I/O"); 292 293 // exit critical section294 hal_restore_irq( save_sr );295 264 296 265 #if DEBUG_CHDEV_CMD_RX 297 266 rx_cycle = (uint32_t)hal_get_cycles(); 298 267 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) ) 299 printk("\n[%s] client _thread[%x,%x] exit for RX / cycle %d\n",268 printk("\n[%s] client thread[%x,%x] exit for RX / cycle %d\n", 300 269 __FUNCTION__, this->process->pid, this->trdid, rx_cycle ); 301 270 #endif … … 304 273 tx_cycle = (uint32_t)hal_get_cycles(); 305 274 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) ) 306 printk("\n[%s] client _thread[%x,%x] exit for TX / cycle %d\n",275 printk("\n[%s] client thread[%x,%x] exit for TX / cycle %d\n", 307 276 __FUNCTION__, this->process->pid, this->trdid, tx_cycle ); 308 277 #endif … … 344 313 uint32_t rx_cycle = (uint32_t)hal_get_cycles(); 345 314 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) ) 346 printk("\n[%s] DEVthread[%x,%x] check TXT_RX channel %d / cycle %d\n",315 printk("\n[%s] server thread[%x,%x] check TXT_RX channel %d / cycle %d\n", 347 316 __FUNCTION__ , server->process->pid, server->trdid, chdev->channel, rx_cycle ); 348 317 #endif … … 370 339 rx_cycle = (uint32_t)hal_get_cycles(); 371 340 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) ) 372 printk("\n[%s] thread[%x,%x] found RX queue empty => blocks / cycle %d\n",341 printk("\n[%s] server thread[%x,%x] found RX queue empty => blocks / cycle %d\n", 373 342 __FUNCTION__ , server->process->pid, server->trdid, rx_cycle ); 374 343 #endif … … 377 346 tx_cycle = (uint32_t)hal_get_cycles(); 378 347 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) ) 379 printk("\n[%s] thread[%x,%x] found TX queue empty => blocks / cycle %d\n",348 printk("\n[%s] server thread[%x,%x] found TX queue empty => blocks / cycle %d\n", 380 349 __FUNCTION__ , server->process->pid, server->trdid, tx_cycle ); 381 350 #endif … … 407 376 rx_cycle = (uint32_t)hal_get_cycles(); 408 377 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) ) 409 printk("\n[%s] thread[%x,%x] for RX getclient thread[%x,%x] / cycle %d\n",378 printk("\n[%s] server thread[%x,%x] get command from client thread[%x,%x] / cycle %d\n", 410 379 __FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, rx_cycle ); 411 380 #endif … … 414 383 tx_cycle = (uint32_t)hal_get_cycles(); 415 384 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) ) 416 printk("\n[%s] thread[%x,%x] for TX getclient thread[%x,%x] / cycle %d\n",385 printk("\n[%s] server thread[%x,%x] get command from client thread[%x,%x] / cycle %d\n", 417 386 __FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, tx_cycle ); 418 387 #endif … … 445 414 rx_cycle = (uint32_t)hal_get_cycles(); 446 415 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) ) 447 printk("\n[%s] thread[%x,%x] completes RXfor client thread[%x,%x] / cycle %d\n",416 printk("\n[%s] thread[%x,%x] completes command for client thread[%x,%x] / cycle %d\n", 448 417 __FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, rx_cycle ); 449 418 #endif … … 452 421 tx_cycle = (uint32_t)hal_get_cycles(); 453 422 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) ) 454 printk("\n[%s] thread[%x,%x] completes TXfor client thread[%x,%x] / cycle %d\n",423 printk("\n[%s] thread[%x,%x] completes command for client thread[%x,%x] / cycle %d\n", 455 424 __FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, tX_cycle ); 456 425 #endif -
trunk/kernel/kern/chdev.h
r619 r625 111 111 /****************************************************************************************** 112 112 * This structure defines a chdev descriptor. 113 * For multi-channels device, there is one chdev descriptor per channel.114 113 * This structure is NOT replicated, and can be located in any cluster. 115 114 * One kernel thread, in charge of handling the commands registered in the waiting queue -
trunk/kernel/kern/printk.c
r623 r625 253 253 break; 254 254 } 255 case ('b'): / / excactly 2 digits hexadecimal255 case ('b'): /* exactly 2 digits hexadecimal */ 256 256 { 257 257 int val = va_arg( *args, int ); … … 426 426 427 427 // print generic infos 428 nolock_printk("\n [PANIC] in %s: line %d | cycle %d\n"428 nolock_printk("\n\n[PANIC] in %s: line %d | cycle %d\n" 429 429 "core[%x,%d] | thread %x (%x) | process %x (%x)\n", 430 430 function_name, line, (uint32_t)cycle, … … 502 502 remote_busylock_acquire( lock_xp ); 503 503 504 // display stringon TTY0504 // display buf on TTY0 505 505 dev_txt_sync_write( buf , 10 ); 506 507 // release TXT0 lock 508 remote_busylock_release( lock_xp ); 509 } 510 511 //////////////////////// 512 void putd( int32_t val ) 513 { 514 static const char HexaTab[] = "0123456789ABCDEF"; 515 516 char buf[10]; 517 uint32_t i; 518 519 // get pointers on TXT0 chdev 520 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 521 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 522 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 523 524 // get extended pointer on remote TXT0 chdev lock 525 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 526 527 // get TXT0 lock 528 remote_busylock_acquire( lock_xp ); 529 530 if (val < 0) 531 { 532 val = -val; 533 dev_txt_sync_write( "-" , 1 ); 534 } 535 536 for(i = 0; i < 10 ; i++) 537 { 538 buf[9 - i] = HexaTab[val % 10]; 539 if (!(val /= 10)) break; 540 } 541 542 // display buf on TTY0 543 dev_txt_sync_write( &buf[9-i] , i+1 ); 506 544 507 545 // release TXT0 lock -
trunk/kernel/kern/printk.h
r623 r625 123 123 124 124 /********************************************************************************** 125 * This function displays a non-formated message on kernelTXT0 terminal.125 * This function displays a non-formated message on TXT0 terminal. 126 126 * This function is actually used to debug the assembly level kernel functions. 127 127 ********************************************************************************** … … 131 131 132 132 /********************************************************************************** 133 * This function displays a 32 bits value in hexadecimal on kernelTXT0 terminal.133 * This function displays a 32 bits value in hexadecimal on TXT0 terminal. 134 134 * This function is actually used to debug the assembly level kernel functions. 135 135 ********************************************************************************** … … 139 139 140 140 /********************************************************************************** 141 * This function displays a 64 bits value in hexadecimal on kernel TXT0 terminal. 141 * This function displays a 32 bits signed value in decimal on TXT0 terminal. 142 * This function is actually used to debug the assembly level kernel functions. 143 ********************************************************************************** 144 * @ val : 32 bits signed value. 145 *********************************************************************************/ 146 void putd( int32_t val ); 147 148 /********************************************************************************** 149 * This function displays a 64 bits value in hexadecimal on TXT0 terminal. 142 150 * This function is actually used to debug the assembly level kernel functions. 143 151 ********************************************************************************** … … 147 155 148 156 /********************************************************************************** 149 * This debug function displays on the kernelTXT0 terminal the content of an157 * This debug function displays on the TXT0 terminal the content of an 150 158 * array of bytes defined by <buffer> and <size> arguments (16 bytes per line). 151 159 * The <string> argument is displayed before the buffer content. -
trunk/kernel/kern/process.c
r624 r625 91 91 } 92 92 93 ///////////////////////////////////////////////// 94 void process_reference_init( process_t * process, 95 pid_t pid, 96 xptr_t parent_xp ) 97 { 93 //////////////////////////////////////////////////// 94 error_t process_reference_init( process_t * process, 95 pid_t pid, 96 xptr_t parent_xp ) 97 { 98 error_t error; 98 99 xptr_t process_xp; 99 100 cxy_t parent_cxy; … … 105 106 uint32_t stdout_id; 106 107 uint32_t stderr_id; 107 error_t error;108 108 uint32_t txt_id; 109 109 char rx_path[40]; … … 111 111 xptr_t file_xp; 112 112 xptr_t chdev_xp; 113 chdev_t *chdev_ptr;113 chdev_t * chdev_ptr; 114 114 cxy_t chdev_cxy; 115 115 pid_t parent_pid; 116 vmm_t * vmm; 116 117 117 118 // build extended pointer on this reference process 118 119 process_xp = XPTR( local_cxy , process ); 120 121 // get pointer on process vmm 122 vmm = &process->vmm; 119 123 120 124 // get parent process cluster and local pointer … … 129 133 uint32_t cycle = (uint32_t)hal_get_cycles(); 130 134 if( DEBUG_PROCESS_REFERENCE_INIT < cycle ) 131 printk("\n[%s] thread[%x,%x] enter to init alialize process %x / cycle %d\n",132 __FUNCTION__, parent_pid, this->trdid, pid, cycle );135 printk("\n[%s] thread[%x,%x] enter to initialize process %x / cycle %d\n", 136 __FUNCTION__, this->process->pid, this->trdid, pid, cycle ); 133 137 #endif 134 138 … … 144 148 process->cwd_xp = hal_remote_l64( XPTR( parent_cxy, &parent_ptr->cwd_xp ) ); 145 149 146 // initialize vmm as empty 147 error = vmm_init( process ); 148 149 assert( (error == 0) , "cannot initialize VMM\n" ); 150 // initialize VSL as empty 151 vmm->vsegs_nr = 0; 152 xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) ); 153 154 // create an empty GPT as required by the architecture 155 error = hal_gpt_create( &vmm->gpt ); 156 if( error ) 157 { 158 printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ ); 159 return -1; 160 } 161 162 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) 163 if( DEBUG_PROCESS_REFERENCE_INIT < cycle ) 164 printk("\n[%s] thread[%x,%x] created empty GPT for process %x\n", 165 __FUNCTION__, parent_pid, this->trdid, pid ); 166 #endif 167 168 // initialize GPT and VSL locks 169 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 170 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 171 172 // register kernel vsegs in VMM as required by the architecture 173 error = hal_vmm_kernel_update( process ); 174 if( error ) 175 { 176 printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ ); 177 return -1; 178 } 179 180 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) 181 if( DEBUG_PROCESS_REFERENCE_INIT < cycle ) 182 printk("\n[%s] thread[%x,%x] registered kernel vsegs for process %x\n", 183 __FUNCTION__, parent_pid, this->trdid, pid ); 184 #endif 185 186 // create "args" and "envs" vsegs 187 // create "stacks" and "mmap" vsegs allocators 188 // initialize locks protecting GPT and VSL 189 error = vmm_user_init( process ); 190 if( error ) 191 { 192 printk("\n[ERROR] in %s : cannot register user vsegs in VMM\n", __FUNCTION__ ); 193 return -1; 194 } 150 195 151 196 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) 152 197 cycle = (uint32_t)hal_get_cycles(); 153 198 if( DEBUG_PROCESS_REFERENCE_INIT < cycle ) 154 printk("\n[%s] thread[%x,%x] / vmm empty for process %x / cycle %d\n",155 __FUNCTION__, parent_pid, this->trdid, pid , cycle);199 printk("\n[%s] thread[%x,%x] initialized vmm for process %x\n", 200 __FUNCTION__, parent_pid, this->trdid, pid ); 156 201 #endif 157 202 … … 187 232 &stdin_xp, 188 233 &stdin_id ); 189 190 assert( (error == 0) , "cannot open stdin pseudo file" ); 234 if( error ) 235 { 236 printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ ); 237 return -1; 238 } 239 191 240 assert( (stdin_id == 0) , "stdin index must be 0" ); 192 241 … … 206 255 &stdout_xp, 207 256 &stdout_id ); 208 209 assert( (error == 0) , "cannot open stdout pseudo file" ); 210 assert( (stdout_id == 1) , "stdout index must be 1" ); 257 if( error ) 258 { 259 printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ ); 260 return -1; 261 } 262 263 assert( (stdout_id == 1) , "stdout index must be 1" ); 211 264 212 265 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) … … 225 278 &stderr_xp, 226 279 &stderr_id ); 227 228 assert( (error == 0) , "cannot open stderr pseudo file" ); 229 assert( (stderr_id == 2) , "stderr index must be 2" ); 280 if( error ) 281 { 282 printk("\n[ERROR] in %s : cannot open stderr pseudo-file\n", __FUNCTION__ ); 283 return -1; 284 } 285 286 assert( (stderr_id == 2) , "stderr index must be 2" ); 230 287 231 288 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) … … 240 297 { 241 298 // get extended pointer on stdin pseudo file in parent process 242 file_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy , &parent_ptr->fd_array.array[0] ) ); 299 file_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy, 300 &parent_ptr->fd_array.array[0] ) ); 243 301 244 302 // get extended pointer on parent process TXT chdev … … 261 319 262 320 // initialize lock protecting CWD changes 263 remote_busylock_init( XPTR( local_cxy , &process->cwd_lock ), LOCK_PROCESS_CWD ); 321 remote_busylock_init( XPTR( local_cxy , 322 &process->cwd_lock ), LOCK_PROCESS_CWD ); 264 323 265 324 #if (DEBUG_PROCESS_REFERENCE_INIT & 1) … … 273 332 xlist_root_init( XPTR( local_cxy , &process->children_root ) ); 274 333 process->children_nr = 0; 275 remote_queuelock_init( XPTR( local_cxy , &process->children_lock ), LOCK_PROCESS_CHILDREN ); 334 remote_queuelock_init( XPTR( local_cxy, 335 &process->children_lock ), LOCK_PROCESS_CHILDREN ); 276 336 277 337 // reset semaphore / mutex / barrier / condvar list roots and lock … … 280 340 xlist_root_init( XPTR( local_cxy , &process->barrier_root ) ); 281 341 xlist_root_init( XPTR( local_cxy , &process->condvar_root ) ); 282 remote_queuelock_init( XPTR( local_cxy , &process->sync_lock ), LOCK_PROCESS_USERSYNC ); 342 remote_queuelock_init( XPTR( local_cxy , 343 &process->sync_lock ), LOCK_PROCESS_USERSYNC ); 283 344 284 345 // reset open directories root and lock 285 346 xlist_root_init( XPTR( local_cxy , &process->dir_root ) ); 286 remote_queuelock_init( XPTR( local_cxy , &process->dir_lock ), LOCK_PROCESS_DIR ); 347 remote_queuelock_init( XPTR( local_cxy , 348 &process->dir_lock ), LOCK_PROCESS_DIR ); 287 349 288 350 // register new process in the local cluster manager pref_tbl[] … … 315 377 #endif 316 378 379 return 0; 380 317 381 } // process_reference_init() 318 382 … … 321 385 xptr_t reference_process_xp ) 322 386 { 323 error_t error; 387 error_t error; 388 vmm_t * vmm; 324 389 325 390 // get reference process cluster and local pointer 326 391 cxy_t ref_cxy = GET_CXY( reference_process_xp ); 327 392 process_t * ref_ptr = GET_PTR( reference_process_xp ); 393 394 // get pointer on process vmm 395 vmm = &local_process->vmm; 328 396 329 397 // initialize PID, REF_XP, PARENT_XP, and STATE … … 343 411 344 412 // check user process 345 assert( (local_process->pid != 0), "PID cannot be 0" ); 346 347 // reset local process vmm 348 error = vmm_init( local_process ); 349 assert( (error == 0) , "cannot initialize VMM\n"); 350 351 // reset process file descriptors array 413 assert( (local_process->pid != 0), "LPID cannot be 0" ); 414 415 // initialize VSL as empty 416 vmm->vsegs_nr = 0; 417 xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) ); 418 419 // create an empty GPT as required by the architecture 420 error = hal_gpt_create( &vmm->gpt ); 421 if( error ) 422 { 423 printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ ); 424 return -1; 425 } 426 427 // initialize GPT and VSL locks 428 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 429 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 430 431 // register kernel vsegs in VMM as required by the architecture 432 error = hal_vmm_kernel_update( local_process ); 433 if( error ) 434 { 435 printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ ); 436 return -1; 437 } 438 439 // create "args" and "envs" vsegs 440 // create "stacks" and "mmap" vsegs allocators 441 // initialize locks protecting GPT and VSL 442 error = vmm_user_init( local_process ); 443 if( error ) 444 { 445 printk("\n[ERROR] in %s : cannot register user vsegs in VMM\n", __FUNCTION__ ); 446 return -1; 447 } 448 449 #if (DEBUG_PROCESS_COPY_INIT & 1) 450 cycle = (uint32_t)hal_get_cycles(); 451 if( DEBUG_PROCESS_COPY_INIT < cycle ) 452 printk("\n[%s] thread[%x,%x] initialized vmm for process %x / cycle %d\n", 453 __FUNCTION__, parent_pid, this->trdid, pid, cycle ); 454 #endif 455 456 // set process file descriptors array 352 457 process_fd_init( local_process ); 353 458 354 // reset vfs_root_xp / vfs_bin_xp / cwd_xp fields459 // set vfs_root_xp / vfs_bin_xp / cwd_xp fields 355 460 local_process->vfs_root_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) ); 356 461 local_process->vfs_bin_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) ); … … 380 485 local_process->th_nr = 0; 381 486 rwlock_init( &local_process->th_lock , LOCK_PROCESS_THTBL ); 382 383 487 384 488 // register new process descriptor in local cluster manager local_list … … 451 555 #endif 452 556 453 // remove process from children_list 454 // and release PID if owner cluster 557 // when target process cluster is the owner cluster 558 // - remove process from TXT list and transfer ownership 559 // - remove process from children_list 560 // - release PID 455 561 if( CXY_FROM_PID( pid ) == local_cxy ) 456 562 { 563 process_txt_detach( XPTR( local_cxy , process ) ); 564 565 #if (DEBUG_PROCESS_DESTROY & 1) 566 if( DEBUG_PROCESS_DESTROY < cycle ) 567 printk("\n[%s] thread[%x,%x] removed process %x from TXT list\n", 568 __FUNCTION__, this->process->pid, this->trdid, pid ); 569 #endif 570 457 571 // get pointers on parent process 458 572 parent_xp = process->parent_xp; … … 472 586 #if (DEBUG_PROCESS_DESTROY & 1) 473 587 if( DEBUG_PROCESS_DESTROY < cycle ) 474 printk("\n[%s] thread[%x,%x] removed process %x in cluster %x fromchildren list\n",475 __FUNCTION__, this->process->pid, this->trdid, pid , local_cxy);588 printk("\n[%s] thread[%x,%x] removed process %x from parent process children list\n", 589 __FUNCTION__, this->process->pid, this->trdid, pid ); 476 590 #endif 477 591 … … 777 891 uint32_t cycle = (uint32_t)hal_get_cycles(); 778 892 if( DEBUG_PROCESS_SIGACTION < cycle ) 779 printk("\n[%s] thread[%x,%x] enter in cluster %x for process%x / cycle %d\n",780 __FUNCTION__, this->process->pid, this->trdid, local_cxy, process->pid, cycle );893 printk("\n[%s] thread[%x,%x] enter for process %x n cluster %x / cycle %d\n", 894 __FUNCTION__, this->process->pid, this->trdid, process->pid, local_cxy, cycle ); 781 895 #endif 782 896 … … 1189 1303 } // end process_register_thread() 1190 1304 1191 ///////////////////////////////////////////////// 1192 bool_t process_remove_thread( thread_t * thread )1305 /////////////////////////////////////////////////// 1306 uint32_t process_remove_thread( thread_t * thread ) 1193 1307 { 1194 1308 uint32_t count; // number of threads in local process descriptor 1309 1310 // check thread 1311 assert( (thread != NULL) , "thread argument is NULL" ); 1195 1312 1196 1313 process_t * process = thread->process; … … 1205 1322 count = process->th_nr; 1206 1323 1207 // check thread1208 assert( (thread != NULL) , "thread argument is NULL" );1209 1210 1324 // check th_nr value 1211 1325 assert( (count > 0) , "process th_nr cannot be 0" ); … … 1218 1332 rwlock_wr_release( &process->th_lock ); 1219 1333 1220 return (count == 1);1334 return count; 1221 1335 1222 1336 } // end process_remove_thread() … … 1283 1397 cycle = (uint32_t)hal_get_cycles(); 1284 1398 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1285 printk("\n[%s] thread[%x,%x] allocated process %x / cycle %d\n",1399 printk("\n[%s] thread[%x,%x] allocated child_process %x / cycle %d\n", 1286 1400 __FUNCTION__, pid, trdid, new_pid, cycle ); 1287 1401 #endif 1288 1402 1289 1403 // initializes child process descriptor from parent process descriptor 1290 process_reference_init( process, 1291 new_pid, 1292 parent_process_xp ); 1404 error = process_reference_init( process, 1405 new_pid, 1406 parent_process_xp ); 1407 if( error ) 1408 { 1409 printk("\n[ERROR] in %s : cannot initialize child process in cluster %x\n", 1410 __FUNCTION__, local_cxy ); 1411 process_free( process ); 1412 return -1; 1413 } 1293 1414 1294 1415 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) … … 1298 1419 __FUNCTION__, pid, trdid, new_pid, cycle ); 1299 1420 #endif 1300 1301 1421 1302 1422 // copy VMM from parent descriptor to child descriptor … … 1361 1481 #endif 1362 1482 1363 // set C opy_On_Write flag in parent process GPT1364 // this includes all replicated GPT copies1483 // set COW flag in DATA, ANON, REMOTE vsegs for parent process VMM 1484 // this includes all parnet process copies in all clusters 1365 1485 if( parent_process_cxy == local_cxy ) // reference is local 1366 1486 { … … 1373 1493 } 1374 1494 1375 // set C opy_On_Write flag in child process GPT1495 // set COW flag in DATA, ANON, REMOTE vsegs for child process VMM 1376 1496 vmm_set_cow( process ); 1377 1497 … … 1423 1543 char ** args_pointers; // array of pointers on main thread arguments 1424 1544 1425 // get thread, process, pid and ref_xp1545 // get calling thread, process, pid and ref_xp 1426 1546 thread = CURRENT_THREAD; 1427 1547 process = thread->process; … … 1470 1590 cycle = (uint32_t)hal_get_cycles(); 1471 1591 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1472 printk("\n[%s] thread[%x,%x] deleted allthreads / cycle %d\n",1592 printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n", 1473 1593 __FUNCTION__, pid, thread->trdid, cycle ); 1474 1594 #endif 1475 1595 1476 // reset localprocess VMM1477 vmm_ destroy( process );1596 // reset calling process VMM 1597 vmm_user_reset( process ); 1478 1598 1479 1599 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1480 1600 cycle = (uint32_t)hal_get_cycles(); 1481 1601 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1482 printk("\n[%s] thread[%x,%x] reset VMM/ cycle %d\n",1602 printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n", 1483 1603 __FUNCTION__, pid, thread->trdid, cycle ); 1484 1604 #endif 1485 1605 1486 // re-initialize the VMM ( kentry/args/envs vsegs registration)1487 error = vmm_ init( process );1606 // re-initialize the VMM (args/envs vsegs registration) 1607 error = vmm_user_init( process ); 1488 1608 if( error ) 1489 1609 { … … 1497 1617 cycle = (uint32_t)hal_get_cycles(); 1498 1618 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1499 printk("\n[%s] thread[%x,%x] / kentry/args/envs vsegs registered/ cycle %d\n",1619 printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n", 1500 1620 __FUNCTION__, pid, thread->trdid, cycle ); 1501 1621 #endif … … 1515 1635 cycle = (uint32_t)hal_get_cycles(); 1516 1636 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 1517 printk("\n[%s] thread[%x,%x] / code/data vsegs registered/ cycle %d\n",1637 printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n", 1518 1638 __FUNCTION__, pid, thread->trdid, cycle ); 1519 1639 #endif … … 1577 1697 vmm->vsegs_nr = 0; 1578 1698 xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) ); 1579 remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) , LOCK_VMM_VSL );1580 1699 1581 1700 // initialise GPT as empty 1582 1701 error = hal_gpt_create( &vmm->gpt ); 1583 1584 1702 if( error ) 1585 1703 { … … 1588 1706 } 1589 1707 1590 // initialize GPT lock 1708 // initialize VSL and GPT locks 1709 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 1591 1710 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 1592 1711 1593 1712 // create kernel vsegs in GPT and VSL, as required by the hardware architecture 1594 1713 error = hal_vmm_kernel_init( info ); 1595 1596 1714 if( error ) 1597 1715 { … … 1652 1770 // allocates memory for process descriptor from local cluster 1653 1771 process = process_alloc(); 1654 1655 // check memory allocator 1656 assert( (process != NULL), 1657 "no memory for process descriptor in cluster %x", local_cxy ); 1772 if( process == NULL ) 1773 { 1774 printk("\n[PANIC] in %s : cannot allocate process\n", __FUNCTION__ ); 1775 hal_core_sleep(); 1776 } 1658 1777 1659 1778 // set the CWD and VFS_ROOT fields in process descriptor … … 1663 1782 // get PID from local cluster 1664 1783 error = cluster_pid_alloc( process , &pid ); 1665 1666 // check PID allocator 1667 assert( (error == 0), 1668 "cannot allocate PID in cluster %x", local_cxy ); 1669 1670 // check PID value 1671 assert( (pid == 1) , 1672 "process INIT must be first process in cluster 0" ); 1784 if( error ) 1785 { 1786 printk("\n[PANIC] in %s : cannot allocate PID\n", __FUNCTION__ ); 1787 hal_core_sleep(); 1788 } 1789 if( pid != 1 ) 1790 { 1791 printk("\n[PANIC] in %s : process PID must be 0x1\n", __FUNCTION__ ); 1792 hal_core_sleep(); 1793 } 1673 1794 1674 1795 // initialize process descriptor / parent is local process_zero 1675 process_reference_init( process, 1676 pid, 1677 XPTR( local_cxy , &process_zero ) ); 1796 error = process_reference_init( process, 1797 pid, 1798 XPTR( local_cxy , &process_zero ) ); 1799 if( error ) 1800 { 1801 printk("\n[PANIC] in %s : cannot initialize process\n", __FUNCTION__ ); 1802 hal_core_sleep(); 1803 } 1678 1804 1679 1805 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1693 1819 &file_xp, 1694 1820 &file_id ); 1695 1696 assert( (error == 0), 1697 "failed to open file <%s>", CONFIG_PROCESS_INIT_PATH ); 1821 if( error ) 1822 { 1823 printk("\n[PANIC] in %s : cannot open file <%s>\n", 1824 __FUNCTION__, CONFIG_PROCESS_INIT_PATH ); 1825 hal_core_sleep(); 1826 } 1698 1827 1699 1828 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1703 1832 #endif 1704 1833 1705 // register "code" and "data" vsegs as well as entry-point1834 // register "code" and "data" vsegs as well as entry-point 1706 1835 // in process VMM, using information contained in the elf file. 1707 1836 error = elf_load_process( file_xp , process ); 1708 1837 1709 assert( (error == 0), 1710 "cannot access .elf file <%s>", CONFIG_PROCESS_INIT_PATH ); 1838 if( error ) 1839 { 1840 printk("\n[PANIC] in %s : cannot access file <%s>\n", 1841 __FUNCTION__, CONFIG_PROCESS_INIT_PATH ); 1842 hal_core_sleep(); 1843 } 1844 1711 1845 1712 1846 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1714 1848 printk("\n[%s] thread[%x,%x] registered code/data vsegs in VMM\n", 1715 1849 __FUNCTION__, this->process->pid, this->trdid ); 1850 #endif 1851 1852 #if (DEBUG_PROCESS_INIT_CREATE & 1) 1853 hal_vmm_display( process , true ); 1716 1854 #endif 1717 1855 … … 1751 1889 &thread ); 1752 1890 1753 assert( (error == 0), 1754 "cannot create main thread for <%s>", CONFIG_PROCESS_INIT_PATH ); 1755 1756 assert( (thread->trdid == 0), 1757 "main thread must have index 0 for <%s>", CONFIG_PROCESS_INIT_PATH ); 1891 if( error ) 1892 { 1893 printk("\n[PANIC] in %s : cannot create main thread\n", __FUNCTION__ ); 1894 hal_core_sleep(); 1895 } 1896 if( thread->trdid != 0 ) 1897 { 1898 printk("\n[PANIC] in %s : bad main thread trdid\n", __FUNCTION__ ); 1899 hal_core_sleep(); 1900 } 1758 1901 1759 1902 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1989 2132 process_txt_transfer_ownership( process_xp ); 1990 2133 1991 // get extended pointer on process stdin file2134 // get extended pointer on process stdin pseudo file 1992 2135 file_xp = (xptr_t)hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1993 2136 … … 2014 2157 uint32_t txt_id = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) ); 2015 2158 if( DEBUG_PROCESS_TXT < cycle ) 2016 printk("\n[%s] thread[%x,%x] detached process %x from TXT 2159 printk("\n[%s] thread[%x,%x] detached process %x from TXT%d / cycle %d\n", 2017 2160 __FUNCTION__, this->process->pid, this->trdid, process_pid, txt_id, cycle ); 2018 2161 #endif … … 2056 2199 uint32_t txt_id = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) ); 2057 2200 if( DEBUG_PROCESS_TXT < cycle ) 2058 printk("\n[%s] thread[%x,%x] give TXT %dto process %x / cycle %d\n",2201 printk("\n[%s] thread[%x,%x] give TXT%d ownership to process %x / cycle %d\n", 2059 2202 __FUNCTION__, this->process->pid, this->trdid, txt_id, process_pid, cycle ); 2060 2203 #endif … … 2078 2221 xptr_t iter_xp; // iterator for xlist 2079 2222 xptr_t current_xp; // extended pointer on current process 2080 process_t * current_ptr; // local pointer on current process 2081 cxy_t current_cxy; // cluster for current process 2223 bool_t found; 2082 2224 2083 2225 #if DEBUG_PROCESS_TXT … … 2086 2228 #endif 2087 2229 2088 // get pointers on process in owner cluster2230 // get pointers on target process 2089 2231 process_cxy = GET_CXY( process_xp ); 2090 2232 process_ptr = GET_PTR( process_xp ); 2091 2233 process_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) ); 2092 2234 2093 2094 2095 2235 // check owner cluster 2236 assert( (process_cxy == CXY_FROM_PID( process_pid )) , 2237 "process descriptor not in owner cluster" ); 2096 2238 2097 2239 // get extended pointer on stdin pseudo file … … 2103 2245 txt_ptr = GET_PTR( txt_xp ); 2104 2246 2105 // get extended pointer on TXT_RX owner and TXT channel2247 // get relevant infos from chdev descriptor 2106 2248 owner_xp = hal_remote_l64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) ); 2107 txt_id = hal_remote_l32 2108 2109 // transfer ownership only if process is the TXT owner2249 txt_id = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) ); 2250 2251 // transfer ownership only if target process is the TXT owner 2110 2252 if( (owner_xp == process_xp) && (txt_id > 0) ) 2111 2253 { … … 2114 2256 lock_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.lock ); 2115 2257 2116 // get lock 2117 remote_busylock_acquire( lock_xp ); 2118 2119 if( process_get_ppid( process_xp ) != 1 ) // process is not KSH 2258 if( process_get_ppid( process_xp ) != 1 ) // target process is not KSH 2120 2259 { 2260 // get lock 2261 remote_busylock_acquire( lock_xp ); 2262 2121 2263 // scan attached process list to find KSH process 2122 XLIST_FOREACH( root_xp , iter_xp ) 2264 found = false; 2265 for( iter_xp = hal_remote_l64( root_xp ) ; 2266 (iter_xp != root_xp) && (found == false) ; 2267 iter_xp = hal_remote_l64( iter_xp ) ) 2268 { 2269 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 2270 2271 if( process_get_ppid( current_xp ) == 1 ) // current is KSH 2272 { 2273 // set owner field in TXT chdev 2274 hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 2275 2276 #if DEBUG_PROCESS_TXT 2277 cycle = (uint32_t)hal_get_cycles(); 2278 if( DEBUG_PROCESS_TXT < cycle ) 2279 printk("\n[%s] thread[%x,%x] transfered TXT%d ownership to KSH / cycle %d\n", 2280 __FUNCTION__, this->process->pid, this->trdid, txt_id, cycle ); 2281 #endif 2282 found = true; 2283 } 2284 } 2285 2286 // release lock 2287 remote_busylock_release( lock_xp ); 2288 2289 // It must exist a KSH process for each user TXT channel 2290 assert( (found == true), "KSH process not found for TXT%d", txt_id ); 2291 2292 } 2293 else // target process is KSH 2294 { 2295 // get lock 2296 remote_busylock_acquire( lock_xp ); 2297 2298 // scan attached process list to find another process 2299 found = false; 2300 for( iter_xp = hal_remote_l64( root_xp ) ; 2301 (iter_xp != root_xp) && (found == false) ; 2302 iter_xp = hal_remote_l64( iter_xp ) ) 2123 2303 { 2124 2304 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 2125 current_cxy = GET_CXY( current_xp ); 2126 current_ptr = GET_PTR( current_xp ); 2127 2128 if( process_get_ppid( current_xp ) == 1 ) // current is KSH 2305 2306 if( current_xp != process_xp ) // current is not KSH 2129 2307 { 2130 // release lock2131 remote_busylock_release( lock_xp );2132 2133 2308 // set owner field in TXT chdev 2134 2309 hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 2135 2310 2136 2311 #if DEBUG_PROCESS_TXT 2137 cycle = (uint32_t)hal_get_cycles(); 2138 uint32_t ksh_pid = hal_remote_l32( XPTR( current_cxy , ¤t_ptr->pid ) ); 2312 cycle = (uint32_t)hal_get_cycles(); 2313 cxy_t current_cxy = GET_CXY( current_xp ); 2314 process_t * current_ptr = GET_PTR( current_xp ); 2315 uint32_t new_pid = hal_remote_l32( XPTR( current_cxy , ¤t_ptr->pid ) ); 2139 2316 if( DEBUG_PROCESS_TXT < cycle ) 2140 printk("\n[%s] thread[%x,%x] release TXT %d to KSH %x / cycle %d\n", 2141 __FUNCTION__, this->process->pid, this->trdid, txt_id, ksh_pid, cycle ); 2142 process_txt_display( txt_id ); 2143 #endif 2144 return; 2317 printk("\n[%s] thread[%x,%x] transfered TXT%d ownership to process %x / cycle %d\n", 2318 __FUNCTION__,this->process->pid, this->trdid, txt_id, new_pid, cycle ); 2319 #endif 2320 found = true; 2145 2321 } 2146 2322 } 2147 2323 2148 2324 // release lock 2149 2325 remote_busylock_release( lock_xp ); 2150 2326 2151 // PANIC if KSH not found 2152 assert( false , "KSH process not found for TXT %d" ); 2153 2154 return; 2327 // no more owner for TXT if no other process found 2328 if( found == false ) 2329 { 2330 // set owner field in TXT chdev 2331 hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL ); 2332 2333 #if DEBUG_PROCESS_TXT 2334 cycle = (uint32_t)hal_get_cycles(); 2335 if( DEBUG_PROCESS_TXT < cycle ) 2336 printk("\n[%s] thread[%x,%x] released TXT%d (no attached process) / cycle %d\n", 2337 __FUNCTION__, this->process->pid, this->trdid, txt_id, cycle ); 2338 #endif 2339 } 2155 2340 } 2156 else // process is KSH 2157 { 2158 // scan attached process list to find another process 2159 XLIST_FOREACH( root_xp , iter_xp ) 2160 { 2161 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 2162 current_cxy = GET_CXY( current_xp ); 2163 current_ptr = GET_PTR( current_xp ); 2164 2165 if( current_xp != process_xp ) // current is not KSH 2166 { 2167 // release lock 2168 remote_busylock_release( lock_xp ); 2169 2170 // set owner field in TXT chdev 2171 hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 2341 } 2342 else 2343 { 2172 2344 2173 2345 #if DEBUG_PROCESS_TXT 2174 cycle = (uint32_t)hal_get_cycles(); 2175 uint32_t new_pid = hal_remote_l32( XPTR( current_cxy , ¤t_ptr->pid ) ); 2346 cycle = (uint32_t)hal_get_cycles(); 2176 2347 if( DEBUG_PROCESS_TXT < cycle ) 2177 printk("\n[%s] thread[%x,%x] release TXT %d to process %x / cycle %d\n", 2178 __FUNCTION__,this->process->pid, this->trdid, txt_id, new_pid, cycle ); 2179 process_txt_display( txt_id ); 2180 #endif 2181 return; 2182 } 2183 } 2184 2185 // release lock 2186 remote_busylock_release( lock_xp ); 2187 2188 // no more owner for TXT if no other process found 2189 hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL ); 2190 2191 #if DEBUG_PROCESS_TXT 2192 cycle = (uint32_t)hal_get_cycles(); 2193 if( DEBUG_PROCESS_TXT < cycle ) 2194 printk("\n[%s] thread[%x,%x] release TXT %d to nobody / cycle %d\n", 2195 __FUNCTION__, this->process->pid, this->trdid, txt_id, cycle ); 2196 process_txt_display( txt_id ); 2197 #endif 2198 return; 2199 } 2200 } 2201 else 2202 { 2203 2204 #if DEBUG_PROCESS_TXT 2205 cycle = (uint32_t)hal_get_cycles(); 2206 if( DEBUG_PROCESS_TXT < cycle ) 2207 printk("\n[%s] thread %x in process %d does nothing (not TXT owner) / cycle %d\n", 2208 __FUNCTION__, this->trdid, process_pid, cycle ); 2209 process_txt_display( txt_id ); 2210 #endif 2211 2212 } 2348 printk("\n[%s] thread[%x,%x] does nothing for process %x (not TXT owner) / cycle %d\n", 2349 __FUNCTION__, this->process->pid, this->trdid, process_pid, cycle ); 2350 #endif 2351 2352 } 2353 2213 2354 } // end process_txt_transfer_ownership() 2214 2355 -
trunk/kernel/kern/process.h
r623 r625 228 228 229 229 /********************************************************************************************* 230 * This function initializes a reference ,user process descriptor from another process230 * This function initializes a reference user process descriptor from another process 231 231 * descriptor, defined by the <parent_xp> argument. The <process> and <pid> arguments 232 232 * are previously allocated by the caller. This function can be called by two functions: 233 * 1) process_init_create() : process is the INIT process ;parent is process-zero.233 * 1) process_init_create() : process is the INIT process, and parent is process-zero. 234 234 * 2) process_make_fork() : the parent process descriptor is generally remote. 235 235 * The following fields are initialised : 236 236 * - It set the pid / ppid / ref_xp / parent_xp / state fields. 237 * - It initializes the VMM (register the kentry, args, envs vsegs in VSL) 237 * - It creates an empty GPT and an empty VSL. 238 * - It initializes the locks protecting the GPT and the VSL. 239 * - It registers the "kernel" vsegs in VSL, using the hal_vmm_kernel_update() function. 240 * - It registers the "args" and "envs" vsegs in VSL, using the vmm_user_init() function. 241 * - The "code and "data" must be registered later, using the elf_load_process() function. 238 242 * - It initializes the FDT, defining the three pseudo files STDIN / STDOUT / STDERR. 239 243 * . if INIT process => link to kernel TXT[0]. 240 * . if KSH[i] process => allocate a free TXT[i] and give TXT ownership.241 * . if USER process => same TXT[i] as parent process and give TXT ownership.244 * . if KSH[i] process => allocate a free TXT[i]. 245 * . if USER process => link to parent process TXT[i]. 242 246 * - It set the root_xp, bin_xp, cwd_xp fields. 243 247 * - It reset the children list as empty, but does NOT register it in parent children list. … … 251 255 * @ pid : [in] process identifier. 252 256 * @ parent_xp : [in] extended pointer on parent process descriptor. 253 ********************************************************************************************/ 254 void process_reference_init( process_t * process, 255 pid_t pid, 256 xptr_t parent_xp ); 257 * @ return 0 if success / return -1 if failure 258 ********************************************************************************************/ 259 error_t process_reference_init( process_t * process, 260 pid_t pid, 261 xptr_t parent_xp ); 257 262 258 263 /********************************************************************************************* 259 264 * This function initializes a copy process descriptor, in the local cluster, 260 265 * from information defined in the reference remote process descriptor. 266 * As the VSL and the GPT of a process copy are handled as local caches, the GPT copy is 267 * created empty, and the VSL copy contains only the "kernel", "args", and "envs" vsegs. 261 268 ********************************************************************************************* 262 269 * @ process : [in] local pointer on process descriptor to initialize. 263 270 * @ reference_process_xp : [in] extended pointer on reference process descriptor. 264 * @ return 0 if success / return ENOMEMif failure271 * @ return 0 if success / return -1 if failure 265 272 ********************************************************************************************/ 266 273 error_t process_copy_init( process_t * local_process, … … 272 279 * The local th_tbl[] array must be empty. 273 280 ********************************************************************************************* 274 * @ process : pointer on the process descriptor.281 * @ process : [in] pointer on the process descriptor. 275 282 ********************************************************************************************/ 276 283 void process_destroy( process_t * process ); … … 283 290 * taken by the caller function. 284 291 ********************************************************************************************* 285 * @ process_xp :extended pointer on process descriptor.292 * @ process_xp : [in] extended pointer on process descriptor. 286 293 ********************************************************************************************/ 287 294 void process_display( xptr_t process_xp ); … … 396 403 /********************************************************************************************* 397 404 * This function implements the "fork" system call, and is called by the sys_fork() function, 398 * likely throu ch the RPC_PROCESS_MAKE_FORK.399 * It allocates memory and initializes a new "child"process descriptor, and the associated400 * "child" thread descriptor in local cluster. It involves up to three different clusters:405 * likely through the RPC_PROCESS_MAKE_FORK. 406 * It allocates memory and initializes a new child process descriptor, and the associated 407 * child thread descriptor in local cluster. It involves up to three different clusters: 401 408 * - the child (local) cluster can be any cluster selected by the sys_fork function. 402 409 * - the parent cluster must be the reference cluster for the parent process. 403 410 * - the client cluster containing the thread requesting the fork can be any cluster. 404 * The new "child" process descriptor is initialised from informations found in the "parent"411 * The new child process descriptor is initialised from informations found in the parent 405 412 * reference process descriptor, containing the complete process description. 406 * The new "child" thread descriptor is initialised from informations found in the "parent"413 * The new child thread descriptor is initialised from informations found in the parent 407 414 * thread descriptor. 408 415 ********************************************************************************************* … … 504 511 505 512 /********************************************************************************************* 506 * This function atomically registers a new thread in the local process descriptor. 507 * It checks that there is an available slot in the local th_tbl[] array, and allocates 508 * a new LTID using the relevant lock depending on the kernel/user type. 509 ********************************************************************************************* 510 * @ process : pointer on the local process descriptor. 511 * @ thread : pointer on new thread to be registered. 513 * This function atomically registers a new thread identified by the <thread> argument 514 * in the th_tbl[] array of the local process descriptor identified by the <process> 515 * argument. It checks that there is an available slot in the local th_tbl[] array, 516 * and allocates a new LTID using the relevant lock depending on the kernel/user type, 517 * and returns the global thread identifier in the <trdid> buffer. 518 ********************************************************************************************* 519 * @ process : [in] pointer on the local process descriptor. 520 * @ thread : [in] pointer on new thread to be registered. 512 521 * @ trdid : [out] buffer for allocated trdid. 513 522 * @ returns 0 if success / returns non zero if no slot available. … … 516 525 struct thread_s * thread, 517 526 trdid_t * trdid ); 527 528 /********************************************************************************************* 529 * This function atomically removes a thread identified by the <thread> argument from 530 * the local process descriptor th_tbl[] array, and returns the number of thread currently 531 * registered in th_tbl[] array before this remove. 532 ********************************************************************************************* 533 * @ thread : pointer on thread to be removed. 534 * @ returns number of threads registered in th_tbl before thread remove. 535 ********************************************************************************************/ 536 uint32_t process_remove_thread( struct thread_s * thread ); 518 537 519 538 … … 556 575 557 576 /********************************************************************************************* 558 * This function gives a process identified by the <process_xp> argument the exclusive577 * This function gives a process identified by the <process_xp> argument the 559 578 * ownership of its attached TXT_RX terminal (i.e. put the process in foreground). 560 * It can be called by a thread running in any cluster, but the <process_xp> must be the561 * owner cluster process descriptor.579 * It can be called by a thread running in any cluster, but the target process descriptor 580 * must be the process owner. 562 581 ********************************************************************************************* 563 582 * @ owner_xp : extended pointer on process descriptor in owner cluster. … … 566 585 567 586 /********************************************************************************************* 568 * When the process identified by the <owner_xp> argument has the exclusive ownership of 569 * the TXT_RX terminal, this function transfer this ownership to another attached process. 570 * The process descriptor must be the process owner. 571 * This function does nothing if the process identified by the <process_xp> is not 572 * the TXT owner. 587 * When the target process identified by the <owner_xp> argument has the exclusive ownership 588 * of the TXT_RX terminal, this function transfer this ownership to another process attached 589 * to the same terminal. The target process descriptor must be the process owner. 590 * This function does nothing if the target process is not the TXT owner. 573 591 * - If the current owner is not the KSH process, the new owner is the KSH process. 574 592 * - If the current owner is the KSH process, the new owner is another attached process. -
trunk/kernel/kern/rpc.c
r624 r625 24 24 #include <kernel_config.h> 25 25 #include <hal_kernel_types.h> 26 #include <hal_vmm.h> 26 27 #include <hal_atomic.h> 27 28 #include <hal_remote.h> … … 52 53 &rpc_pmem_get_pages_server, // 0 53 54 &rpc_pmem_release_pages_server, // 1 54 &rpc_ undefined, // 2 unused slot55 &rpc_ppm_display_server, // 2 55 56 &rpc_process_make_fork_server, // 3 56 57 &rpc_user_dir_create_server, // 4 … … 81 82 &rpc_vmm_create_vseg_server, // 27 82 83 &rpc_vmm_set_cow_server, // 28 83 &rpc_hal_vmm_display_server, 84 &rpc_hal_vmm_display_server, // 29 84 85 }; 85 86 … … 88 89 "PMEM_GET_PAGES", // 0 89 90 "PMEM_RELEASE_PAGES", // 1 90 " undefined",// 291 "PPM_DISPLAY", // 2 91 92 "PROCESS_MAKE_FORK", // 3 92 93 "USER_DIR_CREATE", // 4 … … 566 567 567 568 ///////////////////////////////////////////////////////////////////////////////////////// 568 // [2] undefined slot 569 ///////////////////////////////////////////////////////////////////////////////////////// 569 // [2] Marshaling functions attached to RPC_PPM_DISPLAY 570 ///////////////////////////////////////////////////////////////////////////////////////// 571 572 ///////////////////////////////////////// 573 void rpc_ppm_display_client( cxy_t cxy ) 574 { 575 #if DEBUG_RPC_PPM_DISPLAY 576 thread_t * this = CURRENT_THREAD; 577 uint32_t cycle = (uint32_t)hal_get_cycles(); 578 if( cycle > DEBUG_RPC_PPM_DISPLAY ) 579 printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", 580 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); 581 #endif 582 583 uint32_t responses = 1; 584 585 // initialise RPC descriptor header 586 rpc_desc_t rpc; 587 rpc.index = RPC_PPM_DISPLAY; 588 rpc.blocking = true; 589 rpc.rsp = &responses; 590 591 // register RPC request in remote RPC fifo 592 rpc_send( cxy , &rpc ); 593 594 #if DEBUG_RPC_PPM_DISPLAY 595 cycle = (uint32_t)hal_get_cycles(); 596 if( cycle > DEBUG_RPC_PPM_DISPLAY ) 597 printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", 598 __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); 599 #endif 600 } 601 602 //////////////////////////////////////////////////////////////////// 603 void rpc_ppm_display_server( xptr_t __attribute__((__unused__)) xp ) 604 { 605 #if DEBUG_RPC_PPM_DISPLAY 606 thread_t * this = CURRENT_THREAD; 607 uint32_t cycle = (uint32_t)hal_get_cycles(); 608 if( cycle > DEBUG_RPC_PPM_DISPLAY ) 609 printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", 610 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); 611 #endif 612 613 // call local kernel function 614 ppm_display(); 615 616 #if DEBUG_RPC_PPM_DISPLAY 617 cycle = (uint32_t)hal_get_cycles(); 618 if( cycle > DEBUG_RPC_PPM_DISPLAY ) 619 printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", 620 __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); 621 #endif 622 } 570 623 571 624 ///////////////////////////////////////////////////////////////////////////////////////// -
trunk/kernel/kern/rpc.h
r624 r625 62 62 RPC_PMEM_GET_PAGES = 0, 63 63 RPC_PMEM_RELEASE_PAGES = 1, 64 RPC_ UNDEFINED_2= 2,64 RPC_PPM_DISPLAY = 2, 65 65 RPC_PROCESS_MAKE_FORK = 3, 66 66 RPC_USER_DIR_CREATE = 4, … … 200 200 201 201 /*********************************************************************************** 202 * [2] undefined slot 203 **********************************************************************************/ 202 * [2] The RPC_PPM_DISPLAY allows any client thread to require any remote cluster 203 * identified by the <cxy> argumentto display the physical memory allocator state. 204 **********************************************************************************/ 205 void rpc_ppm_display_client( cxy_t cxy ); 206 207 void rpc_ppm_display_server( xptr_t xp ); 204 208 205 209 /*********************************************************************************** -
trunk/kernel/kern/scheduler.c
r624 r625 180 180 sched = &core->scheduler; 181 181 182 /////////////// scan user threads to handle both ACK and DELETE requests182 ////////////////// scan user threads to handle both ACK and DELETE requests 183 183 root = &sched->u_root; 184 184 iter = root->next; … … 240 240 busylock_release( &sched->lock ); 241 241 242 // check th_nr value 243 assert( (process->th_nr > 0) , "process th_nr cannot be 0\n" ); 244 245 // remove thread from process th_tbl[] 246 process->th_tbl[ltid] = NULL; 247 count = hal_atomic_add( &process->th_nr , - 1 ); 248 249 // release memory allocated for thread descriptor 250 thread_destroy( thread ); 242 // release memory allocated for thread 243 count = thread_destroy( thread ); 251 244 252 245 hal_fence(); … … 255 248 uint32_t cycle = (uint32_t)hal_get_cycles(); 256 249 if( DEBUG_SCHED_HANDLE_SIGNALS < cycle ) 257 printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted / cycle %d\n",258 __FUNCTION__ , process->pid , thread->trdid , local_cxy , thread->core->lid, cycle );250 printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted / %d threads / cycle %d\n", 251 __FUNCTION__, process->pid, thread->trdid, local_cxy, thread->core->lid, count, cycle ); 259 252 #endif 260 253 // destroy process descriptor if last thread … … 274 267 } // end user threads 275 268 276 ////// scan kernel threads for DELETE only269 ///////////// scan kernel threads for DELETE only 277 270 root = &sched->k_root; 278 271 iter = root->next; … … 290 283 291 284 // check process descriptor is local kernel process 292 assert( ( thread->process == &process_zero ) , "illegal process descriptor \n");285 assert( ( thread->process == &process_zero ) , "illegal process descriptor"); 293 286 294 287 // get thread ltid … … 325 318 326 319 // check th_nr value 327 assert( (process_zero.th_nr > 0) , "kernel process th_nr cannot be 0 \n" );320 assert( (process_zero.th_nr > 0) , "kernel process th_nr cannot be 0" ); 328 321 329 322 // remove thread from process th_tbl[] … … 477 470 } // end sched_register_thread() 478 471 479 ////////////////////////////////////// 480 void sched_yield( const char * cause )472 ////////////////////////////////////////////////////////////////// 473 void sched_yield( const char * cause __attribute__((__unused__)) ) 481 474 { 482 475 thread_t * next; … … 512 505 // check next thread kernel_stack overflow 513 506 assert( (next->signature == THREAD_SIGNATURE), 514 "kernel stack overflow for thread %x on core[%x,%d] \n", next, local_cxy, lid );507 "kernel stack overflow for thread %x on core[%x,%d]", next, local_cxy, lid ); 515 508 516 509 // check next thread attached to same core as the calling thread 517 510 assert( (next->core == current->core), 518 "next core %x != current core %x \n", next->core, current->core );511 "next core %x != current core %x", next->core, current->core ); 519 512 520 513 // check next thread not blocked when type != IDLE 521 514 assert( ((next->blocked == 0) || (next->type == THREAD_IDLE)) , 522 "next thread %x (%s) is blocked on core[%x,%d] \n",515 "next thread %x (%s) is blocked on core[%x,%d]", 523 516 next->trdid , thread_type_str(next->type) , local_cxy , lid ); 524 517 … … 561 554 #if (DEBUG_SCHED_YIELD & 1) 562 555 // if( sched->trace ) 563 if( uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD )556 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 564 557 printk("\n[%s] core[%x,%d] / cause = %s\n" 565 558 " thread %x (%s) (%x,%x) continue / cycle %d\n", … … 584 577 list_entry_t * iter; 585 578 thread_t * thread; 586 587 // check lid588 assert( (lid < LOCAL_CLUSTER->cores_nr),589 "illegal core index %d\n", lid);590 579 591 580 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; … … 644 633 { 645 634 thread_t * thread; 646 647 // check cxy648 assert( (cluster_is_undefined( cxy ) == false),649 "illegal cluster %x\n", cxy );650 651 assert( (lid < hal_remote_l32( XPTR( cxy , &LOCAL_CLUSTER->cores_nr ) ) ),652 "illegal core index %d\n", lid );653 635 654 636 // get local pointer on target scheduler -
trunk/kernel/kern/thread.c
r624 r625 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 29 29 #include <hal_special.h> 30 30 #include <hal_remote.h> 31 #include <hal_vmm.h> 31 32 #include <memcpy.h> 32 33 #include <printk.h> … … 96 97 97 98 ///////////////////////////////////////////////////////////////////////////////////// 98 // This static function releases the physical memory for a thread descriptor.99 // It is called by the three functions:100 // - thread_user_create()101 // - thread_user_fork()102 // - thread_kernel_create()103 /////////////////////////////////////////////////////////////////////////////////////104 // @ thread : pointer on thread descriptor.105 /////////////////////////////////////////////////////////////////////////////////////106 static void thread_release( thread_t * thread )107 {108 kmem_req_t req;109 110 xptr_t base_xp = ppm_base2page( XPTR(local_cxy , thread ) );111 112 req.type = KMEM_PAGE;113 req.ptr = GET_PTR( base_xp );114 kmem_free( &req );115 }116 117 /////////////////////////////////////////////////////////////////////////////////////118 99 // This static function initializes a thread descriptor (kernel or user). 119 100 // It can be called by the four functions: … … 122 103 // - thread_kernel_create() 123 104 // - thread_idle_init() 105 // The "type" and "trdid" fields must have been previously set. 124 106 // It updates the local DQDT. 125 107 ///////////////////////////////////////////////////////////////////////////////////// 126 // @ thread : pointer on local thread descriptor127 // @ process : pointer on local process descriptor.128 // @ type : thread type.129 // @ func : pointer on thread entry function.130 // @ args : pointer on thread entry function arguments.131 // @ core_lid : target core local index.132 // @ u_stack_base : stack base (user thread only)133 // @ u _stack_size : stack base(user thread only)108 // @ thread : pointer on local thread descriptor 109 // @ process : pointer on local process descriptor. 110 // @ type : thread type. 111 // @ trdid : thread identifier 112 // @ func : pointer on thread entry function. 113 // @ args : pointer on thread entry function arguments. 114 // @ core_lid : target core local index. 115 // @ user_stack_vseg : local pointer on user stack vseg (user thread only) 134 116 ///////////////////////////////////////////////////////////////////////////////////// 135 117 static error_t thread_init( thread_t * thread, 136 118 process_t * process, 137 119 thread_type_t type, 120 trdid_t trdid, 138 121 void * func, 139 122 void * args, 140 123 lid_t core_lid, 141 intptr_t u_stack_base, 142 uint32_t u_stack_size ) 143 { 144 error_t error; 145 trdid_t trdid; // allocated thread identifier 146 147 cluster_t * local_cluster = LOCAL_CLUSTER; 124 vseg_t * user_stack_vseg ) 125 { 126 127 // check type and trdid fields initialized 128 assert( (thread->type == type) , "bad type argument" ); 129 assert( (thread->trdid == trdid) , "bad trdid argument" ); 148 130 149 131 #if DEBUG_THREAD_INIT … … 152 134 if( DEBUG_THREAD_INIT < cycle ) 153 135 printk("\n[%s] thread[%x,%x] enter for thread %x in process %x / cycle %d\n", 154 __FUNCTION__, this->process->pid, this->trdid, thread , process->pid , cycle );136 __FUNCTION__, this->process->pid, this->trdid, thread->trdid, process->pid , cycle ); 155 137 #endif 156 138 … … 159 141 160 142 // Initialize new thread descriptor 161 thread->type = type;162 143 thread->quantum = 0; // TODO 163 144 thread->ticks_nr = 0; // TODO 164 145 thread->time_last_check = 0; // TODO 165 thread->core = & local_cluster->core_tbl[core_lid];146 thread->core = &LOCAL_CLUSTER->core_tbl[core_lid]; 166 147 thread->process = process; 167 168 148 thread->busylocks = 0; 169 149 … … 172 152 #endif 173 153 174 thread->u_stack_base = u_stack_base; 175 thread->u_stack_size = u_stack_size; 154 thread->user_stack_vseg = user_stack_vseg; 176 155 thread->k_stack_base = (intptr_t)thread + desc_size; 177 156 thread->k_stack_size = CONFIG_THREAD_DESC_SIZE - desc_size; 178 179 157 thread->entry_func = func; // thread entry point 180 158 thread->entry_args = args; // thread function arguments … … 185 163 thread->blocked = THREAD_BLOCKED_GLOBAL; 186 164 187 // register new thread in process descriptor, and get a TRDID188 error = process_register_thread( process, thread , &trdid );189 190 if( error )191 {192 printk("\n[ERROR] in %s : thread %x in process %x cannot get TRDID in cluster %x\n"193 " for thread %s in process %x / cycle %d\n",194 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,195 local_cxy, thread_type_str(type), process->pid, (uint32_t)hal_get_cycles() );196 return EINVAL;197 }198 199 // initialize trdid200 thread->trdid = trdid;201 202 165 // initialize sched list 203 166 list_entry_init( &thread->sched_list ); … … 237 200 } // end thread_init() 238 201 239 ////////////////////////////////////////////////// ///////202 ////////////////////////////////////////////////// 240 203 error_t thread_user_create( pid_t pid, 241 204 void * start_func, … … 246 209 error_t error; 247 210 thread_t * thread; // pointer on created thread descriptor 211 trdid_t trdid; // created thred identifier 248 212 process_t * process; // pointer to local process descriptor 249 213 lid_t core_lid; // selected core local index 250 vseg_t * vseg; //stack vseg214 vseg_t * us_vseg; // user stack vseg 251 215 252 216 assert( (attr != NULL) , "pthread attributes must be defined" ); … … 266 230 { 267 231 printk("\n[ERROR] in %s : cannot get process descriptor %x\n", 268 269 return ENOMEM;232 __FUNCTION__ , pid ); 233 return -1; 270 234 } 271 235 … … 284 248 printk("\n[ERROR] in %s : illegal core index attribute = %d\n", 285 249 __FUNCTION__ , core_lid ); 286 return EINVAL;250 return -1; 287 251 } 288 252 } … … 298 262 #endif 299 263 300 // allocate a stack from local VMM301 vseg = vmm_create_vseg( process,302 VSEG_TYPE_STACK,303 0, // size unused304 0, // length unused305 0, // file_offset unused306 0, // file_size unused307 XPTR_NULL, // mapper_xp unused308 local_cxy );309 310 if( vseg == NULL )311 {312 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );313 return ENOMEM;314 }315 316 #if( DEBUG_THREAD_USER_CREATE & 1)317 if( DEBUG_THREAD_USER_CREATE < cycle )318 printk("\n[%s] stack vseg created / vpn_base %x / %d pages\n",319 __FUNCTION__, vseg->vpn_base, vseg->vpn_size );320 #endif321 322 264 // allocate memory for thread descriptor 323 265 thread = thread_alloc(); … … 325 267 if( thread == NULL ) 326 268 { 327 printk("\n[ERROR] in %s : cannot create new thread \n", __FUNCTION__ );328 vmm_delete_vseg( process->pid , vseg->min);329 return ENOMEM;269 printk("\n[ERROR] in %s : cannot create new thread in cluster %x\n", 270 __FUNCTION__, local_cxy ); 271 return -1; 330 272 } 331 273 … … 336 278 #endif 337 279 280 // set type in thread descriptor 281 thread->type = THREAD_USER; 282 283 // register new thread in process descriptor, and get a TRDID 284 error = process_register_thread( process, thread , &trdid ); 285 286 if( error ) 287 { 288 printk("\n[ERROR] in %s : cannot register new thread in process %x\n", 289 __FUNCTION__, pid ); 290 thread_destroy( thread ); 291 return -1; 292 } 293 294 // set trdid in thread descriptor 295 thread->trdid = trdid; 296 297 #if( DEBUG_THREAD_USER_CREATE & 1) 298 if( DEBUG_THREAD_USER_CREATE < cycle ) 299 printk("\n[%s] new thread %x registered in process %x\n", 300 __FUNCTION__, trdid, pid ); 301 #endif 302 303 // allocate a stack from local VMM 304 us_vseg = vmm_create_vseg( process, 305 VSEG_TYPE_STACK, 306 LTID_FROM_TRDID( trdid ), 307 0, // size unused 308 0, // file_offset unused 309 0, // file_size unused 310 XPTR_NULL, // mapper_xp unused 311 local_cxy ); 312 313 if( us_vseg == NULL ) 314 { 315 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 316 process_remove_thread( thread ); 317 thread_destroy( thread ); 318 return -1; 319 } 320 321 #if( DEBUG_THREAD_USER_CREATE & 1) 322 if( DEBUG_THREAD_USER_CREATE < cycle ) 323 printk("\n[%s] stack vseg created / vpn_base %x / %d pages\n", 324 __FUNCTION__, us_vseg->vpn_base, us_vseg->vpn_size ); 325 #endif 326 338 327 // initialize thread descriptor 339 328 error = thread_init( thread, 340 329 process, 341 330 THREAD_USER, 331 trdid, 342 332 start_func, 343 333 start_arg, 344 334 core_lid, 345 vseg->min, 346 vseg->max - vseg->min ); 335 us_vseg ); 347 336 if( error ) 348 337 { 349 338 printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ ); 350 vmm_delete_vseg( process->pid , vseg->min ); 351 thread_release( thread ); 352 return EINVAL; 339 vmm_remove_vseg( process , us_vseg ); 340 process_remove_thread( thread ); 341 thread_destroy( thread ); 342 return -1; 353 343 } 354 344 355 345 #if( DEBUG_THREAD_USER_CREATE & 1) 356 346 if( DEBUG_THREAD_USER_CREATE < cycle ) 357 printk("\n[%s] new thread descriptor initialised / trdid %x\n",358 __FUNCTION__, thread->trdid );347 printk("\n[%s] new thread %x in process %x initialised\n", 348 __FUNCTION__, thread->trdid, process->pid ); 359 349 #endif 360 350 … … 369 359 { 370 360 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 371 vmm_delete_vseg( process->pid , vseg->min ); 372 thread_release( thread ); 373 return ENOMEM; 361 vmm_remove_vseg( process , us_vseg ); 362 process_remove_thread( thread ); 363 thread_destroy( thread ); 364 return -1; 374 365 } 375 366 hal_cpu_context_init( thread ); … … 379 370 { 380 371 printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ ); 381 vmm_delete_vseg( process->pid , vseg->min ); 382 thread_release( thread ); 383 return ENOMEM; 372 vmm_remove_vseg( process , us_vseg ); 373 process_remove_thread( thread ); 374 thread_destroy( thread ); 375 return -1; 384 376 } 385 377 hal_fpu_context_init( thread ); … … 410 402 { 411 403 error_t error; 412 thread_t * child_ptr; // local pointer on local child thread 404 thread_t * child_ptr; // local pointer on child thread 405 trdid_t child_trdid; // child thread identifier 413 406 lid_t core_lid; // selected core local index 414 415 407 thread_t * parent_ptr; // local pointer on remote parent thread 416 408 cxy_t parent_cxy; // parent thread cluster 417 409 process_t * parent_process; // local pointer on parent process 418 410 xptr_t parent_gpt_xp; // extended pointer on parent thread GPT 419 420 void * func; // parent thread entry_func 421 void * args; // parent thread entry_args 422 intptr_t base; // parent thread u_stack_base 423 uint32_t size; // parent thread u_stack_size 424 uint32_t flags; // parent_thread flags 425 vpn_t vpn_base; // parent thread stack vpn_base 426 vpn_t vpn_size; // parent thread stack vpn_size 427 reg_t * uzone; // parent thread pointer on uzone 428 429 vseg_t * vseg; // child thread STACK vseg 411 void * parent_func; // parent thread entry_func 412 void * parent_args; // parent thread entry_args 413 uint32_t parent_flags; // parent_thread flags 414 vseg_t * parent_us_vseg; // parent thread user stack vseg 415 vseg_t * child_us_vseg; // child thread user stack vseg 430 416 431 417 #if DEBUG_THREAD_USER_FORK … … 433 419 thread_t * this = CURRENT_THREAD; 434 420 if( DEBUG_THREAD_USER_FORK < cycle ) 435 printk("\n[%s] thread[%x,%x] enter /child_process %x / cycle %d\n",421 printk("\n[%s] thread[%x,%x] enter for child_process %x / cycle %d\n", 436 422 __FUNCTION__, this->process->pid, this->trdid, child_process->pid, cycle ); 437 423 #endif … … 439 425 // select a target core in local cluster 440 426 core_lid = cluster_select_local_core(); 427 428 #if (DEBUG_THREAD_USER_FORK & 1) 429 if( DEBUG_THREAD_USER_FORK < cycle ) 430 printk("\n[%s] thread[%x,%x] selected core [%x,%d]\n", 431 __FUNCTION__, this->process->pid, this->trdid, local_cxy, core_lid ); 432 #endif 441 433 442 434 // get cluster and local pointer on parent thread descriptor … … 444 436 parent_ptr = GET_PTR( parent_thread_xp ); 445 437 446 // get relevant fields from parent thread 447 func = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func )); 448 args = (void *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args )); 449 base = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base )); 450 size = (uint32_t)hal_remote_l32 ( XPTR( parent_cxy , &parent_ptr->u_stack_size )); 451 flags = hal_remote_l32 ( XPTR( parent_cxy , &parent_ptr->flags )); 452 uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone_current )); 453 454 vpn_base = base >> CONFIG_PPM_PAGE_SHIFT; 455 vpn_size = size >> CONFIG_PPM_PAGE_SHIFT; 438 // get relevant infos from parent thread 439 parent_func = (void *) hal_remote_lpt( XPTR(parent_cxy,&parent_ptr->entry_func )); 440 parent_args = (void *) hal_remote_lpt( XPTR(parent_cxy,&parent_ptr->entry_args )); 441 parent_flags = (uint32_t)hal_remote_l32( XPTR(parent_cxy,&parent_ptr->flags )); 442 parent_us_vseg = (vseg_t *)hal_remote_lpt( XPTR(parent_cxy,&parent_ptr->user_stack_vseg )); 456 443 457 444 // get pointer on parent process in parent thread cluster … … 459 446 &parent_ptr->process ) ); 460 447 461 // getextended pointer on parent GPT in parent thread cluster448 // build extended pointer on parent GPT in parent thread cluster 462 449 parent_gpt_xp = XPTR( parent_cxy , &parent_process->vmm.gpt ); 450 451 #if (DEBUG_THREAD_USER_FORK & 1) 452 if( DEBUG_THREAD_USER_FORK < cycle ) 453 printk("\n[%s] thread[%x,%x] get parent GPT\n", 454 __FUNCTION__, this->process->pid, this->trdid ); 455 #endif 463 456 464 457 // allocate memory for child thread descriptor 465 458 child_ptr = thread_alloc(); 459 466 460 if( child_ptr == NULL ) 467 461 { 468 printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ ); 462 printk("\n[ERROR] in %s : cannot allocate new thread\n", 463 __FUNCTION__ ); 469 464 return -1; 470 465 } 466 467 #if (DEBUG_THREAD_USER_FORK & 1) 468 if( DEBUG_THREAD_USER_FORK < cycle ) 469 printk("\n[%s] thread[%x,%x] allocated new thread descriptor %x\n", 470 __FUNCTION__, this->process->pid, this->trdid, child_ptr ); 471 #endif 472 473 // set type in thread descriptor 474 child_ptr->type = THREAD_USER; 475 476 // register new thread in process descriptor, and get a TRDID 477 error = process_register_thread( child_process, child_ptr , &child_trdid ); 478 479 if( error ) 480 { 481 printk("\n[ERROR] in %s : cannot register new thread in process %x\n", 482 __FUNCTION__, child_process->pid ); 483 thread_destroy( child_ptr ); 484 return -1; 485 } 486 487 // set trdid in thread descriptor 488 child_ptr->trdid = child_trdid; 489 490 #if (DEBUG_THREAD_USER_FORK & 1) 491 if( DEBUG_THREAD_USER_FORK < cycle ) 492 printk("\n[%s] thread[%x,%x] registered child thread %x in child process %x\n", 493 __FUNCTION__, this->process->pid, this->trdid, child_trdid, child_process->pid ); 494 #endif 495 496 // get an user stack vseg from local VMM allocator 497 child_us_vseg = vmm_create_vseg( child_process, 498 VSEG_TYPE_STACK, 499 LTID_FROM_TRDID( child_trdid ), 500 0, // size unused 501 0, // file_offset unused 502 0, // file_size unused 503 XPTR_NULL, // mapper_xp unused 504 local_cxy ); 505 if( child_us_vseg == NULL ) 506 { 507 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 508 process_remove_thread( child_ptr ); 509 thread_destroy( child_ptr ); 510 return -1; 511 } 512 513 #if (DEBUG_THREAD_USER_FORK & 1) 514 if( DEBUG_THREAD_USER_FORK < cycle ) 515 printk("\n[%s] thread[%x,%x] created an user stack vseg / vpn_base %x / %d pages\n", 516 __FUNCTION__, this->process->pid, this->trdid, 517 child_us_vseg->vpn_base, child_us_vseg->vpn_size ); 518 #endif 471 519 472 520 // initialize thread descriptor … … 474 522 child_process, 475 523 THREAD_USER, 476 func, 477 args, 524 child_trdid, 525 parent_func, 526 parent_args, 478 527 core_lid, 479 base, 480 size ); 528 child_us_vseg ); 481 529 if( error ) 482 530 { 483 531 printk("\n[ERROR] in %s : cannot initialize child thread\n", __FUNCTION__ ); 484 thread_release( child_ptr ); 485 return EINVAL; 532 vmm_remove_vseg( child_process , child_us_vseg ); 533 process_remove_thread( child_ptr ); 534 thread_destroy( child_ptr ); 535 return -1; 486 536 } 487 537 … … 492 542 #endif 493 543 494 // return child pointer495 *child_thread = child_ptr;496 497 544 // set detached flag if required 498 if( flags & THREAD_FLAG_DETACHED ) child_ptr->flags = THREAD_FLAG_DETACHED; 499 500 // update uzone pointer in child thread descriptor 501 child_ptr->uzone_current = (char *)((intptr_t)uzone + 502 (intptr_t)child_ptr - 503 (intptr_t)parent_ptr ); 504 505 506 // allocate CPU context for child thread 545 if( parent_flags & THREAD_FLAG_DETACHED ) child_ptr->flags = THREAD_FLAG_DETACHED; 546 547 // allocate a CPU context for child thread 507 548 if( hal_cpu_context_alloc( child_ptr ) ) 508 549 { 509 550 printk("\n[ERROR] in %s : cannot allocate CPU context\n", __FUNCTION__ ); 510 thread_release( child_ptr ); 551 vmm_remove_vseg( child_process , child_us_vseg ); 552 process_remove_thread( child_ptr ); 553 thread_destroy( child_ptr ); 511 554 return -1; 512 555 } 513 556 514 // allocate FPU context for child thread557 // allocate a FPU context for child thread 515 558 if( hal_fpu_context_alloc( child_ptr ) ) 516 559 { 517 560 printk("\n[ERROR] in %s : cannot allocate FPU context\n", __FUNCTION__ ); 518 thread_release( child_ptr ); 561 vmm_remove_vseg( child_process , child_us_vseg ); 562 process_remove_thread( child_ptr ); 563 thread_destroy( child_ptr ); 519 564 return -1; 520 565 } … … 526 571 #endif 527 572 528 // create and initialize STACK vseg 529 vseg = vseg_alloc(); 530 vseg_init( vseg, 531 VSEG_TYPE_STACK, 532 base, 533 size, 534 vpn_base, 535 vpn_size, 536 0, 0, XPTR_NULL, // not a file vseg 537 local_cxy ); 538 539 // register STACK vseg in local child VSL 540 vmm_attach_vseg_to_vsl( &child_process->vmm , vseg ); 541 542 #if (DEBUG_THREAD_USER_FORK & 1) 543 if( DEBUG_THREAD_USER_FORK < cycle ) 544 printk("\n[%s] thread[%x,%x] created stack vseg for thread %x in process %x\n", 545 __FUNCTION__, this->process->pid, this->trdid, child_ptr->trdid, child_process->pid ); 546 #endif 547 548 // copy all valid STACK GPT entries 549 vpn_t vpn; 550 bool_t mapped; 551 ppn_t ppn; 552 for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ ) 573 // scan parent GPT, and copy all valid entries 574 // associated to user stack vseg into child GPT 575 vpn_t parent_vpn; 576 vpn_t child_vpn; 577 bool_t mapped; 578 ppn_t ppn; 579 vpn_t parent_vpn_base = hal_remote_l32( XPTR( parent_cxy, &parent_us_vseg->vpn_base ) ); 580 vpn_t parent_vpn_size = hal_remote_l32( XPTR( parent_cxy, &parent_us_vseg->vpn_size ) ); 581 vpn_t child_vpn_base = child_us_vseg->vpn_base; 582 for( parent_vpn = parent_vpn_base , child_vpn = child_vpn_base ; 583 parent_vpn < (parent_vpn_base + parent_vpn_size) ; 584 parent_vpn++ , child_vpn++ ) 553 585 { 554 586 error = hal_gpt_pte_copy( &child_process->vmm.gpt, 587 child_vpn, 555 588 parent_gpt_xp, 556 vpn,589 parent_vpn, 557 590 true, // set cow 558 591 &ppn, … … 560 593 if( error ) 561 594 { 562 vmm_detach_vseg_from_vsl( &child_process->vmm , vseg );563 thread_release( child_ptr );564 595 printk("\n[ERROR] in %s : cannot update child GPT\n", __FUNCTION__ ); 596 vmm_remove_vseg( child_process , child_us_vseg ); 597 process_remove_thread( child_ptr ); 598 thread_destroy( child_ptr ); 565 599 return -1; 566 600 } 567 601 568 // increment pending forks counter for the page if mapped602 // increment pending forks counter for a mapped page 569 603 if( mapped ) 570 604 { … … 574 608 page_t * page_ptr = GET_PTR( page_xp ); 575 609 576 // getextended pointers on forks and lock fields610 // build extended pointers on forks and lock fields 577 611 xptr_t forks_xp = XPTR( page_cxy , &page_ptr->forks ); 578 612 xptr_t lock_xp = XPTR( page_cxy , &page_ptr->lock ); … … 586 620 // release lock protecting page 587 621 remote_busylock_release( lock_xp ); 622 } 623 } 588 624 589 625 #if (DEBUG_THREAD_USER_FORK & 1) 590 cycle = (uint32_t)hal_get_cycles();591 626 if( DEBUG_THREAD_USER_FORK < cycle ) 592 printk("\n[%s] thread[%x,%x] copied one PTE to child GPT : vpn %x / forks %d\n", 593 __FUNCTION__, this->process->pid, this->trdid, 594 vpn, hal_remote_l32( XPTR( page_cxy , &page_ptr->forks) ) ); 595 #endif 596 597 } 598 } 599 600 // set COW flag for all mapped entries of STAK vseg in parent thread GPT 627 printk("\n[%s] thread[%x,%x] copied all stack vseg PTEs to child GPT\n", 628 __FUNCTION__, this->process->pid, this->trdid ); 629 #endif 630 631 // set COW flag for all mapped entries of user stack vseg in parent GPT 601 632 hal_gpt_set_cow( parent_gpt_xp, 602 vpn_base, 603 vpn_size ); 604 633 parent_vpn_base, 634 parent_vpn_size ); 635 636 #if (DEBUG_THREAD_USER_FORK & 1) 637 if( DEBUG_THREAD_USER_FORK < cycle ) 638 printk("\n[%s] thread[%x,%x] set the COW flag for stack vseg in parent GPT\n", 639 __FUNCTION__, this->process->pid, this->trdid ); 640 #endif 641 642 // return child pointer 643 *child_thread = child_ptr; 644 605 645 #if DEBUG_THREAD_USER_FORK 606 646 cycle = (uint32_t)hal_get_cycles(); 607 647 if( DEBUG_THREAD_USER_FORK < cycle ) 608 printk("\n[%s] thread[%x,%x] exit / child_thread %x / cycle %d\n", 609 __FUNCTION__, this->process->pid, this->trdid, child_ptr, cycle ); 648 printk("\n[%s] thread[%x,%x] exit / created thread[%x,%x] / cycle %d\n", 649 __FUNCTION__, this->process->pid, this->trdid, 650 child_ptr->process->pid, child_ptr->trdid, cycle ); 610 651 #endif 611 652 … … 660 701 661 702 // allocate an user stack vseg for main thread 662 vseg_t * vseg = vmm_create_vseg( process,663 VSEG_TYPE_STACK,664 0, // size unused665 0, // length unused666 0, // file_offset unused667 0, // file_size unused668 XPTR_NULL, // mapper_xp unused669 local_cxy );670 if( vseg == NULL )703 vseg_t * us_vseg = vmm_create_vseg( process, 704 VSEG_TYPE_STACK, 705 LTID_FROM_TRDID( thread->trdid ), 706 0, // length unused 707 0, // file_offset unused 708 0, // file_size unused 709 XPTR_NULL, // mapper_xp unused 710 local_cxy ); 711 if( us_vseg == NULL ) 671 712 { 672 713 printk("\n[ERROR] in %s : cannot create stack vseg for main thread\n", __FUNCTION__ ); … … 675 716 676 717 // update user stack in thread descriptor 677 thread->u_stack_base = vseg->min; 678 thread->u_stack_size = vseg->max - vseg->min; 718 thread->user_stack_vseg = us_vseg; 679 719 680 720 // release FPU ownership if required … … 710 750 error_t error; 711 751 thread_t * thread; // pointer on new thread descriptor 752 trdid_t trdid; // new thread identifier 712 753 713 754 thread_t * this = CURRENT_THREAD; … … 737 778 } 738 779 780 // set type in thread descriptor 781 thread->type = type; 782 783 // register new thread in local kernel process descriptor, and get a TRDID 784 error = process_register_thread( &process_zero , thread , &trdid ); 785 786 if( error ) 787 { 788 printk("\n[ERROR] in %s : cannot register thread in kernel process\n", __FUNCTION__ ); 789 return -1; 790 } 791 792 // set trdid in thread descriptor 793 thread->trdid = trdid; 794 739 795 // initialize thread descriptor 740 796 error = thread_init( thread, 741 797 &process_zero, 742 798 type, 799 trdid, 743 800 func, 744 801 args, 745 802 core_lid, 746 0 , 0); // no user stack for a kernel thread803 NULL ); // no user stack for a kernel thread 747 804 748 805 if( error ) // release allocated memory for thread descriptor 749 806 { 750 printk("\n[ERROR] in %s : thread %x in process %x\n" 751 " cannot initialize thread descriptor\n", 752 __FUNCTION__, this->trdid, this->process->pid ); 753 thread_release( thread ); 807 printk("\n[ERROR] in %s : cannot initialize thread descriptor\n", __FUNCTION__ ); 808 thread_destroy( thread ); 754 809 return ENOMEM; 755 810 } … … 763 818 " cannot create CPU context\n", 764 819 __FUNCTION__, this->trdid, this->process->pid ); 765 thread_ release( thread );820 thread_destroy( thread ); 766 821 return EINVAL; 767 822 } … … 791 846 lid_t core_lid ) 792 847 { 848 trdid_t trdid; 849 error_t error; 793 850 794 851 // check arguments … … 796 853 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , "illegal core index" ); 797 854 855 // set type in thread descriptor 856 thread->type = THREAD_IDLE; 857 858 // register idle thread in local kernel process descriptor, and get a TRDID 859 error = process_register_thread( &process_zero , thread , &trdid ); 860 861 assert( (error == 0), "cannot register idle_thread in kernel process" ); 862 863 // set trdid in thread descriptor 864 thread->trdid = trdid; 865 798 866 // initialize thread descriptor 799 error_t error = thread_init( thread, 800 &process_zero, 801 type, 802 func, 803 args, 804 core_lid, 805 0 , 0 ); // no user stack for a kernel thread 806 807 assert( (error == 0), "cannot create thread idle" ); 867 error = thread_init( thread, 868 &process_zero, 869 THREAD_IDLE, 870 trdid, 871 func, 872 args, 873 core_lid, 874 NULL ); // no user stack for a kernel thread 875 876 assert( (error == 0), "cannot initialize idle_thread" ); 808 877 809 878 // allocate & initialize CPU context if success 810 879 error = hal_cpu_context_alloc( thread ); 811 880 812 881 assert( (error == 0), "cannot allocate CPU context" ); 813 882 814 883 hal_cpu_context_init( thread ); … … 816 885 } // end thread_idle_init() 817 886 818 /////////////////////////////////////////////////////////////////////////////////////// 819 // TODO: check that all memory dynamically allocated during thread execution 820 // has been released => check vmm destroy for MMAP vsegs [AG] 821 /////////////////////////////////////////////////////////////////////////////////////// 822 void thread_destroy( thread_t * thread ) 823 { 824 reg_t save_sr; 825 826 process_t * process = thread->process; 827 core_t * core = thread->core; 887 //////////////////////////////////////////// 888 uint32_t thread_destroy( thread_t * thread ) 889 { 890 reg_t save_sr; 891 uint32_t count; 892 893 thread_type_t type = thread->type; 894 process_t * process = thread->process; 895 core_t * core = thread->core; 828 896 829 897 #if DEBUG_THREAD_DESTROY … … 835 903 #endif 836 904 837 // check busylocks counter905 // check calling thread busylocks counter 838 906 thread_assert_can_yield( thread , __FUNCTION__ ); 839 907 840 // update intrumentation values908 // update target process instrumentation counter 841 909 process->vmm.pgfault_nr += thread->info.pgfault_nr; 842 910 843 // release memory allocated for CPU context and FPU context 911 // remove thread from process th_tbl[] 912 count = process_remove_thread( thread ); 913 914 // release memory allocated for CPU context and FPU context if required 844 915 hal_cpu_context_destroy( thread ); 845 if ( thread->type == THREAD_USER )hal_fpu_context_destroy( thread );916 hal_fpu_context_destroy( thread ); 846 917 918 // release user stack vseg (for an user thread only) 919 if( type == THREAD_USER ) vmm_remove_vseg( process , thread->user_stack_vseg ); 920 847 921 // release FPU ownership if required 848 922 hal_disable_irq( &save_sr ); … … 857 931 thread->signature = 0; 858 932 859 // release memory for thread descriptor 860 thread_release( thread ); 933 // release memory for thread descriptor (including kernel stack) 934 kmem_req_t req; 935 xptr_t base_xp = ppm_base2page( XPTR(local_cxy , thread ) ); 936 937 req.type = KMEM_PAGE; 938 req.ptr = GET_PTR( base_xp ); 939 kmem_free( &req ); 861 940 862 941 #if DEBUG_THREAD_DESTROY … … 866 945 __FUNCTION__, this->process->pid, this->trdid, process->pid, thread->trdid, cycle ); 867 946 #endif 947 948 return count; 868 949 869 950 } // end thread_destroy() … … 993 1074 cxy_t target_cxy; // target thread cluster 994 1075 thread_t * target_ptr; // pointer on target thread 1076 process_t * target_process; // pointer on arget process 1077 pid_t target_pid; // target process identifier 995 1078 xptr_t target_flags_xp; // extended pointer on target thread <flags> 996 1079 xptr_t target_join_lock_xp; // extended pointer on target thread <join_lock> … … 1006 1089 target_ptr = GET_PTR( target_xp ); 1007 1090 1008 // get target thread identifier s, and attached flag1091 // get target thread identifier, attached flag, and process PID 1009 1092 target_trdid = hal_remote_l32( XPTR( target_cxy , &target_ptr->trdid ) ); 1010 1093 target_ltid = LTID_FROM_TRDID( target_trdid ); 1011 1094 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 1012 1095 target_attached = ( (hal_remote_l32( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0 ); 1096 target_process = hal_remote_lpt( XPTR( target_cxy , &target_ptr->process ) ); 1097 target_pid = hal_remote_l32( XPTR( target_cxy , &target_process->pid ) ); 1098 1099 // check target PID 1100 assert( (pid == target_pid), 1101 "unconsistent pid and target_xp arguments" ); 1013 1102 1014 1103 // get killer thread pointers … … 1027 1116 // must be deleted by the parent process sys_wait() function 1028 1117 assert( ((CXY_FROM_PID( pid ) != target_cxy) || (target_ltid != 0)), 1029 "t harget thread cannot be the main thread\n" );1118 "target thread cannot be the main thread" ); 1030 1119 1031 1120 // check killer thread can yield … … 1151 1240 void thread_idle_func( void ) 1152 1241 { 1242 1243 #if DEBUG_THREAD_IDLE 1244 uint32_t cycle; 1245 #endif 1246 1153 1247 while( 1 ) 1154 1248 { … … 1161 1255 1162 1256 #if DEBUG_THREAD_IDLE 1163 { 1164 uint32_t cycle = (uint32_t)hal_get_cycles(); 1257 cycle = (uint32_t)hal_get_cycles(); 1165 1258 if( DEBUG_THREAD_IDLE < cycle ) 1166 1259 printk("\n[%s] idle thread on core[%x,%d] goes to sleep / cycle %d\n", 1167 1260 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cycle ); 1168 }1169 1261 #endif 1170 1262 … … 1172 1264 1173 1265 #if DEBUG_THREAD_IDLE 1174 { 1175 uint32_t cycle = (uint32_t)hal_get_cycles(); 1266 cycle = (uint32_t)hal_get_cycles(); 1176 1267 if( DEBUG_THREAD_IDLE < cycle ) 1177 1268 printk("\n[%s] idle thread on core[%x,%d] wake up / cycle %d\n", 1178 1269 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cycle ); 1179 }1180 1270 #endif 1181 1271 … … 1183 1273 1184 1274 #if DEBUG_THREAD_IDLE 1185 { 1186 uint32_t cycle = (uint32_t)hal_get_cycles(); 1275 cycle = (uint32_t)hal_get_cycles(); 1187 1276 if( DEBUG_THREAD_IDLE < cycle ) 1188 1277 sched_display( CURRENT_THREAD->core->lid ); 1189 }1190 1278 #endif 1191 1279 // search a runable thread -
trunk/kernel/kern/thread.h
r619 r625 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 29 29 #include <shared_syscalls.h> 30 30 #include <hal_special.h> 31 #include <hal_kentry.h> 31 32 #include <xlist.h> 32 33 #include <list.h> … … 100 101 { 101 102 uint32_t pgfault_nr; /*! cumulated number of page fault */ 102 uint32_t sched_nr; /*! TODO ??? [AG] */103 uint32_t u_err_nr; /*! TODO ??? [AG] */104 uint32_t m_err_nr; /*! TODO ??? [AG] */105 103 cycle_t last_cycle; /*! last cycle counter value (date) */ 106 104 cycle_t usr_cycles; /*! user execution duration (cycles) */ … … 121 119 * 122 120 * WARNING (1) Don't modify the first 4 fields order, as this order is used by the 123 * hal_kentry assembly code for some architectures (TSAR).121 * hal_kentry assembly code for the TSAR architectures. 124 122 * 125 123 * WARNING (2) Most of the thread state is private and accessed only by this thread, … … 165 163 uint32_t * ack_rsp_count; /*! pointer on acknowledge response counter */ 166 164 167 intptr_t u_stack_base; /*! user stack base address */ 168 uint32_t u_stack_size; /*! user stack size (bytes) */ 165 vseg_t * user_stack_vseg; /*! local pointer on user stack vseg */ 169 166 170 167 void * entry_func; /*! pointer on entry function */ … … 248 245 249 246 /*************************************************************************************** 250 * This function is used by the sys_fork() system call to create the "child" thread 251 * in the local cluster. It allocates memory for a thread descriptor, and initializes 252 * it from the "parent" thread descriptor defined by the <parent_thread_xp> argument. 247 * This function is used by the sys_fork() syscall to create the "child" main thread 248 * in the local cluster. It is called, generally through the RPC_PROCESS_MAKE_FORK, 249 * by the process_make_fork() function. It allocates memory from the local cluster 250 * for a "child" thread descriptor, and initializes it from the "parent" thread 251 * descriptor defined by the <parent_thread_xp> argument. 253 252 * The new thread is attached to the core that has the lowest load in local cluster. 254 253 * It is registered in the "child" process defined by the <child_process> argument. … … 259 258 * uses physical addressing on some architectures). 260 259 * The CPU and FPU execution contexts are created and linked to the new thread. 261 * but the actual context copy is NOT done, and must be done by by the sys_fork().260 * but the actual context copy is NOT done, and is done by the sys_fork() function. 262 261 * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated to start. 263 262 *************************************************************************************** … … 273 272 /*************************************************************************************** 274 273 * This function is called by the process_make_exec() function to re-initialise the 275 * thread descriptor of the calling thread (that will become the new process main 276 * thread), and immediately jump to user code without returning to kentry!!! 274 * calling thread descriptor, that will become the new process main thread. 277 275 * It must be called by the main thread of the calling process. 276 * - The calling thread TRDID is not modified. 277 * - The kernel stack (currently in use) is not modified. 278 278 * - A new user stack vseg is created and initialised. 279 * - The kernel stack (currently in use) is not modified.280 279 * - The function calls the hal_cpu_context_exec() to re-initialize the CPU context 281 * an jump to user code.280 * and the uzone registered in kernel stack, an jump to user code. 282 281 *************************************************************************************** 283 282 * @ entry_func : main thread entry point. … … 329 328 330 329 /*************************************************************************************** 331 * This low-level function is called by the sched_handle_signals() function to releases 332 * the physical memory allocated for a thread in a given cluster, when this thread 333 * is marked for delete. This include the thread descriptor itself, the associated 334 * CPU and FPU context, and the physical memory allocated for an user thread local stack. 330 * This low-level function is called by the sched_handle_signals() function when a 331 * thread is marked for delete. It removes the thread identified by the <thread> 332 * argument from the process th_tbl[], and releases all physical memory allocated for 333 * this. This includes the thread descriptor itself, the associated CPU and FPU context, 334 * and the physical memory allocated for an user thread stack. 335 335 *************************************************************************************** 336 336 * @ thread : pointer on the thread descriptor to release. 337 * @ return t rue, if the thread was the last registerd thread in local process.338 **************************************************************************************/ 339 voidthread_destroy( thread_t * thread );337 * @ return the number of threads registered in the process th_tbl[] before deletion. 338 **************************************************************************************/ 339 uint32_t thread_destroy( thread_t * thread ); 340 340 341 341 /*************************************************************************************** … … 383 383 * This function is used by the four sys_thread_cancel(), sys_thread_exit(), 384 384 * sys_kill() and sys_exit() system calls to mark for delete a given thread. 385 * It set the THREAD_BLOCKED_GLOBAL bit and set the the THREAD_FLAG_REQ_DELETE bit386 * in thethread descriptor identified by the <thread_xp> argument, to ask the scheduler385 * It set the THREAD_BLOCKED_GLOBAL bit and set the THREAD_FLAG_REQ_DELETE bit in the 386 * thread descriptor identified by the <thread_xp> argument, to ask the scheduler 387 387 * to asynchronously delete the target thread, at the next scheduling point. 388 * The calling thread can run in any cluster, as it uses remote accesses, but 389 * the target thread cannot be the main thread of the process identified by the <pid> 390 * argument, because the main thread must be deleted by the parent process argument. 388 * The calling thread can run in any cluster, as it uses remote accesses. 389 * This function makes a kernel panic if the target thread is the main thread, 390 * because * the main thread deletion will cause the process deletion, and a process 391 * must be deleted by the parent process, running the wait function. 391 392 * If the target thread is running in "attached" mode, and the <is_forced> argument 392 393 * is false, this function implements the required sychronisation with the joining
Note: See TracChangeset
for help on using the changeset viewer.