- Timestamp:
- Mar 7, 2018, 9:02:03 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 50 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/drivers/soclib_bdv.c
r408 r436 132 132 else // descheduling + IRQ policy 133 133 { 134 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );134 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 135 135 sched_yield("blocked on ISR"); 136 136 … … 173 173 174 174 // unblock server thread 175 thread_unblock( server_xp , THREAD_BLOCKED_ DEV_ISR );175 thread_unblock( server_xp , THREAD_BLOCKED_ISR ); 176 176 177 177 // unblock client thread -
trunk/hal/tsar_mips32/drivers/soclib_dma.c
r408 r436 90 90 91 91 // Block and deschedule server thread 92 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );92 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 93 93 sched_yield("blocked on ISR"); 94 94 … … 127 127 128 128 // unblock server thread 129 thread_unblock( server_xp , THREAD_BLOCKED_ DEV_ISR );129 thread_unblock( server_xp , THREAD_BLOCKED_ISR ); 130 130 131 131 // unblock client thread -
trunk/hal/tsar_mips32/drivers/soclib_hba.c
r408 r436 239 239 else // descheduling + IRQ 240 240 { 241 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );241 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 242 242 sched_yield( "blocked on ISR" ); 243 243 } -
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r435 r436 46 46 #endif 47 47 48 //////////////////////////////////////////////////////////////////////////////////// 49 // These global variables implement the TTY_RX FIFOs (one per channel) 50 //////////////////////////////////////////////////////////////////////////////////// 51 52 __attribute__((section(".kdata"))) 53 tty_fifo_t tty_rx_fifo[CONFIG_MAX_TXT_CHANNELS]; 54 55 __attribute__((section(".kdata"))) 56 tty_fifo_t tty_tx_fifo[CONFIG_MAX_TXT_CHANNELS]; 57 48 58 /////////////////////////////////////// 49 59 void soclib_tty_init( chdev_t * chdev ) … … 51 61 xptr_t reg_xp; 52 62 63 // initialise function pointers in chdev 53 64 chdev->cmd = &soclib_tty_cmd; 54 65 chdev->isr = &soclib_tty_isr; … … 58 69 xptr_t tty_xp = chdev->base; 59 70 uint32_t channel = chdev->channel; 71 bool_t is_rx = chdev->is_rx; 60 72 61 73 // get SOCLIB_TTY device cluster and local pointer … … 70 82 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE ); 71 83 hal_remote_sw( reg_xp , 0 ); 72 } 84 85 // reset relevant FIFO 86 if( is_rx ) 87 { 88 tty_rx_fifo[channel].sts = 0; 89 tty_rx_fifo[channel].ptr = 0; 90 tty_rx_fifo[channel].ptw = 0; 91 } 92 else 93 { 94 tty_tx_fifo[channel].sts = 0; 95 tty_tx_fifo[channel].ptr = 0; 96 tty_tx_fifo[channel].ptw = 0; 97 } 98 } // end soclib_tty_init() 73 99 74 100 ////////////////////////////////////////////////////////////// 75 101 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp ) 76 102 { 77 78 #if (CONFIG_DEBUG_SYS_READ & 1) 79 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles(); 80 #endif 81 82 #if (CONFIG_DEBUG_SYS_WRITE & 1) 83 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles(); 84 #endif 103 tty_fifo_t * fifo; // TTY_RX or TTY_TX FIFO 104 char byte; // byte value 105 uint32_t done; // number of bytes moved 85 106 86 107 // get client thread cluster and local pointer … … 88 109 thread_t * th_ptr = GET_PTR( th_xp ); 89 110 90 // get command type and extended pointer on TXT device 91 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 92 93 #if CONFIG_DEBUG_HAL_TXT 111 // get command arguments 112 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 113 xptr_t buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) ); 114 uint32_t count = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) ); 115 xptr_t error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error ); 116 117 #if (CONFIG_DEBUG_SYS_READ & 1) 118 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles(); 119 #endif 120 121 #if (CONFIG_DEBUG_SYS_WRITE & 1) 122 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles(); 123 #endif 124 125 #if CONFIG_DEBUG_HAL_TXT_RX 94 126 uint32_t cycle = (uint32_t)hal_get_cycles(); 95 if (CONFIG_DEBUG_HAL_TXT < cycle ) 96 printk("\n[DBG] %s : thread %x enter for %s / cycle %d\n", 97 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str(type) , cycle ); 98 #endif 99 100 if( type == TXT_WRITE ) // block, enable TX_IRQ, and dechedule for a WRITE 101 { 102 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 103 104 // get TXT device cluster and local pointer 105 cxy_t dev_cxy = GET_CXY( dev_xp ); 106 chdev_t * dev_ptr = GET_PTR( dev_xp ); 107 108 // get extended pointer on SOCLIB_TTY base segment 109 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 110 111 // get SOCLIB_TTY base segment cluster and local pointer 112 cxy_t tty_cxy = GET_CXY( tty_xp ); 113 uint32_t * tty_ptr = GET_PTR( tty_xp ); 114 115 // get TTY channel index and channel base address 116 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 117 uint32_t * base = tty_ptr + TTY_SPAN * channel; 118 119 // block server thread 120 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 121 122 // enable relevant TX_IRQ for a WRITE 123 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 ); 124 125 // deschedule 126 sched_yield( "waiting TXT_TX_ISR completion" ); 127 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) ) 128 printk("\n[DBG] %s : thread %x enter for RX / cycle %d\n", 129 __FUNCTION__ , CURRENT_THREAD , cycle ); 130 #endif 131 132 #if CONFIG_DEBUG_HAL_TXT_TX 133 uint32_t cycle = (uint32_t)hal_get_cycles(); 134 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) ) 135 printk("\n[DBG] %s : thread %x enter for TX / cycle %d\n", 136 __FUNCTION__ , CURRENT_THREAD , cycle ); 137 #endif 138 139 // get TXT device pointers 140 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 141 cxy_t dev_cxy = GET_CXY( dev_xp ); 142 chdev_t * dev_ptr = GET_PTR( dev_xp ); 143 144 // get extended pointer on SOCLIB_TTY base segment 145 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 146 147 // get SOCLIB_TTY base segment cluster and local pointer 148 cxy_t tty_cxy = GET_CXY( tty_xp ); 149 uint32_t * tty_ptr = GET_PTR( tty_xp ); 150 151 // get TTY channel index and channel base address 152 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 153 uint32_t * base = tty_ptr + TTY_SPAN * channel; 154 155 /////////////////////// 156 if( type == TXT_WRITE ) // write bytes to TTY_TX FIFO 157 { 158 fifo = &tty_tx_fifo[channel]; 159 160 done = 0; 161 162 while( done < count ) 163 { 164 if( fifo->sts < TTY_FIFO_DEPTH ) // put one byte to FIFO if TX_FIFO not full 165 { 166 // get one byte from command buffer 167 byte = hal_remote_lb( buf_xp + done ); 168 169 // write byte to FIFO 170 fifo->data[fifo->ptw] = byte; 171 172 // prevent race 173 hal_fence(); 174 175 // update FIFO state 176 fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH; 177 hal_atomic_add( &fifo->sts , 1 ); 178 179 // udate number of bytes moved 180 done++; 181 182 // enable TX_IRQ 183 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 ); 184 } 185 else // block & deschedule if TX_FIFO full 186 { 187 // block on ISR 188 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 189 190 // deschedule 191 sched_yield( "TTY_TX_FIFO full" ); 192 } 193 } 194 195 // set error status in command and return 196 hal_remote_sw( error_xp , 0 ); 127 197 } 128 else if( type == TXT_READ ) // block, and deschedule for a READ 129 { 130 // block server thread 131 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 132 133 // deschedule 134 sched_yield( "waiting TXT_RX_ISR completion" ); 198 /////////////////////////// 199 else if( type == TXT_READ ) // read bytes from TTY_RX FIFO 200 { 201 fifo = &tty_rx_fifo[channel]; 202 203 done = 0; 204 205 while( done < count ) 206 { 207 if( fifo->sts > 0 ) // get byte from FIFO if not empty 208 { 209 // get one byte from FIFO 210 char byte = fifo->data[fifo->ptr]; 211 212 // update FIFO state 213 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 214 hal_atomic_add( &fifo->sts , -1 ); 215 216 // set byte to command buffer 217 hal_remote_sb( buf_xp + done , byte ); 218 219 // udate number of bytes 220 done++; 221 } 222 else // deschedule if FIFO empty 223 { 224 // block on ISR 225 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 226 227 // deschedule 228 sched_yield( "TTY_TX_FIFO_RX empty" ); 229 } 230 } // end while 231 232 // set error status in command 233 hal_remote_sw( error_xp , 0 ); 135 234 } 136 235 else … … 139 238 } 140 239 141 #if CONFIG_DEBUG_HAL_TXT 240 #if CONFIG_DEBUG_HAL_TXT_RX 142 241 cycle = (uint32_t)hal_get_cycles(); 143 if (CONFIG_DEBUG_HAL_TXT < cycle ) 144 printk("\n[DBG] %s : thread %x exit after %s / cycle %d\n", 145 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str( type ) , cycle ); 242 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) ) 243 printk("\n[DBG] %s : thread %x exit after RX / cycle %d\n", 244 __FUNCTION__ , CURRENT_THREAD , cycle ); 245 #endif 246 247 #if CONFIG_DEBUG_HAL_TXT_TX 248 cycle = (uint32_t)hal_get_cycles(); 249 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) ) 250 printk("\n[DBG] %s : thread %x exit after TX / cycle %d\n", 251 __FUNCTION__ , CURRENT_THREAD , cycle ); 146 252 #endif 147 253 … … 155 261 156 262 } // end soclib_tty_cmd() 263 264 ///////////////////////////////////////////////////////////////// 265 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 266 { 267 thread_t * server; // pointer on TXT chdev server thread 268 lid_t server_lid; // local index of core running the server thread 269 uint32_t channel; // TXT chdev channel 270 bool_t is_rx; // TXT chdev direction 271 char byte; // byte value 272 xptr_t owner_xp; // extended pointer on foreground process in owner cluster 273 cxy_t owner_cxy; 274 process_t * owner_ptr; 275 pid_t owner_pid; 276 tty_fifo_t * fifo; // pointer on TTY_TX or TTY_RX FIFO 277 cxy_t tty_cxy; // soclib_tty cluster 278 uint32_t * tty_ptr; // soclib_tty segment base address 279 uint32_t * base; // soclib_tty channel base address 280 xptr_t status_xp; // extended pointer on TTY_STATUS register 281 xptr_t write_xp; // extended pointer on TTY_WRITE register 282 xptr_t read_xp; // extended pointer on TTY_READ register 283 284 // get TXT chdev channel, direction and server thread 285 channel = chdev->channel; 286 is_rx = chdev->is_rx; 287 server = chdev->server; 288 server_lid = server->core->lid; 289 290 #if (CONFIG_DEBUG_SYS_READ & 1) 291 if( is_rx ) enter_tty_isr_read = (uint32_t)hal_get_cycles(); 292 #endif 293 294 #if (CONFIG_DEBUG_SYS_WRITE & 1) 295 if( is_rx == 0 ) enter_tty_isr_write = (uint32_t)hal_get_cycles(); 296 #endif 297 298 #if CONFIG_DEBUG_HAL_TXT_RX 299 uint32_t cycle = (uint32_t)hal_get_cycles(); 300 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx ) 301 printk("\n[DBG] %s : enter for RX / cycle %d\n", __FUNCTION__ , cycle ); 302 #endif 303 304 #if CONFIG_DEBUG_HAL_TXT_TX 305 uint32_t cycle = (uint32_t)hal_get_cycles(); 306 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) ) 307 printk("\n[DBG] %s : enter for TX / cycle %d\n", __FUNCTION__ , cycle ); 308 #endif 309 310 // get SOCLIB_TTY peripheral cluster and local pointer 311 tty_cxy = GET_CXY( chdev->base ); 312 tty_ptr = GET_PTR( chdev->base ); 313 314 // get channel base address 315 base = tty_ptr + TTY_SPAN * channel; 316 317 // get extended pointer on TTY registers 318 status_xp = XPTR( tty_cxy , base + TTY_STATUS ); 319 write_xp = XPTR( tty_cxy , base + TTY_WRITE ); 320 read_xp = XPTR( tty_cxy , base + TTY_READ ); 321 322 /////////////////////////// handle RX ////////////////////// 323 if( is_rx ) 324 { 325 fifo = &tty_rx_fifo[channel]; 326 327 // try to move bytes until TTY_READ register empty 328 while( hal_remote_lw( status_xp ) & TTY_STATUS_RX_FULL ) 329 { 330 // get one byte from TTY_READ register & acknowledge RX_IRQ 331 byte = (char)hal_remote_lb( read_xp ); 332 333 // filter special character ^Z 334 if( byte == 0x1A ) 335 { 336 // get pointers on TXT owner process in owner cluster 337 owner_xp = process_txt_get_owner( channel ); 338 339 // check process exist 340 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 341 "TXT owner process not found\n" ); 342 343 // get relevant infos on owner process 344 owner_cxy = GET_CXY( owner_xp ); 345 owner_ptr = GET_PTR( owner_xp ); 346 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 347 348 // block owner process only if it is not a KSH 349 if( process_get_ppid( owner_xp ) > 1 ) 350 { 351 // send stop signal to owner process 352 process_sigaction( owner_pid , BLOCK_ALL_THREADS ); 353 354 // atomically update owner process termination state 355 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 356 PROCESS_TERM_STOP ); 357 return; 358 } 359 } 360 361 // filter special character ^C 362 if( byte == 0x03 ) 363 { 364 // get pointers on TXT owner process in owner cluster 365 owner_xp = process_txt_get_owner( channel ); 366 367 // check process exist 368 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 369 "TXT owner process not found\n" ); 370 371 // get relevant infos on TXT owner process 372 owner_cxy = GET_CXY( owner_xp ); 373 owner_ptr = GET_PTR( owner_xp ); 374 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 375 376 // kill TXT owner process only if it is not INIT 377 if( owner_pid != 1 ) 378 { 379 // remove process from TXT list 380 process_txt_detach( owner_xp ); 381 382 // mark for delete all processes in all clusters, but the main 383 process_sigaction( owner_pid , DELETE_ALL_THREADS ); 384 385 // get pointer on target process main thread 386 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 387 388 // block main thread 389 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 390 391 // atomically update owner process termination state 392 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 393 PROCESS_TERM_KILL ); 394 return; 395 } 396 } 397 398 // write byte in TTY_RX FIFO if not full / discard byte if full 399 if ( fifo->sts < TTY_FIFO_DEPTH ) 400 { 401 // store byte into FIFO 402 fifo->data[fifo->ptw] = (char)byte; 403 404 // avoid race 405 hal_fence(); 406 407 // update RX_FIFO state 408 fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH; 409 hal_atomic_add( &fifo->sts , 1 ); 410 411 // unblock TXT_RX server thread 412 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 413 414 // send IPI to core running server thread 415 dev_pic_send_ipi( local_cxy , server_lid ); 416 } 417 else 418 { 419 printk("\n[WARNING] %s : TTY_RX_FIFO[%d] full => discard character <%x>\n", 420 __FUNCTION__, channel, (uint32_t)byte ); 421 } 422 } // end while TTY_READ register full 423 424 } // end RX 425 426 /////////////////////// handle TX ///////////////////////////// 427 else 428 { 429 fifo = &tty_tx_fifo[channel]; 430 431 // try to move bytes until TX_FIFO empty 432 while( fifo->sts > 0 ) 433 { 434 // write one byte to TTY_WRITE register if empty / exit while if full 435 if( (hal_remote_lw( status_xp ) & TTY_STATUS_TX_FULL) == 0 ) 436 { 437 // get one byte from TX_FIFO 438 byte = fifo->data[fifo->ptr]; 439 440 // update TX_FIFO state 441 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 442 hal_atomic_add( &fifo->sts , -1 ); 443 444 // write byte to TTY_WRITE register & acknowledge TX_IRQ 445 hal_remote_sb( write_xp , byte ); 446 } 447 } 448 449 // disable TX_IRQ 450 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 ); 451 452 // unblock TXT_TX server thread 453 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 454 455 // send IPI to core running server thread 456 dev_pic_send_ipi( local_cxy , server_lid ); 457 } // end TX 458 459 hal_fence(); 460 461 #if CONFIG_DEBUG_HAL_TXT_RX 462 cycle = (uint32_t)hal_get_cycles(); 463 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx ) 464 printk("\n[DBG] %s : exit after RX / cycle %d\n", __FUNCTION__, cycle ); 465 #endif 466 467 #if CONFIG_DEBUG_HAL_TXT_TX 468 cycle = (uint32_t)hal_get_cycles(); 469 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) ) 470 printk("\n[DBG] %s : exit after TX / cycle %d\n", __FUNCTION__, cycle ); 471 #endif 472 473 #if (CONFIG_DEBUG_SYS_READ & 1) 474 if( is_rx ) exit_tty_isr_read = (uint32_t)hal_get_cycles(); 475 #endif 476 477 #if (CONFIG_DEBUG_SYS_WRITE & 1) 478 if( is_rx == 0 ) exit_tty_isr_write = (uint32_t)hal_get_cycles(); 479 #endif 480 481 } // end soclib_tty_isr() 157 482 158 483 ///////////////////////////////////////////////////////////// … … 182 507 xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS ); 183 508 184 // loop on characters (busy waiting strategy)509 // loop on characters (busy waiting policy) 185 510 for( i = 0 ; i < count ; i++ ) 186 511 { … … 199 524 200 525 201 ///////////////////////////////////////////////////////////////// 202 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 203 { 204 uint32_t type; // command type 205 uint32_t count; // number of bytes in buffer 206 xptr_t buf_xp; // extended pointer on buffer 207 xptr_t error_xp; // extended pointer on error field in command 208 xptr_t status_xp; // extended pointer on TTY_STATUS register 209 xptr_t write_xp; // extended pointer on TTY_WRITE register 210 xptr_t read_xp; // extended pointer on TTY_READ register 211 uint32_t status; // TTY terminal status 212 char byte; // read byte 213 xptr_t client_xp; // first client thread in waiting queue 214 cxy_t client_cxy; // firts client thread cluster 215 thread_t * client_ptr; // first client thread pointer 216 pid_t pid; // foreground process identifier 217 xptr_t owner_xp; // extended pointer on foreground process in owner cluster 218 cxy_t owner_cxy; 219 process_t * owner_ptr; 220 uint32_t i; 221 222 #if (CONFIG_DEBUG_SYS_READ & 1) 223 enter_tty_isr_read = (uint32_t)hal_get_cycles(); 224 #endif 225 226 #if (CONFIG_DEBUG_SYS_WRITE & 1) 227 enter_tty_isr_write = (uint32_t)hal_get_cycles(); 228 #endif 229 230 #if CONFIG_DEBUG_HAL_TXT 231 uint32_t cycle = (uint32_t)hal_get_cycles(); 232 if (CONFIG_DEBUG_HAL_TXT < cycle) 233 printk("\n[DBG] %s : enter / cycle %d\n", __FUNCTION__ , cycle ); 234 #endif 235 236 // get extended pointer on chdev queue root 237 xptr_t root_xp = XPTR( local_cxy , &chdev->wait_root ); 238 239 // get chdev channel 240 uint32_t channel = chdev->channel; 241 242 // get first command if queue non empty 243 if( xlist_is_empty( root_xp ) == false ) 244 { 245 // get extended pointer on first client thread 246 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 247 248 // get client thread cluster and local pointer 249 client_cxy = GET_CXY( client_xp ); 250 client_ptr = GET_PTR( client_xp ); 251 252 // get command arguments 253 type = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type ) ); 254 count = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ) ); 255 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) ); 256 error_xp = XPTR( client_cxy , &client_ptr->txt_cmd.error ); 257 } 258 else 259 { 260 type = 0xFFFFFFFF; 261 262 // these lines to avoid a GCC warning 263 count = 0; 264 buf_xp = XPTR_NULL; 265 error_xp = XPTR_NULL; 266 client_cxy = 0; 267 client_ptr = NULL; 268 } 269 270 // get SOCLIB_TTY peripheral cluster and local pointer 271 cxy_t tty_cxy = GET_CXY( chdev->base ); 272 uint32_t * tty_ptr = GET_PTR( chdev->base ); 273 274 // get channel base address 275 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel; 276 277 // get extended pointer on TTY registers 278 status_xp = XPTR( tty_cxy , base + TTY_STATUS ); 279 write_xp = XPTR( tty_cxy , base + TTY_WRITE ); 280 read_xp = XPTR( tty_cxy , base + TTY_READ ); 281 282 // get TTY_STATUS register value 283 status = hal_remote_lw( status_xp ); 284 285 // 1. handle RX if TTY_READ buffer full 286 if( status & TTY_STATUS_RX_FULL ) 287 { 288 // get a byte from TTY_READ / acknowledge RX_IRQ 289 byte = (char)hal_remote_lb( read_xp ); 290 291 // check character value 292 if( byte == 0x1A ) // ^Z => stop onwner process 293 { 294 // get pid of terminal owner process 295 pid = process_get_txt_owner( channel ); 296 297 // get cluster and pointers on owner process descriptor 298 owner_xp = cluster_get_owner_process_from_pid( pid ); 299 owner_cxy = GET_CXY( owner_xp ); 300 owner_ptr = GET_PTR( owner_xp ); 301 302 // send stop signal to owner process 303 process_sigaction( pid , BLOCK_ALL_THREADS ); 304 305 // atomically update owner process termination state 306 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 307 PROCESS_TERM_STOP ); 308 return; 309 } 310 else if( byte == 0x03 ) // ^C => kill owner process 311 { 312 // get pid of terminal owner process 313 pid = process_get_txt_owner( channel ); 314 315 // get cluster and pointers on owner process descriptor 316 owner_xp = cluster_get_owner_process_from_pid( pid ); 317 owner_cxy = GET_CXY( owner_xp ); 318 owner_ptr = GET_PTR( owner_xp ); 319 320 // send kill signal to owner process 321 process_sigaction( pid , DELETE_ALL_THREADS ); 322 323 // atomically update owner process termination state 324 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 325 PROCESS_TERM_KILL ); 326 return; 327 } 328 else if( type == TXT_READ ) // pending TXT_READ 329 { 330 // write character to command buffer 331 hal_remote_sb( buf_xp , byte ); 332 333 // set I/O operation status in command 334 hal_remote_sw( error_xp , 0 ); 335 336 // unblock server thread 337 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 338 } 339 } 340 341 // 3. handle TX if TXT_WRITE 342 if( type == TXT_WRITE ) 343 { 344 // loop on characters 345 for( i = 0 ; i < count ; i++ ) 346 { 347 // get TTY_STATUS 348 status = hal_remote_lw( status_xp ); 349 350 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte 351 { 352 // get one byte from command buffer 353 byte = (char)hal_remote_lb( buf_xp + i ); 354 355 // write byte to TTY_WRITE / acknowledge TX_IRQ 356 hal_remote_sb( write_xp , byte ); 357 } 358 else // TTY_TX full => update command arguments and exit ISR for retry 359 { 360 hal_remote_sw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ), count-i ); 361 hal_remote_swd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ), buf_xp+i ); 362 return; 363 } 364 } 365 366 // set I/O operation status in command 367 hal_remote_sw( error_xp , 0 ); 368 369 // disable TX_IRQ 370 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 ); 371 372 // unblock server thread 373 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 374 } 375 376 hal_fence(); 377 378 #if CONFIG_DEBUG_HAL_TXT 379 cycle = (uint32_t)hal_get_cycles(); 380 if (CONFIG_DEBUG_HAL_TXT < cycle) 381 printk("\n[DBG] %s : exit after %s / cycle %d\n", 382 __FUNCTION__ , dev_txt_type_str( type ) , cycle ); 383 #endif 384 385 #if (CONFIG_DEBUG_SYS_READ & 1) 386 if( type == TXT_READ) exit_tty_isr_read = (uint32_t)hal_get_cycles(); 387 #endif 388 389 #if (CONFIG_DEBUG_SYS_WRITE & 1) 390 if( type == TXT_WRITE) exit_tty_isr_write = (uint32_t)hal_get_cycles(); 391 #endif 392 393 } // end soclib_tty_isr() 394 526 -
trunk/hal/tsar_mips32/drivers/soclib_tty.h
r435 r436 52 52 #define TTY_STATUS_RX_FULL 1 // TTY_READ_REG full if 1 53 53 #define TTY_STATUS_TX_FULL 2 // TTY_WRITE_REG full if 1 54 55 /**************************************************************************************** 56 * This Rstructure is used by the soclib_tty_isr for the RX channel. 57 ***************************************************************************************/ 58 59 #define TTY_FIFO_DEPTH 128 60 61 typedef struct tty_fifo_s // 32 bytes 62 { 63 char data[TTY_FIFO_DEPTH]; // one char per slot 64 unsigned int ptr; // next free slot index 65 unsigned int ptw; // next full slot index 66 unsigned int sts; // number of full slots 67 } tty_fifo_t; 68 54 69 55 70 /**************************************************************************************** -
trunk/kernel/devices/dev_nic.c
r408 r436 130 130 131 131 // block on THREAD_BLOCKED_IO condition and deschedule 132 thread_block( thread_ptr, THREAD_BLOCKED_IO );132 thread_block( XPTR( local_cxy , thread_ptr ) , THREAD_BLOCKED_IO ); 133 133 sched_yield("client blocked on I/O"); 134 134 … … 200 200 201 201 // block on THREAD_BLOCKED I/O condition and deschedule 202 thread_block( thread_ptr, THREAD_BLOCKED_IO );202 thread_block( XPTR( local_cxy , thread_ptr ) , THREAD_BLOCKED_IO ); 203 203 sched_yield("client blocked on I/O"); 204 204 -
trunk/kernel/devices/dev_txt.c
r435 r436 131 131 thread_t * this = CURRENT_THREAD; 132 132 133 #if (CONFIG_DEBUG_SYS_READ & 1)134 enter_txt_read = hal_time_stamp();135 #endif136 137 #if (CONFIG_DEBUG_SYS_WRITE & 1)138 enter_txt_write = hal_time_stamp();139 #endif140 141 #if CONFIG_DEBUG_DEV_TXT142 uint32_t cycle = (uint32_t)hal_get_cycles();143 if( CONFIG_DEBUG_DEV_TXT < cycle )144 printk("\n[DBG] %s : thread %x enters / cycle %d\n",145 __FUNCTION__, CURRENT_THREAD , cycle );146 #endif147 148 133 // check channel argument 149 134 assert( (channel < CONFIG_MAX_TXT_CHANNELS) , __FUNCTION__ , "illegal channel index" ); … … 166 151 chdev_register_command( dev_xp ); 167 152 168 #if CONFIG_DEBUG_DEV_TXT169 cycle = (uint32_t)hal_get_cycles();170 if( CONFIG_DEBUG_DEV_TXT < cycle )171 printk("\n[DBG] %s : thread %x exit / cycle %d\n",172 __FUNCTION__, CURRENT_THREAD , cycle );173 #endif174 175 #if (CONFIG_DEBUG_SYS_READ & 1)176 exit_txt_read = hal_time_stamp();177 #endif178 179 #if (CONFIG_DEBUG_SYS_WRITE & 1)180 exit_txt_write = hal_time_stamp();181 #endif182 183 153 // return I/O operation status from calling thread descriptor 184 154 return this->txt_cmd.error; … … 190 160 uint32_t count ) 191 161 { 162 163 #if (CONFIG_DEBUG_SYS_WRITE & 1) 164 enter_txt_write = hal_time_stamp(); 165 #endif 166 167 #if CONFIG_DEBUG_DEV_TXT_TX 168 uint32_t cycle = (uint32_t)hal_get_cycles(); 169 if( CONFIG_DEBUG_DEV_TXT_TX < cycle ) 170 printk("\n[DBG] %s : thread %x enters / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 171 #endif 172 192 173 return dev_txt_access( TXT_WRITE , channel , buffer , count ); 174 175 #if CONFIG_DEBUG_DEV_TXT_TX 176 cycle = (uint32_t)hal_get_cycles(); 177 if( CONFIG_DEBUG_DEV_TXT_TX < cycle ) 178 printk("\n[DBG] %s : thread %x exit / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 179 #endif 180 181 #if (CONFIG_DEBUG_SYS_WRITE & 1) 182 exit_txt_write = hal_time_stamp(); 183 #endif 184 193 185 } 194 186 … … 197 189 char * buffer ) 198 190 { 191 192 #if (CONFIG_DEBUG_SYS_READ & 1) 193 enter_txt_read = hal_time_stamp(); 194 #endif 195 196 #if CONFIG_DEBUG_DEV_TXT_RX 197 uint32_t cycle = (uint32_t)hal_get_cycles(); 198 if( CONFIG_DEBUG_DEV_TXT_RX < cycle ) 199 printk("\n[DBG] %s : thread %x enters / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 200 #endif 201 199 202 return dev_txt_access( TXT_READ , channel , buffer , 1 ); 203 204 #if CONFIG_DEBUG_DEV_TXT_RX 205 cycle = (uint32_t)hal_get_cycles(); 206 if( CONFIG_DEBUG_DEV_TXT_RX < cycle ) 207 printk("\n[DBG] %s : thread %x exit / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle ); 208 #endif 209 210 #if (CONFIG_DEBUG_SYS_READ & 1) 211 exit_txt_read = hal_time_stamp(); 212 #endif 213 200 214 } 201 215 -
trunk/kernel/fs/vfs.c
r433 r436 235 235 236 236 #if CONFIG_DEBUG_VFS_INODE_CREATE 237 uint32_tcycle = (uint32_t)hal_get_cycles();237 cycle = (uint32_t)hal_get_cycles(); 238 238 if( CONFIG_DEBUG_VFS_INODE_CREATE < cycle ) 239 239 printk("\n[DBG] %s : thread %x exit / inode = %x in cluster %x / cycle %d\n", … … 1351 1351 if( CONFIG_DEBUG_VFS_LOOKUP < cycle ) 1352 1352 printk("\n[DBG] %s : thread %x enter for <%s> / cycle %d\n", 1353 __FUNCTION__, CURRENT_THREAD, path , cycle );1353 __FUNCTION__, CURRENT_THREAD, pathname, cycle ); 1354 1354 #endif 1355 1355 … … 1522 1522 if( CONFIG_DEBUG_VFS_LOOKUP < cycle ) 1523 1523 printk("\n[DBG] %s : thread %x exit for <%s> / inode %x in cluster %x / cycle %d\n", 1524 __FUNCTION__, CURRENT_THREAD, path , GET_PTR(child_xp), GET_CXY(child_xp), cycle );1524 __FUNCTION__, CURRENT_THREAD, pathname, GET_PTR(child_xp), GET_CXY(child_xp), cycle ); 1525 1525 #endif 1526 1526 -
trunk/kernel/kern/chdev.c
r435 r436 179 179 180 180 // block current thread 181 thread_block( CURRENT_THREAD, THREAD_BLOCKED_IO );181 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_IO ); 182 182 183 183 // register client thread in waiting queue -
trunk/kernel/kern/cluster.c
r433 r436 237 237 { 238 238 xptr_t root_xp; // xptr on root of list of processes in owner cluster 239 xptr_t lock_xp; // xptr ron lock protecting this list239 xptr_t lock_xp; // xptr on lock protecting this list 240 240 xptr_t iter_xp; // iterator 241 241 xptr_t current_xp; // xptr on current process descriptor … … 277 277 if( found ) return current_xp; 278 278 else return XPTR_NULL; 279 } 279 280 } // end cluster_get_owner_process_from_pid() 280 281 281 282 ////////////////////////////////////////////////////////// … … 440 441 void cluster_process_copies_link( process_t * process ) 441 442 { 442 uint32_tirq_state;443 reg_t irq_state; 443 444 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 445 446 #if CONFIG_DEBUG_CLUSTER_PROCESS_COPIES 447 uint32_t cycle = (uint32_t)hal_get_cycles(); 448 if( CONFIG_DEBUG_CLUSTER_PROCESS_COPIES < cycle ) 449 printk("\n[DBG] %s enters / cluster %x / process %x / cycle %d\n", 450 __FUNCTION__ , local_cxy , process , cycle ); 451 #endif 444 452 445 453 // get owner cluster identifier CXY and process LPID … … 460 468 remote_spinlock_lock_busy( copies_lock , &irq_state ); 461 469 470 // add copy to copies_list 462 471 xlist_add_first( copies_root , copies_entry ); 463 472 hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , 1 ); … … 465 474 // release lock protecting copies_list[lpid] 466 475 remote_spinlock_unlock_busy( copies_lock , irq_state ); 467 } 476 477 #if CONFIG_DEBUG_CLUSTER_PROCESS_COPIES 478 cycle = (uint32_t)hal_get_cycles(); 479 if( CONFIG_DEBUG_CLUSTER_PROCESS_COPIES < cycle ) 480 printk("\n[DBG] %s exit / cluster %x / process %x / cycle %d\n", 481 __FUNCTION__ , local_cxy , process , cycle ); 482 #endif 483 484 } // end cluster_process_copies_link() 468 485 469 486 ///////////////////////////////////////////////////////// … … 472 489 uint32_t irq_state; 473 490 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 491 492 #if CONFIG_DEBUG_CLUSTER_PROCESS_COPIES 493 uint32_t cycle = (uint32_t)hal_get_cycles(); 494 if( CONFIG_DEBUG_CLUSTER_PROCESS_COPIES < cycle ) 495 printk("\n[DBG] %s enters / cluster %x / process %x / cycle %d\n", 496 __FUNCTION__ , local_cxy , process , cycle ); 497 #endif 474 498 475 499 // get owner cluster identifier CXY and process LPID … … 479 503 480 504 // get extended pointer on lock protecting copies_list[lpid] 481 xptr_t copies_lock = hal_remote_lwd( XPTR( owner_cxy , &pm->copies_lock[lpid] ));505 xptr_t copies_lock = XPTR( owner_cxy , &pm->copies_lock[lpid] ); 482 506 483 507 // get extended pointer on the local copies_list entry … … 487 511 remote_spinlock_lock_busy( copies_lock , &irq_state ); 488 512 513 // remove copy from copies_list 489 514 xlist_unlink( copies_entry ); 490 515 hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , -1 ); … … 492 517 // release lock protecting copies_list[lpid] 493 518 remote_spinlock_unlock_busy( copies_lock , irq_state ); 494 } 519 520 #if CONFIG_DEBUG_CLUSTER_PROCESS_COPIES 521 cycle = (uint32_t)hal_get_cycles(); 522 if( CONFIG_DEBUG_CLUSTER_PROCESS_COPIES < cycle ) 523 printk("\n[DBG] %s exit / cluster %x / process %x / cycle %d\n", 524 __FUNCTION__ , local_cxy , process , cycle ); 525 #endif 526 527 } // end cluster_process_copies_unlink() 495 528 496 529 /////////////////////////////////////////// -
trunk/kernel/kern/kernel_init.c
r435 r436 125 125 // these debug variables are used to analyse the sys_read() syscall timing 126 126 127 #if CONFIG_ READ_DEBUG127 #if CONFIG_DEBUG_SYS_READ 128 128 uint32_t enter_sys_read; 129 129 uint32_t exit_sys_read; … … 150 150 // these debug variables are used to analyse the sys_write() syscall timing 151 151 152 #if CONFIG_ WRITE_DEBUG152 #if CONFIG_DEBUG_SYS_WRITE 153 153 uint32_t enter_sys_write; 154 154 uint32_t exit_sys_write; -
trunk/kernel/kern/process.c
r435 r436 365 365 cxy_t parent_cxy; 366 366 xptr_t children_lock_xp; 367 xptr_t copies_lock_xp;368 367 369 368 assert( (process->th_nr == 0) , __FUNCTION__ , … … 377 376 #endif 378 377 379 // get local process manager pointer 380 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 381 382 // remove process from local_list in cluster manager 383 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) ); 384 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); 385 remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) ); 386 387 // get extended pointer on copies_lock in owner cluster manager 388 cxy_t owner_cxy = CXY_FROM_PID( process->pid ); 389 lpid_t lpid = LPID_FROM_PID( process->pid ); 390 copies_lock_xp = XPTR( owner_cxy , &pmgr->copies_lock[lpid] ); 391 392 // remove local process from copies_list 393 remote_spinlock_lock( copies_lock_xp ); 394 xlist_unlink( XPTR( local_cxy , &process->copies_list ) ); 395 remote_spinlock_unlock( copies_lock_xp ); 396 397 // for reference process only 398 if( XPTR( local_cxy , process ) == process->ref_xp ) 399 { 400 // remove reference process from txt_list 401 process_txt_detach( process ); 402 378 // remove process from local_list in local cluster manager 379 cluster_process_local_unlink( process ); 380 381 // remove process from copies_list in owner cluster manager 382 cluster_process_copies_unlink( process ); 383 384 // remove process from children_list if process is in owner cluster 385 if( CXY_FROM_PID( process->pid ) == local_cxy ) 386 { 403 387 // get pointers on parent process 404 388 parent_xp = process->parent_xp; … … 461 445 xptr_t process_xp; // extended pointer on process copy 462 446 cxy_t process_cxy; // process copy cluster identifier 463 process_t * process_ptr; // local pointer on process copy 464 uint32_t responses; // number of remote process copies 465 uint32_t rsp_count; // used to assert number of copies 466 rpc_desc_t rpc; // rpc descriptor allocated in stack 447 reg_t save_sr; // for critical section 448 rpc_desc_t rpc; // shared RPC descriptor 467 449 468 450 thread_t * client = CURRENT_THREAD; … … 475 457 #endif 476 458 477 // get localpointer on local cluster manager459 // get pointer on local cluster manager 478 460 cluster = LOCAL_CLUSTER; 479 461 … … 483 465 484 466 // get root of list of copies, lock, and number of copies from owner cluster 485 responses = hal_remote_lw ( XPTR( owner_cxy , &cluster->pmgr.copies_nr[lpid] ) ); 486 root_xp = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ) ); 487 lock_xp = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ) ); 488 489 rsp_count = 0; 467 root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 468 lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 490 469 491 470 // check action type … … 494 473 (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" ); 495 474 496 // initialise rpc descriptor 497 rpc.index = RPC_PROCESS_SIGACTION; 498 rpc.response = responses; 499 rpc.blocking = false; 500 rpc.thread = client; 475 // allocate a - shared - RPC descriptor in client thread stack 476 // it can be shared because all parallel, non-blocking, server threads 477 // use the same input arguments, and use the shared RPC response field 478 // but use 479 480 // the client thread makes the following sequence: 481 // 1. mask interrupts 482 // 2. block itself 483 // 3. send RPC requests to all copies 484 // 4. unmask interrupts 485 // 5. deschedule 486 487 // mask IRQs 488 hal_disable_irq( &save_sr); 489 490 // client register blocking condition for itself 491 thread_block( XPTR( local_cxy , client ) , THREAD_BLOCKED_RPC ); 501 492 502 493 // take the lock protecting the copies 503 494 remote_spinlock_lock( lock_xp ); 504 495 505 // send RPCs to remote clusters 496 // initialize shared RPC descriptor 497 rpc.response = 0; 498 rpc.blocking = false; 499 rpc.index = RPC_PROCESS_SIGACTION; 500 rpc.thread = client; 501 rpc.lid = client->core->lid; 502 rpc.args[0] = action_type; 503 rpc.args[1] = pid; 504 505 // send RPCs to all clusters containing process copiess 506 506 XLIST_FOREACH( root_xp , iter_xp ) 507 507 { 508 509 #if CONFIG_DEBUG_PROCESS_SIGACTION 510 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 511 printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n", 512 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy ); 513 #endif 514 // atomically increment responses counter 515 hal_atomic_add( (void *)&rpc.response , 1 ); 516 508 517 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 509 518 process_cxy = GET_CXY( process_xp ); 510 process_ptr = GET_PTR( process_xp ); 511 512 #if CONFIG_DEBUG_PROCESS_SIGACTION 513 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 514 printk("\n[DBG] %s : send RPC to cluster %x\n", __FUNCTION__ , process_cxy ); 515 #endif 516 517 // check PID 518 assert( (hal_remote_lw( XPTR( process_cxy , &process_ptr->pid) ) == pid), 519 __FUNCTION__ , "unconsistent PID value\n" ); 520 521 rpc.args[0] = (uint64_t)action_type; 522 rpc.args[1] = (uint64_t)pid; 519 520 // call RPC in target cluster 523 521 rpc_process_sigaction_client( process_cxy , &rpc ); 524 rsp_count++;525 522 } 526 523 … … 528 525 remote_spinlock_unlock( lock_xp ); 529 526 530 // check number of copies... 531 assert( (rsp_count == responses) , __FUNCTION__ , 532 "unconsistent number of process copies : rsp_count = %d / responses = %d", 533 rsp_count , responses ); 534 535 // block and deschedule to wait RPC responses 536 thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC ); 537 sched_yield("BLOCKED on RPC_PROCESS_SIGACTION"); 527 // restore IRQs 528 hal_restore_irq( save_sr); 529 530 // client deschedule : will be unblocked by the last RPC server thread 531 sched_yield("blocked on rpc_process_sigaction"); 538 532 539 533 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 541 535 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 542 536 printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n", 543 __FUNCTION__ , client, process_action_str( action_type ) , 544 process->pid , local_cxy , cycle ); 537 __FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle ); 545 538 #endif 546 539 … … 553 546 thread_t * this; // pointer on calling thread 554 547 uint32_t ltid; // index in process th_tbl 548 cxy_t owner_cxy; // target process owner cluster 555 549 uint32_t count; // requests counter 556 volatile uint32_t rsp_count; // responsescounter550 volatile uint32_t ack_count; // scheduler acknowledge counter 557 551 558 552 // get calling thread pointer 559 553 this = CURRENT_THREAD; 554 555 // get target process owner cluster 556 owner_cxy = CXY_FROM_PID( process->pid ); 560 557 561 558 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 569 566 spinlock_lock( &process->th_lock ); 570 567 571 // initialize local responses counter 572 rsp_count = process->th_nr; 573 574 // loop on process threads to block and deschedule all threads in cluster 568 // loop to block all threads but the main thread 575 569 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 576 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )570 for( ltid = 0 , count = 0 , ack_count = 0 ; count < process->th_nr ; ltid++ ) 577 571 { 578 572 target = process->th_tbl[ltid]; 579 573 580 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" ); 581 582 if( target != NULL ) // thread found 574 if( target != NULL ) // thread exist 583 575 { 584 576 count++; 585 577 586 // - if the calling thread and the target thread are on the same core, 587 // we block the target thread, we don't need confirmation from scheduler, 588 // and we simply decrement the responses counter. 589 // - if the calling thread and the target thread are not running on the same 590 // core, we ask the target scheduler to acknowlege the blocking 591 // to be sure that the target thread is not running. 592 593 if( this->core->lid == target->core->lid ) 578 // main thread should not be deleted 579 if( (ltid != 0) || (owner_cxy != local_cxy) ) 594 580 { 595 581 // set the global blocked bit in target thread descriptor. 596 thread_block( target , THREAD_BLOCKED_GLOBAL ); 597 598 // decrement responses counter 599 hal_atomic_add( (void *)&rsp_count , -1 ); 600 } 601 else 602 { 603 // set the global blocked bit in target thread descriptor. 604 thread_block( target , THREAD_BLOCKED_GLOBAL ); 605 606 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor 607 thread_set_req_ack( target , (void *)&rsp_count ); 608 609 // force scheduling on target thread 610 dev_pic_send_ipi( local_cxy , target->core->lid ); 582 thread_block( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL ); 583 584 // - if the calling thread and the target thread are on the same core, 585 // we don't need confirmation from scheduler, 586 // - if the calling thread and the target thread are not running on the same 587 // core, we ask the target scheduler to acknowlege the blocking 588 // to be sure that the target thread is not running. 589 590 if( this->core->lid != target->core->lid ) 591 { 592 // increment responses counter 593 hal_atomic_add( (void*)&ack_count , 1 ); 594 595 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor 596 thread_set_req_ack( target , (uint32_t *)&ack_count ); 597 598 // force scheduling on target thread 599 dev_pic_send_ipi( local_cxy , target->core->lid ); 600 } 611 601 } 612 602 } … … 616 606 spinlock_unlock( &process->th_lock ); 617 607 618 // wait a ll responses from schedulers608 // wait acknowledges 619 609 while( 1 ) 620 610 { 621 // exit loop when all local responses received622 if ( rsp_count == 0 ) break;611 // exit when all scheduler acknoledges received 612 if ( ack_count == 0 ) break; 623 613 624 614 // wait 1000 cycles before retry … … 656 646 spinlock_lock( &process->th_lock ); 657 647 658 // loop on process threads to unblock all threads in cluster648 // loop on process threads to unblock all threads 659 649 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 660 650 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) 661 651 { 662 652 target = process->th_tbl[ltid]; 663 664 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" );665 653 666 654 if( target != NULL ) // thread found … … 689 677 { 690 678 thread_t * target; // pointer on target thread 691 thread_t * this; // pointer on calling thread692 679 uint32_t ltid; // index in process th_tbl 693 uint32_t count; // request counter 694 cxy_t owner_cxy; // owner cluster identifier 695 696 // get calling thread pointer 697 this = CURRENT_THREAD; 698 owner_cxy = CXY_FROM_PID( process->pid ); 680 uint32_t count; // threads counter 699 681 700 682 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 702 684 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 703 685 printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n", 704 __FUNCTION__ , this, process->pid , local_cxy , cycle );686 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle ); 705 687 #endif 706 688 … … 708 690 spinlock_lock( &process->th_lock ); 709 691 710 // loop on threads to set the REQ_DELETE flag692 // loop to set the REQ_DELETE flag on all threads but the main 711 693 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 712 694 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) … … 714 696 target = process->th_tbl[ltid]; 715 697 716 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" ); 717 718 if( target != NULL ) // thread found 698 if( target != NULL ) 719 699 { 720 700 count++; 721 701 722 // the main thread should not be deleted 723 if( (owner_cxy != local_cxy) || (ltid != 0) ) 724 { 725 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE ); 726 } 702 thread_kill( XPTR( local_cxy , target ), 703 false, // is_exit 704 true ); // is_forced 727 705 } 728 706 } … … 735 713 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 736 714 printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n", 737 __FUNCTION__ , this, process->pid , local_cxy , cycle );715 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle ); 738 716 #endif 739 717 … … 790 768 791 769 } // end process_get_local_copy() 770 771 //////////////////////////////////////////// 772 pid_t process_get_ppid( xptr_t process_xp ) 773 { 774 cxy_t process_cxy; 775 process_t * process_ptr; 776 xptr_t parent_xp; 777 cxy_t parent_cxy; 778 process_t * parent_ptr; 779 780 // get process cluster and local pointer 781 process_cxy = GET_CXY( process_xp ); 782 process_ptr = GET_PTR( process_xp ); 783 784 // get pointers on parent process 785 parent_xp = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) ); 786 parent_cxy = GET_CXY( parent_xp ); 787 parent_ptr = GET_PTR( parent_xp ); 788 789 return hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 790 } 792 791 793 792 ////////////////////////////////////////////////////////////////////////////////////////// … … 1067 1066 parent_process_xp ); 1068 1067 1069 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1068 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1070 1069 cycle = (uint32_t)hal_get_cycles(); 1071 1070 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1086 1085 } 1087 1086 1088 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1087 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1089 1088 cycle = (uint32_t)hal_get_cycles(); 1090 1089 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1112 1111 assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1113 1112 1114 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1113 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1115 1114 cycle = (uint32_t)hal_get_cycles(); 1116 1115 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1134 1133 vmm_set_cow( process ); 1135 1134 1136 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1135 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1137 1136 cycle = (uint32_t)hal_get_cycles(); 1138 1137 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1236 1235 1237 1236 // give TXT ownership to new_process 1238 process_txt_set_ownership( XPTR( local_cxy , new_process 1239 1240 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1237 process_txt_set_ownership( XPTR( local_cxy , new_process) ); 1238 1239 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1241 1240 cycle = (uint32_t)hal_get_cycles(); 1242 1241 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1255 1254 } 1256 1255 1257 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1256 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1258 1257 cycle = (uint32_t)hal_get_cycles(); 1259 1258 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1287 1286 assert( (new_thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1288 1287 1289 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1288 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1290 1289 cycle = (uint32_t)hal_get_cycles(); 1291 1290 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1312 1311 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 1313 1312 1313 // detach old_process from TXT 1314 process_txt_detach( XPTR( local_cxy , old_process ) ); 1315 1314 1316 // request old_thread destruction => old_process destruction 1315 thread_block( old_thread, THREAD_BLOCKED_GLOBAL );1317 thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL ); 1316 1318 hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE ); 1317 1319 … … 1600 1602 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1601 1603 printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d / cycle %d\n", 1602 __FUNCTION__, CURRENT_THREAD, process , txt_id, cycle );1603 #endif 1604 1605 // check process is reference1606 assert( ( process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,1607 "process is not the reference descriptor" );1604 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle ); 1605 #endif 1606 1607 // check process is in owner cluster 1608 assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ , 1609 "process descriptor not in owner cluster" ); 1608 1610 1609 1611 // check terminal index … … 1629 1631 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1630 1632 printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n", 1631 __FUNCTION__, CURRENT_THREAD, process , txt_id , cycle );1633 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle ); 1632 1634 #endif 1633 1635 1634 1636 } // end process_txt_attach() 1635 1637 1636 ////////////////////////////////////////////// 1637 void process_txt_detach( process_t * process ) 1638 { 1638 ///////////////////////////////////////////// 1639 void process_txt_detach( xptr_t process_xp ) 1640 { 1641 process_t * process_ptr; // local pointer on process in owner cluster 1642 cxy_t process_cxy; // process owner cluster 1643 pid_t process_pid; // process identifier 1644 xptr_t file_xp; // extended pointer on stdin file 1639 1645 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1640 1646 cxy_t chdev_cxy; // TXT_RX chdev cluster … … 1642 1648 xptr_t lock_xp; // extended pointer on list lock in chdev 1643 1649 1650 // get process cluster, local pointer, and PID 1651 process_cxy = GET_CXY( process_xp ); 1652 process_ptr = GET_PTR( process_xp ); 1653 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1654 1655 // check process descriptor in owner cluster 1656 assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ , 1657 "process descriptor not in owner cluster" ); 1658 1644 1659 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1645 1660 uint32_t cycle = (uint32_t)hal_get_cycles(); 1646 1661 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1647 1662 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n", 1648 __FUNCTION__, CURRENT_THREAD, process, cycle ); 1649 #endif 1650 1651 // check process is reference 1652 assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ , 1653 "process is not the reference descriptor" ); 1654 1655 // get extended pointer on TXT_RX chdev 1656 chdev_xp = chdev_from_file( process->fd_array.array[0] ); 1663 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1664 #endif 1665 1666 // release TXT ownership (does nothing if not TXT owner) 1667 process_txt_transfer_ownership( process_xp ); 1668 1669 // get extended pointer on process stdin file 1670 file_xp = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1671 1672 // get pointers on TXT_RX chdev 1673 chdev_xp = chdev_from_file( file_xp ); 1657 1674 chdev_cxy = GET_CXY( chdev_xp ); 1658 1675 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 1659 1676 1660 // get extended pointer on lock ofattached process list1677 // get extended pointer on lock protecting attached process list 1661 1678 lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock ); 1662 1679 1663 1680 // unlink process from attached process list 1664 1681 remote_spinlock_lock( lock_xp ); 1665 xlist_unlink( XPTR( local_cxy , &process->txt_list ) );1682 xlist_unlink( XPTR( process_cxy , &process_ptr->txt_list ) ); 1666 1683 remote_spinlock_unlock( lock_xp ); 1667 1684 1685 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1686 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1687 { 1688 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root ); 1689 xptr_t iter_xp; 1690 XLIST_FOREACH( root_xp , iter_xp ) 1691 { 1692 xptr_t current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1693 process_t * current_ptr = GET_PTR( current_xp ); 1694 1695 printk("\n[DBG] %s : attached_process %x (pid = %x)\n", 1696 __FUNCTION__, current_ptr, current_ptr->pid ); 1697 } 1698 } 1699 #endif 1700 1668 1701 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1669 1702 cycle = (uint32_t)hal_get_cycles(); 1670 1703 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1671 printk("\n[DBG] %s : thread %x exit for process %x/ cycle %d\n",1672 __FUNCTION__, CURRENT_THREAD, process , cycle );1704 printk("\n[DBG] %s : thread %x exit / process %x detached from TXT / cycle %d\n", 1705 __FUNCTION__, CURRENT_THREAD, process->pid, cycle ); 1673 1706 #endif 1674 1707 … … 1680 1713 process_t * process_ptr; 1681 1714 cxy_t process_cxy; 1715 pid_t process_pid; 1682 1716 xptr_t file_xp; 1683 1717 xptr_t txt_xp; … … 1685 1719 cxy_t txt_cxy; 1686 1720 1687 // get cluster and local pointer on process1721 // get pointers on process in owner cluster 1688 1722 process_cxy = GET_CXY( process_xp ); 1689 1723 process_ptr = GET_PTR( process_xp ); 1724 1725 // get process PID 1726 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1727 1728 // check owner cluster 1729 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1730 "process descriptor not in owner cluster\n" ); 1731 1732 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1733 uint32_t cycle = (uint32_t)hal_get_cycles(); 1734 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1735 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n", 1736 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1737 #endif 1690 1738 1691 1739 // get extended pointer on stdin pseudo file … … 1700 1748 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , process_xp ); 1701 1749 1750 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1751 cycle = (uint32_t)hal_get_cycles(); 1752 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1753 printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n", 1754 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1755 #endif 1756 1702 1757 } // end process_txt_set ownership() 1703 1758 1704 ///////////////////////////////////////////////////// 1705 void process_txt_reset_ownership( xptr_t process_xp ) 1706 { 1707 process_t * process_ptr; 1708 cxy_t process_cxy; 1709 xptr_t parent_xp; // extended pointer on parent process 1710 process_t * parent_ptr; 1711 cxy_t parent_cxy; 1759 //////////////////////////////////////////////////////// 1760 void process_txt_transfer_ownership( xptr_t process_xp ) 1761 { 1762 process_t * process_ptr; // local pointer on process releasing ownership 1763 cxy_t process_cxy; // process cluster 1764 pid_t process_pid; // process identifier 1712 1765 xptr_t file_xp; // extended pointer on TXT_RX pseudo file 1713 1766 xptr_t txt_xp; // extended pointer on TXT_RX chdev … … 1717 1770 xptr_t owner_xp; // extended pointer on current TXT_RX owner 1718 1771 xptr_t root_xp; // extended pointer on root of attached process list 1772 xptr_t lock_xp; // extended pointer on lock protecting attached process list 1719 1773 xptr_t iter_xp; // iterator for xlist 1720 1774 xptr_t current_xp; // extended pointer on current process 1721 1775 process_t * current_ptr; // local pointer on current process 1722 1776 cxy_t current_cxy; // cluster for current process 1723 pid_t ppid; // parent process identifier for current process 1724 1725 // get cluster and local pointer on process 1777 1778 // get pointers on process in owner cluster 1726 1779 process_cxy = GET_CXY( process_xp ); 1727 1780 process_ptr = GET_PTR( process_xp ); 1781 1782 // get process PID 1783 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1784 1785 // check owner cluster 1786 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1787 "process descriptor not in owner cluster\n" ); 1788 1789 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1790 uint32_t cycle = (uint32_t)hal_get_cycles(); 1791 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1792 printk("\n[DBG] %s : thread %x enter / process %x / pid %x / cycle %d\n", 1793 __FUNCTION__, CURRENT_THREAD, process_ptr, process_pid, cycle ); 1794 #endif 1728 1795 1729 1796 // get extended pointer on stdin pseudo file … … 1739 1806 txt_id = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) ); 1740 1807 1741 // transfer ownership to KSH if required 1742 if( (owner_xp == process_xp) && (txt_id > 0) ) 1743 { 1744 // get extended pointer on root of list of attached processes 1745 root_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.root ) ); 1746 1747 // scan attached process list to find KSH process 1748 XLIST_FOREACH( root_xp , iter_xp ) 1808 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1809 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1810 printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n", 1811 __FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) ); 1812 #endif 1813 1814 // transfer ownership only if process is the TXT owner 1815 if( (owner_xp == process_xp) && (txt_id > 0) ) 1816 { 1817 // get extended pointers on root and lock of attached processes list 1818 root_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.root ); 1819 lock_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.lock ); 1820 1821 // get lock 1822 remote_spinlock_lock( lock_xp ); 1823 1824 if( process_get_ppid( process_xp ) != 1 ) // process is not KSH 1749 1825 { 1750 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1751 current_cxy = GET_CXY( current_xp ); 1752 current_ptr = GET_PTR( current_xp ); 1753 parent_xp = hal_remote_lwd( XPTR( current_cxy , ¤t_ptr->parent_xp ) ); 1754 parent_cxy = GET_CXY( parent_xp ); 1755 parent_ptr = GET_PTR( parent_xp ); 1756 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 1757 1758 printk("\n@@@ %s : pid = %x / process = %x\n", __FUNCTION__ , current_ptr->pid, current_ptr ); 1759 1760 if( ppid == 1 ) // current is KSH 1826 1827 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1828 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1829 printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ ); 1830 #endif 1831 // scan attached process list to find KSH process 1832 XLIST_FOREACH( root_xp , iter_xp ) 1761 1833 { 1762 // set owner field in TXT chdev 1763 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1764 return; 1834 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1835 current_cxy = GET_CXY( current_xp ); 1836 current_ptr = GET_PTR( current_xp ); 1837 1838 if( process_get_ppid( current_xp ) == 1 ) // current is KSH 1839 { 1840 // release lock 1841 remote_spinlock_unlock( lock_xp ); 1842 1843 // set owner field in TXT chdev 1844 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1845 1846 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1847 cycle = (uint32_t)hal_get_cycles(); 1848 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1849 printk("\n[DBG] %s : thread %x exit / process %x to KSH process %x / cycle %d\n", 1850 __FUNCTION__, CURRENT_THREAD, process_pid, 1851 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle ); 1852 #endif 1853 return; 1854 } 1765 1855 } 1856 1857 // release lock 1858 remote_spinlock_unlock( lock_xp ); 1859 1860 // PANIC if KSH not found 1861 assert( false , __FUNCTION__ , "KSH process not found for TXT %d" ); 1862 1863 return; 1766 1864 } 1767 1768 assert( false , __FUNCTION__ , "KSH process not found" ); 1769 } 1770 } // end process_txt_reset_ownership() 1771 1772 1773 ////////////////////////////////////////////////////// 1774 inline pid_t process_get_txt_owner( uint32_t channel ) 1865 else // process is KSH 1866 { 1867 1868 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1869 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1870 printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ ); 1871 #endif 1872 1873 // scan attached process list to find another process 1874 XLIST_FOREACH( root_xp , iter_xp ) 1875 { 1876 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1877 current_cxy = GET_CXY( current_xp ); 1878 current_ptr = GET_PTR( current_xp ); 1879 1880 if( current_xp != process_xp ) // current is not KSH 1881 { 1882 // release lock 1883 remote_spinlock_unlock( lock_xp ); 1884 1885 // set owner field in TXT chdev 1886 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1887 1888 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1889 cycle = (uint32_t)hal_get_cycles(); 1890 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1891 printk("\n[DBG] %s : thread %x exit / KSH process %x to process %x / cycle %d\n", 1892 __FUNCTION__, CURRENT_THREAD, process_pid, 1893 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle ); 1894 #endif 1895 return; 1896 } 1897 } 1898 1899 // release lock 1900 remote_spinlock_unlock( lock_xp ); 1901 1902 // no more owner for TXT if no other process found 1903 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL ); 1904 1905 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1906 cycle = (uint32_t)hal_get_cycles(); 1907 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1908 printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n", 1909 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1910 #endif 1911 return; 1912 } 1913 } 1914 else 1915 { 1916 1917 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1918 cycle = (uint32_t)hal_get_cycles(); 1919 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1920 printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n", 1921 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1922 #endif 1923 1924 } 1925 } // end process_txt_transfer_ownership() 1926 1927 1928 //////////////////////////////////////////////// 1929 xptr_t process_txt_get_owner( uint32_t channel ) 1775 1930 { 1776 1931 xptr_t txt_rx_xp = chdev_dir.txt_rx[channel]; … … 1778 1933 chdev_t * txt_rx_ptr = GET_PTR( txt_rx_xp ); 1779 1934 1780 xptr_t process_xp = (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy, 1781 &txt_rx_ptr->ext.txt.owner_xp ) ); 1782 1783 cxy_t process_cxy = GET_CXY( process_xp ); 1784 process_t * process_ptr = GET_PTR( process_xp ); 1785 1786 return (pid_t)hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1935 return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) ); 1787 1936 } 1788 1937 … … 1817 1966 remote_spinlock_lock( lock_xp ); 1818 1967 1819 // scan attached process list to find KSH process1968 // scan attached process list 1820 1969 XLIST_FOREACH( root_xp , iter_xp ) 1821 1970 { -
trunk/kernel/kern/process.h
r435 r436 58 58 enum process_sigactions 59 59 { 60 BLOCK_ALL_THREADS = 11,61 UNBLOCK_ALL_THREADS = 22,62 DELETE_ALL_THREADS = 33,60 BLOCK_ALL_THREADS = 0x11, 61 UNBLOCK_ALL_THREADS = 0x22, 62 DELETE_ALL_THREADS = 0x33, 63 63 }; 64 64 … … 281 281 * This function allows a client thread running in any cluster to block, unblock or delete 282 282 * all threads of a process identified by the <pid> argument, depending on the 283 * <action_type> argument. The scenario is the following: 284 * - It uses the multicast, non blocking rpc_process_sigaction_client() function to send 285 * parallel requests to all remote clusters containing a process copy. Then it blocks 286 $ and deschedule to wait completion of these parrallel requests. 287 * - In each remote cluster, the rpc_process_sigaction_server() function, calls directly 288 * the relevant process_block(), process_unblock(), or process_delete() function, and 289 * decrement the responses counter to signal completion. The last server unblock 290 * the client thread. 291 * - Finally, the client thread calls directly the process_block(), process_unblock(), or 292 * process_delete() function in the owner cluster. 283 * <action_type> argument. 284 * WARNING : the DELETE action is NOT executed on the target process main thread 285 * (thread 0 in process owner cluster). 286 * It uses the multicast, non blocking rpc_process_sigaction_client() function to send 287 * parallel requests to all remote clusters containing a process copy. 288 * Then it blocks and deschedule to wait completion of these parallel requests. 289 * 293 290 * It is used by the sys_kill() & sys_exit() functions to handle the "kill" & "exit" syscalls. 294 291 * It is also used by the process_make_exec() function to handle the "exec" syscall. 295 * It is also called by the TXT device to execute the ctrl C & ctrl Z commands. 296 * WARNING : the DELETE action is NOT executed on the main thread (thread 0 in owner cluster). 292 * It is also called by the TXT device ISR to execute the ctrl C & ctrl Z commands. 293 * 294 * Implementation note: 295 * This function allocates a - shared - RPC descriptor in client thread stack, 296 * and initializes it. This RPC descriptor can be shared because all parallel, 297 * non-blocking, RPC server threads use the same input arguments, including the 298 * RPC responses counter field. 297 299 ********************************************************************************************* 298 300 * @ pid : target process identifier. … … 303 305 304 306 /********************************************************************************************* 305 * This function blocks all threads for a given <process> in a given cluster. 306 * The calling thread cannot be a target thread. 307 * It loops on all local threads of the process, set the THREAD_BLOCKED_GLOBAL bit, 307 * This function blocks all threads - but the main thread - for a given <process> 308 * in a given cluster. It sets the THREAD_BLOCKED_GLOBAL bit in the thread descriptor, 308 309 * and request the relevant schedulers to acknowledge the blocking, using IPI if required. 309 310 * The threads are not detached from the scheduler, and not detached from the local process. … … 322 323 323 324 /********************************************************************************************* 324 * This function marks for deletion all threads - but one _ for a given <process> 325 * in a given cluster. The main thread in owner cluster is NOT marked. 326 * It will be marked for deletion by the parent process sys_wait(). 327 * The calling thread cannot be a target thread. 328 * It loops on all local threads of the process, and set the THREAD_FLAG_REQ_DELETE bit. 329 * For each marked thread, the following actions will be done by the scheduler at the next 330 * scheduling point: 325 * This function marks for deletion all threads - but the main thread - for a given <process> 326 * in a given cluster. It sets the THREAD_FLAG_REQ_DELETE bit. For each marked thread, 327 * the following actions will be done by the scheduler at the next scheduling point: 331 328 * - the thread will be detached from the scheduler. 332 329 * - the thread will be detached from the local process descriptor. … … 349 346 ********************************************************************************************/ 350 347 process_t * process_get_local_copy( pid_t pid ); 348 349 /********************************************************************************************* 350 * This function returns the parent process identifier for a remote process descriptor 351 * identified by an extended pointer. 352 ********************************************************************************************* 353 * @ process_xp : extended pointer on remote process descriptor. 354 * @ returns parent process dentifier. 355 ********************************************************************************************/ 356 pid_t process_get_ppid( xptr_t process_xp ); 351 357 352 358 /********************************************************************************************* … … 508 514 509 515 /********************************************************************************************* 510 * This function attach a reference process descriptor, identified by the <process>516 * This function attach a process descriptor in owner cluster, identified by the <process> 511 517 * argument to a TXT terminal, identified by its <txt_id> channel index argument. 512 518 * It insert the process descriptor in the xlist rooted in the TXT_RX device. … … 520 526 521 527 /********************************************************************************************* 522 * This function detach a reference process descriptor, identified by the <process_xp> 523 * argument, from the list of process attached to a given TXT terminal. 524 * It is called when the process is killed. 525 ********************************************************************************************* 526 * @ process : local pointer on process descriptor. 527 ********************************************************************************************/ 528 void process_txt_detach( process_t * process ); 529 530 /********************************************************************************************* 531 * This function gives to a process identified by the <process_xp> argument, and attached 528 * This function detach a process, identified by the <process_xp> argument, 529 * from the list of process attached to a given TXT terminal. 530 * The target process descriptor must be in the owner cluster, but the calling thread can 531 * be running in any cluster. 532 ********************************************************************************************* 533 * @ process_xp : extended pointer on process descriptor. 534 ********************************************************************************************/ 535 void process_txt_detach( xptr_t process_xp ); 536 537 /********************************************************************************************* 538 * This function gives to a process identified by the <owner_xp> argument, and attached 532 539 * to terminal TXT[i] the exclusive ownership of the TXT_RX[i] terminal. 533 ********************************************************************************************* 534 * @ process_xp : extended pointer on reference process descriptor. 535 ********************************************************************************************/ 536 void process_txt_set_ownership( xptr_t process_xp ); 537 538 /********************************************************************************************* 539 * When the process identified by the <process_xp> argument has the exclusive ownership 540 * of the TXT_RX[i] terminal, this function gives this ownership to the KSH[i] process. 541 * It does nothing if the process is not the owner. 542 ********************************************************************************************* 543 * @ process_xp : extended pointer on reference process descriptor. 544 ********************************************************************************************/ 545 void process_txt_reset_ownership( xptr_t process_xp ); 546 547 /********************************************************************************************* 548 * This function returns the terminal owner process (foreground process) 540 * The process descriptor must be in the process owner cluster. 541 ********************************************************************************************* 542 * @ owner_xp : extended pointer on process descriptor in owner cluster. 543 ********************************************************************************************/ 544 void process_txt_set_ownership( xptr_t owner_xp ); 545 546 /********************************************************************************************* 547 * When the process dentified by the <owner_xp> argument has the exclusive ownership of 548 * the TXT_RX terminal, this function transfer this ownership to another attached process. 549 * The process descriptor must be in the process owner cluster. 550 * This function does nothing if the <pid> process is not the owner. 551 * - If the current owner is not the KSH process, the new owner is the KSH process. 552 * - If the <pid> process is the the KSH process, the new owner is another attached process. 553 * - If there is no other attached process, the TXT has no more defined owner. 554 ********************************************************************************************* 555 * @ owner_xp : extended pointer on process descriptor in owner cluster. 556 ********************************************************************************************/ 557 void process_txt_transfer_ownership( xptr_t owner_xp ); 558 559 /********************************************************************************************* 560 * This function returns the TXT owner process (foreground process) 549 561 * for a given TXT terminal identified by its <channel> index. 550 562 ********************************************************************************************* 551 563 * @ channel : TXT terminal channel. 552 * @ return owner process identifier.553 ********************************************************************************************/ 554 pid_t process_get_txt_owner( uint32_t channel );564 * @ return extentded pointer on TXT owner process in owner cluster. 565 ********************************************************************************************/ 566 xptr_t process_txt_get_owner( uint32_t channel ); 555 567 556 568 /********************************************************************************************* -
trunk/kernel/kern/rpc.c
r435 r436 82 82 &rpc_thread_user_create_server, // 6 83 83 &rpc_thread_kernel_create_server, // 7 84 &rpc_ thread_kill_server, // 884 &rpc_undefined, // 8 unused slot 85 85 &rpc_process_sigaction_server, // 9 86 86 … … 122 122 rpc_desc_t * rpc ) 123 123 { 124 error_t error; 125 126 thread_t * this = CURRENT_THREAD; 127 core_t * core = this->core; 124 volatile error_t full = 0; 125 thread_t * this = CURRENT_THREAD; 126 core_t * core = this->core; 127 128 #if CONFIG_DEBUG_RPC_SEND 129 uint32_t cycle = (uint32_t)hal_get_cycles(); 130 if( CONFIG_DEBUG_RPC_SEND < cycle ) 131 printk("\n[DBG] %s : thread %x enter for rpc[%d] / rpc_ptr %x / cycle %d\n", 132 __FUNCTION__, CURRENT_THREAD, rpc->index, rpc, cycle ); 133 #endif 128 134 129 135 // register client thread pointer and core lid in RPC descriptor 130 rpc->thread 131 rpc->lid 136 rpc->thread = this; 137 rpc->lid = core->lid; 132 138 133 139 // build an extended pointer on the RPC descriptor 134 140 xptr_t desc_xp = XPTR( local_cxy , rpc ); 135 141 136 // get local pointer on rpc_fifo in remote cluster, with the 137 // assumption that local pointers are identical in all clusters 142 // get local pointer on rpc_fifo in remote cluster, 138 143 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 139 144 140 // try to post an item in remote fifo 141 // deschedule and retry if remote fifo full 145 // post RPC in remote fifo / deschedule and retry if fifo full 142 146 do 143 147 { 144 error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), 145 (uint64_t )desc_xp ); 146 if ( error ) 148 full = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), (uint64_t )desc_xp ); 149 if ( full ) 147 150 { 148 151 printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n", 149 152 __FUNCTION__ , local_cxy , server_cxy ); 150 153 151 if( thread_can_yield() ) sched_yield("RPC fifo full"); 154 // deschedule without blocking 155 sched_yield("RPC fifo full"); 152 156 } 153 157 } 154 while( error);158 while( full ); 155 159 156 160 hal_fence(); … … 167 171 { 168 172 169 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n" 170 " rpc = %d / server = %x / cycle %d\n", 171 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 172 rpc->index , server_cxy , hal_time_stamp() ); 173 #if CONFIG_DEBUG_RPC_SEND 174 cycle = (uint32_t)hal_get_cycles(); 175 if( CONFIG_DEBUG_RPC_SEND < cycle ) 176 printk("\n[DBG] %s : thread %x busy waiting / rpc[%d] / server = %x / cycle %d\n", 177 __FUNCTION__, CURRENT_THREAD, rpc->index , server_cxy , cycle ); 178 #endif 173 179 174 180 while( rpc->response ) hal_fixed_delay( 100 ); 175 181 176 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n", 177 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 178 182 #if CONFIG_DEBUG_RPC_SEND 183 cycle = (uint32_t)hal_get_cycles(); 184 if( CONFIG_DEBUG_RPC_SEND < cycle ) 185 printk("\n[DBG] %s : thread % resume / rpc[%d] / cycle %d\n", 186 __FUNCTION__, CURRENT_THREAD, rpc->index, cycle ); 187 #endif 179 188 } 180 else 189 else // block & deschedule 181 190 { 182 191 183 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n" 184 " rpc = %d / server = %x / cycle %d\n", 185 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 186 rpc->index , server_cxy , hal_time_stamp() ); 187 188 thread_block( this , THREAD_BLOCKED_RPC ); 189 sched_yield("BLOCKED on RPC"); 190 191 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n", 192 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 193 192 #if CONFIG_DEBUG_RPC_SEND 193 cycle = (uint32_t)hal_get_cycles(); 194 if( CONFIG_DEBUG_RPC_SEND < cycle ) 195 printk("\n[DBG] %s : thread %x block & deschedule / rpc[%d] / server = %x / cycle %d\n", 196 __FUNCTION__, CURRENT_THREAD, rpc->index , server_cxy , cycle ); 197 #endif 198 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC ); 199 sched_yield("blocked on RPC"); 200 201 #if CONFIG_DEBUG_RPC_SEND 202 cycle = (uint32_t)hal_get_cycles(); 203 if( CONFIG_DEBUG_RPC_SEND < cycle ) 204 printk("\n[DBG] %s : thread % resume / rpcr[%d] / cycle %d\n", 205 __FUNCTION__, CURRENT_THREAD, rpc->index, cycle ); 206 #endif 194 207 } 195 208 … … 199 212 // acknowledge the IPI sent by the server 200 213 dev_pic_ack_ipi(); 214 } 215 else 216 { 217 218 #if CONFIG_DEBUG_RPC_SEND 219 cycle = (uint32_t)hal_get_cycles(); 220 if( CONFIG_DEBUG_RPC_SEND < cycle ) 221 printk("\n[DBG] %s : non blocking rpc[%d] => thread return / cycle %d\n", 222 __FUNCTION__, rpc->index, CURRENT_THREAD, cycle ); 223 #endif 224 201 225 } 202 226 } // end rpc_send() … … 220 244 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 221 245 222 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n", 223 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 246 #if CONFIG_DEBUG_RPC_SERVER 247 uint32_t cycle = (uint32_t)hal_get_cycles(); 248 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 249 printk("\n[DBG] %s : thread %x interrupted in cluster %x / cycle %d\n", 250 __FUNCTION__, this, local_cxy, cycle ); 251 #endif 224 252 225 253 // interrupted thread not preemptable during RPC chek … … 262 290 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 263 291 264 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / trdid %x / cycle %d\n", 265 __FUNCTION__ , local_cxy , core->lid , thread , thread->trdid , hal_time_stamp() ); 266 292 #if CONFIG_DEBUG_RPC_SERVER 293 cycle = (uint32_t)hal_get_cycles(); 294 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 295 printk("\n[DBG] %s : create a new RPC thread %x in cluster %x / cycle %d\n", 296 __FUNCTION__, thread, local_cxy, cycle ); 297 #endif 267 298 } 268 299 } 269 300 } 270 301 271 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n", 272 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 302 #if CONFIG_DEBUG_RPC_SERVER 303 cycle = (uint32_t)hal_get_cycles(); 304 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 305 printk("\n[DBG] %s : interrupted thread %x deschedules in cluster %x / cycle %d\n", 306 __FUNCTION__, this, local_cxy, cycle ); 307 #endif 273 308 274 309 // interrupted thread deschedule always 275 310 sched_yield("IPI received"); 276 311 277 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", 278 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 312 #if CONFIG_DEBUG_RPC_SERVER 313 cycle = (uint32_t)hal_get_cycles(); 314 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 315 printk("\n[DBG] %s : interrupted thread %x resumes in cluster %x / cycle %d\n", 316 __FUNCTION__, this, local_cxy, cycle ); 317 #endif 279 318 280 319 // interrupted thread restore IRQs after resume … … 312 351 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 313 352 { 353 354 #if CONFIG_DEBUG_RPC_SERVER 355 uint32_t cycle = (uint32_t)hal_get_cycles(); 356 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 357 printk("\n[DBG] %s : RPC thread %x takes RPC fifo ownership / cluster %x / cycle %d\n", 358 __FUNCTION__, this, local_cxy, cycle ); 359 #endif 314 360 // initializes RPC requests counter 315 361 count = 0; … … 324 370 while( 1 ) // internal loop 325 371 { 326 327 372 empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp ); 328 373 … … 330 375 { 331 376 // get client cluster and pointer on RPC descriptor 332 desc_cxy = (cxy_t)GET_CXY( desc_xp ); 333 desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp ); 334 335 // get RPC <index> & <blocking> fields from RPC descriptor 336 index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) ); 337 blocking = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->blocking ) ); 338 339 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n", 340 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , (uint32_t)hal_get_cycles() ); 341 377 desc_cxy = GET_CXY( desc_xp ); 378 desc_ptr = GET_PTR( desc_xp ); 379 380 index = desc_ptr->index; 381 blocking = desc_ptr->blocking; 382 383 #if CONFIG_DEBUG_RPC_SERVER 384 cycle = (uint32_t)hal_get_cycles(); 385 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 386 printk("\n[DBG] %s : RPC thread %x got rpc[%d] / rpc_ptr %x / cycle %d\n", 387 __FUNCTION__, this, index, desc_ptr, cycle ); 388 #endif 342 389 // call the relevant server function 343 390 rpc_server[index]( desc_xp ); 344 391 345 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n", 346 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 347 392 #if CONFIG_DEBUG_RPC_SERVER 393 cycle = (uint32_t)hal_get_cycles(); 394 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 395 printk("\n[DBG] %s : RPC thread %x completes rpc %d in cluster %x / cycle %d\n", 396 __FUNCTION__, this, index, local_cxy, cycle ); 397 #endif 348 398 // increment handled RPCs counter 349 399 count++; … … 382 432 { 383 433 384 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n", 385 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 386 434 #if CONFIG_DEBUG_RPC_SERVER 435 uint32_t cycle = (uint32_t)hal_get_cycles(); 436 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 437 printk("\n[DBG] %s : RPC thread %x suicides in cluster %x / cycle %d\n", 438 __FUNCTION__, this, local_cxy, cycle ); 439 #endif 387 440 // update RPC threads counter 388 441 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 ); 389 442 390 443 // suicide 391 thread_kill( this ); 444 thread_kill( XPTR( local_cxy , this ), 445 true, // is_exit 446 true ); // is forced 392 447 } 393 448 394 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n", 395 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 449 #if CONFIG_DEBUG_RPC_SERVER 450 uint32_t cycle = (uint32_t)hal_get_cycles(); 451 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 452 printk("\n[DBG] %s : RPC thread %x deschedules in cluster %x / cycle %d\n", 453 __FUNCTION__, this, local_cxy, cycle ); 454 #endif 396 455 397 456 // deschedule without blocking 398 457 sched_yield("RPC fifo empty or too much work"); 399 458 400 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", 401 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 459 #if CONFIG_DEBUG_RPC_SERVER 460 cycle = (uint32_t)hal_get_cycles(); 461 if( CONFIG_DEBUG_RPC_SERVER < cycle ) 462 printk("\n[DBG] %s : RPC thread %x resumes in cluster %x / cycle %d\n", 463 __FUNCTION__, this, local_cxy, cycle ); 464 #endif 402 465 403 466 } // end external loop … … 430 493 rpc.args[0] = (uint64_t)order; 431 494 432 // register RPC request in remote RPC fifo (blocking function)495 // register RPC request in remote RPC fifo 433 496 rpc_send( cxy , &rpc ); 434 497 … … 449 512 450 513 // get client cluster identifier and pointer on RPC descriptor 451 cxy_t cxy = (cxy_t)GET_CXY( xp );452 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );514 cxy_t cxy = GET_CXY( xp ); 515 rpc_desc_t * desc = GET_PTR( xp ); 453 516 454 517 // get input arguments from client RPC descriptor … … 489 552 rpc.args[0] = (uint64_t)(intptr_t)page; 490 553 491 // register RPC request in remote RPC fifo (blocking function)554 // register RPC request in remote RPC fifo 492 555 rpc_send( cxy , &rpc ); 493 556 … … 505 568 506 569 // get client cluster identifier and pointer on RPC descriptor 507 cxy_t cxy = (cxy_t)GET_CXY( xp );508 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );570 cxy_t cxy = GET_CXY( xp ); 571 rpc_desc_t * desc = GET_PTR( xp ); 509 572 510 573 // get input arguments from client RPC descriptor … … 554 617 rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp; 555 618 556 // register RPC request in remote RPC fifo (blocking function)619 // register RPC request in remote RPC fifo 557 620 rpc_send( cxy , &rpc ); 558 621 … … 581 644 582 645 // get client cluster identifier and pointer on RPC descriptor 583 cxy_t client_cxy = (cxy_t)GET_CXY( xp );584 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );646 cxy_t client_cxy = GET_CXY( xp ); 647 rpc_desc_t * desc = GET_PTR( xp ); 585 648 586 649 // get input arguments from cient RPC descriptor … … 613 676 614 677 ///////////////////////////////////////////////////////////////////////////////////////// 615 // [6] 678 // [6] Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 616 679 ///////////////////////////////////////////////////////////////////////////////////////// 617 680 … … 633 696 // initialise RPC descriptor header 634 697 rpc_desc_t rpc; 635 rpc.index 636 rpc.response 698 rpc.index = RPC_THREAD_USER_CREATE; 699 rpc.response = 1; 637 700 rpc.blocking = true; 638 701 … … 643 706 rpc.args[3] = (uint64_t)(intptr_t)attr; 644 707 645 // register RPC request in remote RPC fifo (blocking function)708 // register RPC request in remote RPC fifo 646 709 rpc_send( cxy , &rpc ); 647 710 … … 673 736 674 737 // get client cluster identifier and pointer on RPC descriptor 675 cxy_t client_cxy = (cxy_t)GET_CXY( xp );676 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );738 cxy_t client_cxy = GET_CXY( xp ); 739 rpc_desc_t * desc = GET_PTR( xp ); 677 740 678 741 // get pointer on attributes structure in client cluster from RPC descriptor … … 707 770 708 771 ///////////////////////////////////////////////////////////////////////////////////////// 709 // [7] 772 // [7] Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking) 710 773 ///////////////////////////////////////////////////////////////////////////////////////// 711 774 … … 735 798 rpc.args[2] = (uint64_t)(intptr_t)args; 736 799 737 // register RPC request in remote RPC fifo (blocking function)800 // register RPC request in remote RPC fifo 738 801 rpc_send( cxy , &rpc ); 739 802 … … 760 823 761 824 // get client cluster identifier and pointer on RPC descriptor 762 cxy_t client_cxy = (cxy_t)GET_CXY( xp );763 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );825 cxy_t client_cxy = GET_CXY( xp ); 826 rpc_desc_t * desc = GET_PTR( xp ); 764 827 765 828 // get attributes from RPC descriptor … … 785 848 786 849 ///////////////////////////////////////////////////////////////////////////////////////// 787 // [8] Marshaling functions attached to RPC_THREAD_KILL (blocking) 788 ///////////////////////////////////////////////////////////////////////////////////////// 789 790 ///////////////////////////////////////////// 791 void rpc_thread_kill_client( cxy_t cxy, 792 thread_t * thread ) // in 793 { 794 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 795 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 796 CURRENT_THREAD->core->lid , hal_time_stamp() ); 797 798 // this RPC can be called in local cluster 799 800 // initialise RPC descriptor header 801 rpc_desc_t rpc; 802 rpc.index = RPC_THREAD_KILL; 803 rpc.response = 1; 804 rpc.blocking = true; 805 806 // set input arguments in RPC descriptor 807 rpc.args[0] = (uint64_t)(intptr_t)thread; 808 809 // register RPC request in remote RPC fifo (blocking function) 810 rpc_send( cxy , &rpc ); 811 812 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 813 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 814 CURRENT_THREAD->core->lid , hal_time_stamp() ); 815 } 816 817 //////////////////////////////////////// 818 void rpc_thread_kill_server( xptr_t xp ) 819 { 820 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 821 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 822 CURRENT_THREAD->core->lid , hal_time_stamp() ); 823 824 thread_t * thread; // local pointer on process descriptor 825 826 // get client cluster identifier and pointer on RPC descriptor 827 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 828 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 829 830 // get attributes from RPC descriptor 831 thread = (thread_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 832 833 // call local kernel function 834 thread_kill( thread ); 835 836 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 837 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 838 CURRENT_THREAD->core->lid , hal_time_stamp() ); 839 } 850 // [8] undefined slot 851 ///////////////////////////////////////////////////////////////////////////////////////// 840 852 841 853 … … 846 858 //////////////////////////////////////////////////// 847 859 void rpc_process_sigaction_client( cxy_t cxy, 848 rpc_desc_t * rpc_ptr ) 849 { 850 rpc_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n", 851 __FUNCTION__ , process_action_str( (uint32_t)rpc_ptr->args[0] ) , 852 ((process_t *)(intptr_t)rpc_ptr->args[1])->pid , cxy , (uint32_t)hal_get_cycles() ); 853 854 // register RPC request in remote RPC fifo 855 rpc_send( cxy , rpc_ptr ); 856 857 rpc_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n", 858 __FUNCTION__ , process_action_str( (uint32_t)rpc_ptr->args[0] ) , 859 ((process_t *)(intptr_t)rpc_ptr->args[1])->pid , cxy , (uint32_t)hal_get_cycles() ); 860 } 860 rpc_desc_t * rpc ) 861 { 862 863 #if (CONFIG_DEBUG_PROCESS_SIGACTION & 1) 864 uint32_t cycle = (uint32_t)hal_get_cycles(); 865 uint32_t action = rpc->args[0]; 866 pid_t pid = rpc->args[1]; 867 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 868 printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n", 869 __FUNCTION__ , process_action_str( action ) , pid , cxy , cycle ); 870 #endif 871 872 // check some RPC arguments 873 assert( (rpc->blocking == false) , __FUNCTION__ , "must be non-blocking\n"); 874 assert( (rpc->index == RPC_PROCESS_SIGACTION ) , __FUNCTION__ , "bad RPC index\n" ); 875 876 // register RPC request in remote RPC fifo and return 877 rpc_send( cxy , rpc ); 878 879 #if (CONFIG_DEBUG_PROCESS_SIGACTION & 1) 880 cycle = (uint32_t)hal_get_cycles(); 881 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 882 printk("\n[DBG] %s : exit after requesting to %s process %x in cluster %x / cycle %d\n", 883 __FUNCTION__ , process_action_str( action ) , pid , cxy , cycle ); 884 #endif 885 886 } // end rpc_process_sigaction_client() 861 887 862 888 ////////////////////////////////////////////// … … 864 890 { 865 891 pid_t pid; // target process identifier 866 process_t * process; // pointer on local process descriptor892 process_t * process; // pointer on local target process descriptor 867 893 uint32_t action; // sigaction index 868 thread_t * client_ ptr; // localpointer on client thread in client cluster894 thread_t * client_thread; // pointer on client thread in client cluster 869 895 cxy_t client_cxy; // client cluster identifier 870 xptr_t client_xp; // extended pointer on client thread871 core_t * client_core; // local pointer on core running the client thread872 rpc_desc_t * rpc; // local pointer on rpc descriptor in client cluster873 874 // get client cluster identifier and pointer on RPC descriptor 875 client_cxy = (cxy_t)GET_CXY( xp );876 rpc = (rpc_desc_t *)GET_PTR( xp );896 rpc_desc_t * rpc; // pointer on rpc descriptor in client cluster 897 xptr_t count_xp; // extended pointer on response counter 898 lid_t client_lid; // client core local index 899 900 // get client cluster identifier and pointer on RPC descriptor 901 client_cxy = GET_CXY( xp ); 902 rpc = GET_PTR( xp ); 877 903 878 904 // get arguments from RPC descriptor 879 action = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &rpc->args[0] ) ); 880 pid = (pid_t) hal_remote_lwd( XPTR( client_cxy , &rpc->args[1] ) ); 881 client_ptr = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) ); 882 883 rpc_dmsg("\n[DBG] %s : enter to %s process %x / cycle %d\n", 884 __FUNCTION__ , process_action_str( action ) , pid , (uint32_t)hal_get_cycles() ); 905 action = (uint32_t)hal_remote_lwd( XPTR(client_cxy , &rpc->args[0]) ); 906 pid = (pid_t) hal_remote_lwd( XPTR(client_cxy , &rpc->args[1]) ); 907 908 #if (CONFIG_DEBUG_PROCESS_SIGACTION & 1) 909 uint32_t cycle = (uint32_t)hal_get_cycles(); 910 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 911 printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n", 912 __FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle ); 913 #endif 885 914 886 915 // get local process descriptor 887 process = process_get_local_copy( pid ); 888 889 // build extended pointer on client thread 890 client_xp = XPTR( client_cxy , client_ptr ); 916 process = cluster_get_local_process_from_pid( pid ); 891 917 892 918 // call relevant kernel function 893 if (action == DELETE_ALL_THREADS ) process_delete_threads ( process ); 894 else if (action == BLOCK_ALL_THREADS ) process_block_threads ( process ); 895 else if (action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process ); 919 if ( action == DELETE_ALL_THREADS ) process_delete_threads ( process ); 920 else if ( action == BLOCK_ALL_THREADS ) process_block_threads ( process ); 921 else if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process ); 922 923 // build extended pointer on response counter in RPC 924 count_xp = XPTR( client_cxy , &rpc->response ); 896 925 897 926 // decrement the responses counter in RPC descriptor, 898 927 // unblock the client thread only if it is the last response. 899 if( hal_remote_atomic_add( XPTR( client_cxy , &rpc->response ), -1 ) == 1 )928 if( hal_remote_atomic_add( count_xp , -1 ) == 1 ) 900 929 { 901 client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) ); 902 thread_unblock( client_xp , THREAD_BLOCKED_RPC ); 903 dev_pic_send_ipi( client_cxy , client_core->lid ); 930 // get client thread pointer and client core lid 931 client_thread = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) ); 932 client_lid = (lid_t) hal_remote_lw ( XPTR( client_cxy , &rpc->lid ) ); 933 934 thread_unblock( XPTR( client_cxy , client_thread ) , THREAD_BLOCKED_RPC ); 935 dev_pic_send_ipi( client_cxy , client_lid ); 904 936 } 905 937 906 rpc_dmsg("\n[DBG] %s : exit after %s process %x / cycle %d\n", 907 __FUNCTION__ , process_action_str( action ) , pid , (uint32_t)hal_get_cycles() ); 908 } 909 910 ///////////////////////////////////////////////////////////////////////////////////////// 911 // [10] Marshaling functions attached to RPC_VFS_INODE_CREATE (blocking) 938 #if (CONFIG_DEBUG_PROCESS_SIGACTION & 1) 939 cycle = (uint32_t)hal_get_cycles(); 940 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 941 printk("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n", 942 __FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle ); 943 #endif 944 945 } // end rpc_process_sigaction_server() 946 947 ///////////////////////////////////////////////////////////////////////////////////////// 948 // [10] Marshaling functions attached to RPC_VFS_INODE_CREATE (blocking) 912 949 ///////////////////////////////////////////////////////////////////////////////////////// 913 950 … … 947 984 rpc.args[7] = (uint64_t)gid; 948 985 949 // register RPC request in remote RPC fifo (blocking function)986 // register RPC request in remote RPC fifo 950 987 rpc_send( cxy , &rpc ); 951 988 … … 978 1015 979 1016 // get client cluster identifier and pointer on RPC descriptor 980 cxy_t client_cxy = (cxy_t)GET_CXY( xp );981 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1017 cxy_t client_cxy = GET_CXY( xp ); 1018 rpc_desc_t * desc = GET_PTR( xp ); 982 1019 983 1020 // get input arguments from client rpc descriptor … … 1034 1071 rpc.args[0] = (uint64_t)(intptr_t)inode; 1035 1072 1036 // register RPC request in remote RPC fifo (blocking function)1073 // register RPC request in remote RPC fifo 1037 1074 rpc_send( cxy , &rpc ); 1038 1075 … … 1052 1089 1053 1090 // get client cluster identifier and pointer on RPC descriptor 1054 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1055 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1091 cxy_t client_cxy = GET_CXY( xp ); 1092 rpc_desc_t * desc = GET_PTR( xp ); 1056 1093 1057 1094 // get arguments "inode" from client RPC descriptor … … 1095 1132 rpc.args[2] = (uint64_t)(intptr_t)parent; 1096 1133 1097 // register RPC request in remote RPC fifo (blocking function)1134 // register RPC request in remote RPC fifo 1098 1135 rpc_send( cxy , &rpc ); 1099 1136 … … 1123 1160 1124 1161 // get client cluster identifier and pointer on RPC descriptor 1125 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1126 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1162 cxy_t client_cxy = GET_CXY( xp ); 1163 rpc_desc_t * desc = GET_PTR( xp ); 1127 1164 1128 1165 // get arguments "name", "type", and "parent" from client RPC descriptor … … 1173 1210 rpc.args[0] = (uint64_t)(intptr_t)dentry; 1174 1211 1175 // register RPC request in remote RPC fifo (blocking function)1212 // register RPC request in remote RPC fifo 1176 1213 rpc_send( cxy , &rpc ); 1177 1214 … … 1191 1228 1192 1229 // get client cluster identifier and pointer on RPC descriptor 1193 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1194 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1230 cxy_t client_cxy = GET_CXY( xp ); 1231 rpc_desc_t * desc = GET_PTR( xp ); 1195 1232 1196 1233 // get arguments "dentry" from client RPC descriptor … … 1233 1270 rpc.args[1] = (uint64_t)file_attr; 1234 1271 1235 // register RPC request in remote RPC fifo (blocking function)1272 // register RPC request in remote RPC fifo 1236 1273 rpc_send( cxy , &rpc ); 1237 1274 … … 1258 1295 1259 1296 // get client cluster identifier and pointer on RPC descriptor 1260 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1261 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1297 cxy_t client_cxy = GET_CXY( xp ); 1298 rpc_desc_t * desc = GET_PTR( xp ); 1262 1299 1263 1300 // get arguments "file_attr" and "inode" from client RPC descriptor … … 1302 1339 rpc.args[0] = (uint64_t)(intptr_t)file; 1303 1340 1304 // register RPC request in remote RPC fifo (blocking function)1341 // register RPC request in remote RPC fifo 1305 1342 rpc_send( cxy , &rpc ); 1306 1343 … … 1320 1357 1321 1358 // get client cluster identifier and pointer on RPC descriptor 1322 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1323 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1359 cxy_t client_cxy = GET_CXY( xp ); 1360 rpc_desc_t * desc = GET_PTR( xp ); 1324 1361 1325 1362 // get arguments "dentry" from client RPC descriptor … … 1362 1399 rpc.args[2] = (uint64_t)child_inode_xp; 1363 1400 1364 // register RPC request in remote RPC fifo (blocking function)1401 // register RPC request in remote RPC fifo 1365 1402 rpc_send( cxy , &rpc ); 1366 1403 … … 1388 1425 1389 1426 // get client cluster identifier and pointer on RPC descriptor 1390 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1391 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1427 cxy_t client_cxy = GET_CXY( xp ); 1428 rpc_desc_t * desc = GET_PTR( xp ); 1392 1429 1393 1430 // get arguments "parent", "name", and "child_xp" … … 1435 1472 rpc.args[0] = (uint64_t)(intptr_t)inode; 1436 1473 1437 // register RPC request in remote RPC fifo (blocking function)1474 // register RPC request in remote RPC fifo 1438 1475 rpc_send( cxy , &rpc ); 1439 1476 … … 1457 1494 1458 1495 // get client cluster identifier and pointer on RPC descriptor 1459 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1460 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1496 cxy_t client_cxy = GET_CXY( xp ); 1497 rpc_desc_t * desc = GET_PTR( xp ); 1461 1498 1462 1499 // get arguments "parent", "name", and "child_xp" … … 1529 1566 1530 1567 // get client cluster identifier and pointer on RPC descriptor 1531 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1532 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1568 cxy_t client_cxy = GET_CXY( xp ); 1569 rpc_desc_t * desc = GET_PTR( xp ); 1533 1570 1534 1571 // get input arguments … … 1576 1613 rpc.args[1] = (uint64_t)vaddr; 1577 1614 1578 // register RPC request in remote RPC fifo (blocking function)1615 // register RPC request in remote RPC fifo 1579 1616 rpc_send( cxy , &rpc ); 1580 1617 … … 1602 1639 1603 1640 // get client cluster identifier and pointer on RPC descriptor 1604 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1605 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1641 cxy_t client_cxy = GET_CXY( xp ); 1642 rpc_desc_t * desc = GET_PTR( xp ); 1606 1643 1607 1644 // get input argument from client RPC descriptor … … 1653 1690 rpc.args[2] = (uint64_t)cow; 1654 1691 1655 // register RPC request in remote RPC fifo (blocking function)1692 // register RPC request in remote RPC fifo 1656 1693 rpc_send( cxy , &rpc ); 1657 1694 … … 1681 1718 1682 1719 // get client cluster identifier and pointer on RPC descriptor 1683 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1684 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1720 cxy_t client_cxy = GET_CXY( xp ); 1721 rpc_desc_t * desc = GET_PTR( xp ); 1685 1722 1686 1723 // get input argument "process" & "vpn" from client RPC descriptor … … 1726 1763 rpc.args[0] = (uint64_t)kmem_type; 1727 1764 1728 // register RPC request in remote RPC fifo (blocking function)1765 // register RPC request in remote RPC fifo 1729 1766 rpc_send( cxy , &rpc ); 1730 1767 … … 1745 1782 1746 1783 // get client cluster identifier and pointer on RPC descriptor 1747 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1748 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1784 cxy_t client_cxy = GET_CXY( xp ); 1785 rpc_desc_t * desc = GET_PTR( xp ); 1749 1786 1750 1787 // get input argument "kmem_type" from client RPC descriptor … … 1791 1828 rpc.args[1] = (uint64_t)kmem_type; 1792 1829 1793 // register RPC request in remote RPC fifo (blocking function)1830 // register RPC request in remote RPC fifo 1794 1831 rpc_send( cxy , &rpc ); 1795 1832 … … 1807 1844 1808 1845 // get client cluster identifier and pointer on RPC descriptor 1809 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1810 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1846 cxy_t client_cxy = GET_CXY( xp ); 1847 rpc_desc_t * desc = GET_PTR( xp ); 1811 1848 1812 1849 // get input arguments "buf" and "kmem_type" from client RPC descriptor … … 1859 1896 rpc.args[5] = (uint64_t)size; 1860 1897 1861 // register RPC request in remote RPC fifo (blocking function)1898 // register RPC request in remote RPC fifo 1862 1899 rpc_send( cxy , &rpc ); 1863 1900 … … 1887 1924 1888 1925 // get client cluster identifier and pointer on RPC descriptor 1889 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1890 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1926 cxy_t client_cxy = GET_CXY( xp ); 1927 rpc_desc_t * desc = GET_PTR( xp ); 1891 1928 1892 1929 // get arguments from client RPC descriptor … … 1953 1990 rpc.args[1] = (uint64_t)index; 1954 1991 1955 // register RPC request in remote RPC fifo (blocking function)1992 // register RPC request in remote RPC fifo 1956 1993 rpc_send( cxy , &rpc ); 1957 1994 … … 1972 2009 1973 2010 // get client cluster identifier and pointer on RPC descriptor 1974 cxy_t cxy = (cxy_t)GET_CXY( xp );1975 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );2011 cxy_t cxy = GET_CXY( xp ); 2012 rpc_desc_t * desc = GET_PTR( xp ); 1976 2013 1977 2014 // get input arguments from client RPC descriptor … … 2028 2065 rpc.args[7] = (uint64_t)vseg_cxy; 2029 2066 2030 // register RPC request in remote RPC fifo (blocking function)2067 // register RPC request in remote RPC fifo 2031 2068 rpc_send( cxy , &rpc ); 2032 2069 … … 2047 2084 2048 2085 // get client cluster identifier and pointer on RPC descriptor 2049 cxy_t cxy = (cxy_t)GET_CXY( xp );2050 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );2086 cxy_t cxy = GET_CXY( xp ); 2087 rpc_desc_t * desc = GET_PTR( xp ); 2051 2088 2052 2089 // get input arguments from client RPC descriptor … … 2101 2138 rpc.args[0] = (uint64_t)lid; 2102 2139 2103 // register RPC request in remote RPC fifo (blocking function)2140 // register RPC request in remote RPC fifo 2104 2141 rpc_send( cxy , &rpc ); 2105 2142 … … 2117 2154 2118 2155 // get client cluster identifier and pointer on RPC descriptor 2119 cxy_t cxy = (cxy_t)GET_CXY( xp );2120 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );2156 cxy_t cxy = GET_CXY( xp ); 2157 rpc_desc_t * desc = GET_PTR( xp ); 2121 2158 2122 2159 // get input arguments from client RPC descriptor … … 2154 2191 rpc.args[0] = (uint64_t)(intptr_t)process; 2155 2192 2156 // register RPC request in remote RPC fifo (blocking function)2193 // register RPC request in remote RPC fifo 2157 2194 rpc_send( cxy , &rpc ); 2158 2195 … … 2172 2209 2173 2210 // get client cluster identifier and pointer on RPC descriptor 2174 cxy_t cxy = (cxy_t)GET_CXY( xp );2175 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );2211 cxy_t cxy = GET_CXY( xp ); 2212 rpc_desc_t * desc = GET_PTR( xp ); 2176 2213 2177 2214 // get input arguments from client RPC descriptor … … 2211 2248 rpc.args[1] = (uint64_t)detailed; 2212 2249 2213 // register RPC request in remote RPC fifo (blocking function)2250 // register RPC request in remote RPC fifo 2214 2251 rpc_send( cxy , &rpc ); 2215 2252 … … 2230 2267 2231 2268 // get client cluster identifier and pointer on RPC descriptor 2232 cxy_t cxy = (cxy_t)GET_CXY( xp );2233 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );2269 cxy_t cxy = GET_CXY( xp ); 2270 rpc_desc_t * desc = GET_PTR( xp ); 2234 2271 2235 2272 // get input arguments from client RPC descriptor -
trunk/kernel/kern/rpc.h
r435 r436 48 48 struct mapper_s; 49 49 50 50 51 /**********************************************************************************/ 51 52 /************** structures for Remote Procedure Calls ****************************/ … … 67 68 RPC_THREAD_USER_CREATE = 6, 68 69 RPC_THREAD_KERNEL_CREATE = 7, 69 RPC_ THREAD_KILL= 8,70 RPC_UNDEFINED_8 = 8, 70 71 RPC_PROCESS_SIGACTION = 9, 71 72 … … 288 289 289 290 /*********************************************************************************** 290 * [8] The RPC_THREAD_KILL ask a target cluster to kill a given thread descriptor. 291 * It is called by the sys_thread_cancel() function for a remote thread. 292 *********************************************************************************** 293 * @ cxy : server cluster identifier. 294 * @ thread : [in] local pointer on target process descriptor in server. 295 **********************************************************************************/ 296 void rpc_thread_kill_client( cxy_t cxy, 297 struct thread_s * thread ); 298 299 void rpc_thread_kill_server( xptr_t xp ); 300 301 /*********************************************************************************** 302 * [9] The RPC_PROCESS_SIGACTION allows the owner cluster to request any other 303 * cluster to execute a given sigaction (BLOCK / UNBLOCK / DELETE) for all 304 * threads of a given process. 291 * [8] undefined slot 292 **********************************************************************************/ 293 294 /*********************************************************************************** 295 * [9] The RPC_PROCESS_SIGACTION allows a thread running in any cluster 296 * to request a cluster identified by the <cxy> argument (local or remote) 297 * to execute a given sigaction for a given cluster. The <action_type> and 298 * the <pid> arguments are defined in the shared RPC descriptor, that must be 299 * initialised by the client thread. 305 300 * 306 301 * WARNING : It is implemented as a NON BLOCKING multicast RPC, that can be sent 307 * in parallel to all process copies. The rpc descriptor is allocated in the client 308 * thread stack by the process_sigaction() function. The various server threads 309 * must decrement the responses counter defined in the rsp descriptor, and the last 310 * server thread unblock the client thread that blocked (after sending all RPC 311 * requests) in the process_sigaction() function. 312 * - The first RPC argument is the sigaction type (BLOCK / UNBLOCK / DELETE). 313 * - The second RPC argument is the local pointer on target process. 314 *********************************************************************************** 315 * @ cxy : server cluster identifier. 316 * @ rpc_ptr : [in] local pointer on rpc descriptor in client cluster. 317 **********************************************************************************/ 318 void rpc_process_sigaction_client( cxy_t cxy, 319 rpc_desc_t * rpc_ptr ); 302 * in parallel to all process copies. The various RPC server threads atomically 303 * decrement the <response> field in the shared RPC descriptor. 304 * The last server thread unblock the client thread that blocked (after sending 305 * all RPC requests) in the process_sigaction() function. 306 *********************************************************************************** 307 * @ cxy : server cluster identifier. 308 * @ rpc : pointer on ishared RPC descriptor initialized by the client thread. 309 **********************************************************************************/ 310 void rpc_process_sigaction_client( cxy_t cxy, 311 struct rpc_desc_s * rpc ); 320 312 321 313 void rpc_process_sigaction_server( xptr_t xp ); -
trunk/kernel/kern/scheduler.c
r435 r436 286 286 next = sched_select( sched ); 287 287 288 // check next thread kernel_stack overflow 289 assert( (next->signature == THREAD_SIGNATURE), 290 __FUNCTION__ , "kernel stack overflow for thread %x\n", next ); 291 288 292 // check next thread attached to same core as the calling thread 289 assert( (next->core == current->core), __FUNCTION__ ,290 "next core != current core\n");293 assert( (next->core == current->core), 294 __FUNCTION__ , "next core %x != current core %x\n", next->core, current->core ); 291 295 292 296 // check next thread not blocked when type != IDLE … … 327 331 { 328 332 329 #if ( CONFIG_DEBUG_SCHED_YIELD & 0x1)333 #if (CONFIG_DEBUG_SCHED_YIELD & 1) 330 334 uint32_t cycle = (uint32_t)hal_get_cycles(); 331 335 if( CONFIG_DEBUG_SCHED_YIELD < cycle ) … … 354 358 uint32_t save_sr; 355 359 356 if( lid >= LOCAL_CLUSTER->cores_nr ) 357 { 358 printk("\n[ERROR] in %s : illegal local index %d in cluster %x\n", 359 __FUNCTION__ , lid , local_cxy ); 360 return; 361 } 360 assert( (lid < LOCAL_CLUSTER->cores_nr), __FUNCTION__, "illegal core index %d\n", lid); 362 361 363 362 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; -
trunk/kernel/kern/scheduler.h
r433 r436 49 49 struct thread_s * idle; /*! pointer on idle thread */ 50 50 struct thread_s * current; /*! pointer on current running thread */ 51 bool_t req_ack_pending; /*! signal_handller must be called when true*/51 volatile bool_t req_ack_pending; /*! sequencialize ack requests when true */ 52 52 } 53 53 scheduler_t; -
trunk/kernel/kern/thread.c
r433 r436 799 799 } // end thread_check_sched() 800 800 801 ///////////////////////////////////// 802 void thread_block( thread_t * thread, 803 uint32_t cause ) 804 { 801 ////////////////////////////////////// 802 void thread_block( xptr_t thread_xp, 803 uint32_t cause ) 804 { 805 // get thread cluster and local pointer 806 cxy_t cxy = GET_CXY( thread_xp ); 807 thread_t * ptr = GET_PTR( thread_xp ); 808 805 809 // set blocking cause 806 hal_ atomic_or( &thread->blocked, cause );810 hal_remote_atomic_or( XPTR( cxy , &ptr->blocked ) , cause ); 807 811 hal_fence(); 808 812 … … 810 814 uint32_t cycle = (uint32_t)hal_get_cycles(); 811 815 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 812 printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / state %x / cycle %d\n", 813 __FUNCTION__ , CURRENT_THREAD , thread , cause , thread->blocked , cycle ); 816 printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / cycle %d\n", 817 __FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle ); 818 #endif 819 820 #if (CONFIG_DEBUG_THREAD_BLOCK & 1) 821 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 822 sched_display( ptr->core->lid ); 814 823 #endif 815 824 … … 831 840 uint32_t cycle = (uint32_t)hal_get_cycles(); 832 841 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 833 printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / state %x / cycle %d\n", 834 __FUNCTION__ , CURRENT_THREAD , ptr , cause , ptr->blocked , cycle ); 842 printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / cycle %d\n", 843 __FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle ); 844 #endif 845 846 #if (CONFIG_DEBUG_THREAD_BLOCK & 1) 847 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 848 sched_display( ptr->core->lid ); 835 849 #endif 836 850 … … 840 854 } // end thread_unblock() 841 855 842 ///////////////////////////////////// 843 void thread_kill( thread_t * target ) 844 { 845 volatile uint32_t rsp_count = 1; // responses counter 846 847 thread_t * killer = CURRENT_THREAD; 856 //////////////////////////////////// 857 void thread_kill( xptr_t target_xp, 858 bool_t is_exit, 859 bool_t is_forced ) 860 { 861 reg_t save_sr; // for critical section 862 bool_t attached; // target thread in attached mode 863 bool_t join_done; // joining thread arrived first 864 xptr_t killer_xp; // extended pointer on killer thread (this) 865 thread_t * killer_ptr; // pointer on killer thread (this) 866 cxy_t target_cxy; // target thread cluster 867 thread_t * target_ptr; // pointer on target thread 868 xptr_t joining_xp; // extended pointer on joining thread 869 thread_t * joining_ptr; // pointer on joining thread 870 cxy_t joining_cxy; // joining thread cluster 871 pid_t target_pid; // target process PID 872 cxy_t owner_cxy; // target process owner cluster 873 trdid_t target_trdid; // target thread identifier 874 ltid_t target_ltid; // target thread local index 875 xptr_t process_state_xp; // extended pointer on <term_state> in process 876 877 xptr_t target_flags_xp; // extended pointer on target thread <flags> 878 xptr_t target_join_lock_xp; // extended pointer on target thread <join_lock> 879 xptr_t target_join_xp_xp; // extended pointer on target thread <join_xp> 880 xptr_t target_process_xp; // extended pointer on target thread <process> 881 882 process_t * target_process; // pointer on target thread process 883 884 // get target thread cluster and pointer 885 target_cxy = GET_CXY( target_xp ); 886 target_ptr = GET_PTR( target_xp ); 887 888 // get killer thread pointers 889 killer_ptr = CURRENT_THREAD; 890 killer_xp = XPTR( local_cxy , killer_ptr ); 848 891 849 892 #if CONFIG_DEBUG_THREAD_KILL … … 851 894 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 852 895 printk("\n[DBG] %s : thread %x enter for target thread %x / cycle %d\n", 853 __FUNCTION__, killer, target, cycle ); 854 #endif 855 856 // set the global blocked bit in target thread descriptor. 857 thread_block( target , THREAD_BLOCKED_GLOBAL ); 858 859 // request target scheduler to deschedule the target thread 860 // when killer thread is not running on same core as target thread 861 if( killer->core->lid != target->core->lid ) 862 { 863 // set signal in target thread descriptor and in target scheduler 864 thread_set_req_ack( target , (void *)(&rsp_count) ); 865 866 // send an IPI to the target thread core. 867 dev_pic_send_ipi( local_cxy , target->core->lid ); 868 869 // poll the response 870 while( 1 ) 896 __FUNCTION__, killer_ptr, target_ptr, cycle ); 897 #endif 898 899 // block the target thread 900 thread_block( target_xp , THREAD_BLOCKED_GLOBAL ); 901 902 // get target thread attached mode 903 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 904 attached = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0); 905 906 // synchronize with the joining thread 907 // if the target thread is attached && not forced 908 909 if( attached && (is_forced == false) ) 910 { 911 // build extended pointers on target thread join fields 912 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 913 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 914 915 // enter critical section 916 hal_disable_irq( &save_sr ); 917 918 // take the join_lock in target thread descriptor 919 remote_spinlock_lock( target_join_lock_xp ); 920 921 // get join_done from target thread descriptor 922 join_done = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_JOIN_DONE) != 0); 923 924 if( join_done ) // joining thread arrived first 871 925 { 872 // exit when response received from scheduler 873 if( rsp_count == 0 ) break; 874 875 // deschedule without blocking 876 hal_fixed_delay( 1000 ); 926 // get extended pointer on joining thread 927 joining_xp = (xptr_t)hal_remote_lwd( target_join_xp_xp ); 928 joining_ptr = GET_PTR( joining_xp ); 929 joining_cxy = GET_CXY( joining_xp ); 930 931 // reset the join_done flag in target thread 932 hal_remote_atomic_and( target_flags_xp , ~THREAD_FLAG_JOIN_DONE ); 933 934 // unblock the joining thread 935 thread_unblock( joining_xp , THREAD_BLOCKED_JOIN ); 936 937 // release the join_lock in target thread descriptor 938 remote_spinlock_unlock( target_join_lock_xp ); 939 940 // restore IRQs 941 hal_restore_irq( save_sr ); 877 942 } 878 } 879 880 // set REQ_DELETE flag 881 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE ); 943 else // this thread arrived first 944 { 945 // set the kill_done flag in target thread 946 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_KILL_DONE ); 947 948 // block this thread on BLOCKED_JOIN 949 thread_block( killer_xp , THREAD_BLOCKED_JOIN ); 950 951 // set extended pointer on killer thread in target thread 952 hal_remote_swd( target_join_xp_xp , killer_xp ); 953 954 // release the join_lock in target thread descriptor 955 remote_spinlock_unlock( target_join_lock_xp ); 956 957 // deschedule 958 sched_yield( "killer thread wait joining thread" ); 959 960 // restore IRQs 961 hal_restore_irq( save_sr ); 962 } 963 } // end if attached 964 965 // - if the target thread is the main thread 966 // => synchronize with the parent process main thread 967 // - if the target thread is not the main thread 968 // => simply mark the target thread for delete 969 970 // get pointer on target thread process 971 target_process_xp = XPTR( target_cxy , &target_ptr->process ); 972 target_process = (process_t *)hal_remote_lpt( target_process_xp ); 973 974 // get target process owner cluster 975 target_pid = hal_remote_lw( XPTR( target_cxy , &target_process->pid ) ); 976 owner_cxy = CXY_FROM_PID( target_pid ); 977 978 // get target thread local index 979 target_trdid = hal_remote_lw( XPTR( target_cxy , &target_ptr->trdid ) ); 980 target_ltid = LTID_FROM_TRDID( target_trdid ); 981 982 if( (owner_cxy == target_cxy) && (target_ltid == 0) ) // main thread 983 { 984 // get extended pointer on term_state in target process owner cluster 985 process_state_xp = XPTR( owner_cxy , &target_process->term_state ); 986 987 // set termination info in target process owner 988 if( is_exit ) hal_remote_atomic_or( process_state_xp , PROCESS_TERM_EXIT ); 989 else hal_remote_atomic_or( process_state_xp , PROCESS_TERM_KILL ); 882 990 883 991 #if CONFIG_DEBUG_THREAD_KILL 884 992 cycle = (uint32_t)hal_get_cycles; 885 993 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 886 printk("\n[DBG] %s : thread %x exit for target thread %x / cycle %d\n", 887 __FUNCTION__, killer, target, cycle ); 888 #endif 994 printk("\n[DBG] %s : thread %x exit for thread %x / main thread / cycle %d\n", 995 __FUNCTION__, killer_ptr, target_ptr, cycle ); 996 #endif 997 998 } 999 else // main thread 1000 { 1001 // set the REQ_DELETE flag in target thread descriptor 1002 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_REQ_DELETE ); 1003 1004 #if CONFIG_DEBUG_THREAD_KILL 1005 cycle = (uint32_t)hal_get_cycles; 1006 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 1007 printk("\n[DBG] %s : thread %x exit for thread %x / not the main thread / cycle %d\n", 1008 __FUNCTION__, killer_ptr, target_ptr, cycle ); 1009 #endif 1010 1011 } 889 1012 890 1013 } // end thread_kill() … … 958 1081 target_thread_ltid = LTID_FROM_TRDID( trdid ); 959 1082 1083 // check trdid argument 1084 if( (target_thread_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || 1085 cluster_is_undefined( target_cxy ) ) return XPTR_NULL; 1086 960 1087 // get root of list of process descriptors in target cluster 961 1088 hal_remote_memcpy( XPTR( local_cxy , &root ), … … 987 1114 remote_spinlock_unlock( lock_xp ); 988 1115 989 // check target thread found 990 if( found == false ) 991 { 992 return XPTR_NULL; 993 } 1116 // check PID found 1117 if( found == false ) return XPTR_NULL; 994 1118 995 1119 // get target thread local pointer … … 997 1121 target_thread_ptr = (thread_t *)hal_remote_lpt( xp ); 998 1122 999 if( target_thread_ptr == NULL ) 1000 { 1001 return XPTR_NULL; 1002 } 1123 if( target_thread_ptr == NULL ) return XPTR_NULL; 1003 1124 1004 1125 return XPTR( target_cxy , target_thread_ptr ); -
trunk/kernel/kern/thread.h
r428 r436 70 70 71 71 #define THREAD_FLAG_DETACHED 0x0001 /*! This thread is detached from parent */ 72 #define THREAD_FLAG_JOIN_DONE 0x0002 /*! Parent thread made a join */ 73 #define THREAD_FLAG_SCHED 0x0004 /*! Scheduling required for this thread */ 74 #define THREAD_FLAG_REQ_ACK 0x0008 /*! Acknowledge required from scheduler */ 75 #define THREAD_FLAG_REQ_DELETE 0x0010 /*! Destruction required from scheduler */ 72 #define THREAD_FLAG_JOIN_DONE 0x0002 /*! Parent thread made a join request */ 73 #define THREAD_FLAG_KILL_DONE 0x0004 /*! This thread received a kill request */ 74 #define THREAD_FLAG_SCHED 0x0008 /*! Scheduling required for this thread */ 75 #define THREAD_FLAG_REQ_ACK 0x0010 /*! Acknowledge required from scheduler */ 76 #define THREAD_FLAG_REQ_DELETE 0x0020 /*! Destruction required from scheduler */ 76 77 77 78 /*************************************************************************************** … … 88 89 #define THREAD_BLOCKED_USERSYNC 0x0100 /*! thread wait (cond/mutex/barrier) */ 89 90 #define THREAD_BLOCKED_RPC 0x0200 /*! thread wait RPC completion */ 90 #define THREAD_BLOCKED_ DEV_ISR0x0400 /*! thread DEV wait ISR */91 #define THREAD_BLOCKED_ISR 0x0400 /*! thread DEV wait ISR */ 91 92 #define THREAD_BLOCKED_WAIT 0x0800 /*! thread parent wait child termination */ 92 93 … … 153 154 154 155 remote_spinlock_t join_lock; /*! lock protecting the join/exit */ 155 void * join_value; /*! exit_value used in case of join */ 156 xptr_t join_xp; /*! extended pointer on joining thread */ 156 xptr_t join_xp; /*! joining/killer thread extended pointer */ 157 157 158 158 uint32_t * ack_rsp_count; /*! pointer on acknowledge response counter */ … … 386 386 387 387 /*************************************************************************************** 388 * This function is called to handle the "pthread_cancel" system call. 389 * It allows a killer thread to kill one single target thread. 390 * The killer thread must be running in the same cluster as the target thread. 391 * If not, the client thread must use the RPC_THREAD_KILL. 392 * - When the killer thread is running on the same core as the target thread, 393 * this function simply set the BLOCKED_ GLOBAL bit and the REQ_DELETE flag 394 * in the target thread descriptor and return. 395 * - When the killer thread is running on a different core than the target thread, 396 * the killer set the BLOCKED_GLOBAL bit and the REQ_ACK flag in target thread, 397 * to ask the scheduler to confirm that the target is blocked and not running. 398 * Then, it set the REQ_DELETE flag in the target thread and return. 399 * In both cases, the actual target thread destruction is done by the scheduler 400 * at the next scheduling point. 401 *************************************************************************************** 402 * @ thread : local pointer on the target thread. 403 **************************************************************************************/ 404 void thread_kill( thread_t * thread ); 405 406 /*************************************************************************************** 407 * This function registers a blocking cause in the target thread "blocked" bit vector. 408 * Warning : this function does not deschedule the calling thread, and the descheduling 388 * This function is called to handle the four pthread_cancel(), pthread_exit(), 389 * kill() and exit() system calls. It kills a "target" thread identified by the 390 * <thread_xp> argument. The "killer" thread can be the "target" thread, when the 391 * <is_exit> argument is true. The "killer" thread can run in any cluster, 392 * as it uses remote accesses. 393 * If the "target" thread is running in "attached" mode, and the <is_forced> argument 394 * is false, this function implements the required sychronisation with the joining 395 * thread, blocking the "killer" thread until the pthread_join() syscall is executed. 396 * To delete the target thread, this function sets the THREAD_FLAG_REQ_DELETE bit 397 * and the THREAD BLOCKED_GLOBAL bit in the target thread, and the actual destruction 398 * is asynchronously done by the scheduler at the next scheduling point. 399 *************************************************************************************** 400 * @ thread_xp : extended pointer on the target thread. 401 * @ is_exit : the killer thread is the target thread itself. 402 * @ is_forced : the killing does not depends on the attached mode. 403 **************************************************************************************/ 404 void thread_kill( xptr_t thread_xp, 405 bool_t is_exit, 406 bool_t is_forced ); 407 408 /*************************************************************************************** 409 * This function registers a blocking cause defined by the <cause> argument 410 * in a remote thread descriptor identified by the <thread_xp> argument. 411 * We need an extended pointer, because this function can be called by another thread 412 * than the target thread, executing the sys_kill() function. 413 * WARNING : this function does not deschedule the target thread, and the descheduling 409 414 * must be explicitely forced by a sched_yield(). 410 415 *************************************************************************************** 411 * @ thread : local pointer on targetthread descriptor.412 * @ cause : mask defining the cause (one hot).413 **************************************************************************************/ 414 void thread_block( thread_t * thread,415 uint32_t 416 417 /*************************************************************************************** 418 * This function resets the bit identified by the cause argument in the "blocked"419 * bit vector of a remote thread descriptor, using an atomic access.416 * @ thread_xp : extended pointer on remote thread descriptor. 417 * @ cause : mask defining the cause (one hot). 418 **************************************************************************************/ 419 void thread_block( xptr_t thread_xp, 420 uint32_t cause ); 421 422 /*************************************************************************************** 423 * This function resets the bit identified by the <cause> argument in a remote 424 * thread descriptor identified by the <thread_xp> argument. 420 425 * We need an extended pointer, because the client thread of an I/O operation on a 421 426 * given device is not in the same cluster as the associated device descriptor. 422 * W arning: this function does not reschedule the remote thread.427 * WARNING : this function does not reschedule the remote thread. 423 428 * The scheduling can be forced by sending an IPI to the core running the remote thread. 424 429 *************************************************************************************** 425 * @ thread : extended pointer onthe remote thread.426 * @ cause : mask defining the cause (one hot).430 * @ thread_xp : extended pointer the remote thread. 431 * @ cause : mask defining the cause (one hot). 427 432 * @ return non zero if the bit-vector was actually modified / return 0 otherwise 428 433 **************************************************************************************/ 429 uint32_t thread_unblock( xptr_t thread ,434 uint32_t thread_unblock( xptr_t thread_xp, 430 435 uint32_t cause ); 431 436 … … 449 454 450 455 /*************************************************************************************** 451 * This function handles all pending signals for the thread identified by the <thread>452 * argument. It is called each time the core exits the kernel, after handling an453 * interrupt, exception or syscall.454 * TODO This function is not implemented.455 ***************************************************************************************456 * @ thread : local pointer on target thread.457 **************************************************************************************/458 void thread_signals_handle( thread_t * thread );459 460 /***************************************************************************************461 456 * This function returns the extended pointer on a thread descriptor identified 462 457 * by its thread identifier, and process identifier. -
trunk/kernel/libk/remote_barrier.c
r408 r436 273 273 274 274 // block & deschedule the calling thread 275 thread_block( thread_ptr, THREAD_BLOCKED_USERSYNC );275 thread_block( XPTR( local_cxy , thread_ptr ) , THREAD_BLOCKED_USERSYNC ); 276 276 sched_yield("blocked on barrier"); 277 277 -
trunk/kernel/libk/remote_condvar.c
r408 r436 188 188 189 189 // block the calling thread 190 thread_block( CURRENT_THREAD, THREAD_BLOCKED_USERSYNC );190 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_USERSYNC ); 191 191 sched_yield("blocked on condvar"); 192 192 -
trunk/kernel/libk/remote_mutex.c
r408 r436 207 207 208 208 // block & deschedule the calling thread 209 thread_block( thread_ptr, THREAD_BLOCKED_USERSYNC );209 thread_block( XPTR( local_cxy , thread_ptr ) , THREAD_BLOCKED_USERSYNC ); 210 210 sched_yield("blocked on mutex"); 211 211 -
trunk/kernel/libk/remote_rwlock.c
r433 r436 2 2 * remote_rwlock.c - kernel remote rwlock implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017 )4 * Authors Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 41 41 hal_remote_sw ( XPTR( lock_cxy , &lock_ptr->count ) , 0 ); 42 42 43 #if CONFIG_DEBUG_ LOCKS44 45 43 #if CONFIG_DEBUG_REMOTE_RWLOCKS 44 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , XPTR_NULL ); 45 xlist_entry_init( XPTR( lock_cxy , &lock_ptr->list ) ); 46 46 #endif 47 47 … … 86 86 thread_ptr->remote_locks++; 87 87 88 #if CONFIG_DEBUG_ LOCKS89 90 88 #if CONFIG_DEBUG_REMOTE_RWLOCKS 89 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ) , 90 XPTR( lock_cxy , &lock_ptr->list ) ); 91 91 #endif 92 92 … … 126 126 thread_ptr->remote_locks--; 127 127 128 #if CONFIG_DEBUG_ LOCKS129 128 #if CONFIG_DEBUG_REMOTE_RWLOCKS 129 xlist_unlink( XPTR( lock_cxy , &lock_ptr->list ) ); 130 130 #endif 131 131 … … 176 176 } 177 177 178 #if CONFIG_DEBUG_ LOCKS179 180 181 182 178 #if CONFIG_DEBUG_REMOTE_RWLOCKS 179 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , 180 XPTR( local_cxy , thread_ptr ) ); 181 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ) , 182 XPTR( lock_cxy , &lock_ptr->list ) ); 183 183 #endif 184 184 … … 210 210 211 211 #if CONFIG_LOCKS_OWNER 212 213 212 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , XPTR_NULL ); 213 xlist_unlink( XPTR( lock_cxy , &lock_ptr->list ) ); 214 214 #endif 215 215 -
trunk/kernel/libk/remote_rwlock.h
r409 r436 2 2 * remote_rwlock.h - kernel remote_rwlock definition. 3 3 * 4 * Authors Alain Greiner (2016 )4 * Authors Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 48 48 uint32_t count; /*! current number of reader threads */ 49 49 50 #if CONFIG_ LOCKS_DEBUG50 #if CONFIG_DEBUG_REMOTE_RWLOCKS 51 51 xptr_t owner; /*! extended pointer on writer thread */ 52 52 xlist_entry_t list; /*! member of list of remote locks taken by owner */ -
trunk/kernel/libk/remote_sem.c
r408 r436 218 218 219 219 // block and deschedule 220 thread_block( this, THREAD_BLOCKED_SEM );220 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_SEM ); 221 221 sched_yield("blocked on semaphore"); 222 222 } -
trunk/kernel/libk/remote_spinlock.c
r433 r436 2 2 * remote_spinlock.c - kernel remote spinlock implementation. 3 3 * 4 * Authors Mohamed Karaoui (2015) 5 * Alain Greiner (2016) 4 * Authors Alain Greiner (2016,2017,2018) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 39 38 hal_remote_sw ( XPTR( cxy , &ptr->taken ) , 0 ); 40 39 41 #if CONFIG_DEBUG_ LOCKS42 43 40 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 41 hal_remote_swd( XPTR( cxy , &ptr->owner ) , XPTR_NULL ); 42 xlist_entry_init( XPTR( cxy , &ptr->list ) ); 44 43 #endif 45 44 … … 76 75 thread_ptr->remote_locks++; 77 76 78 #if CONFIG_DEBUG_ LOCKS79 80 81 82 77 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 78 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , 79 XPTR( local_cxy , thread_ptr) ); 80 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ) , 81 XPTR( lock_cxy , &lock_ptr->list ) ); 83 82 #endif 84 83 … … 121 120 thread_ptr->remote_locks++; 122 121 123 #if CONFIG_DEBUG_ LOCKS124 125 126 127 122 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 123 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , 124 XPTR( local_cxy , thread_ptr) ); 125 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ) , 126 XPTR( lock_cxy , &lock_ptr->list ) ); 128 127 #endif 129 128 … … 144 143 thread_t * thread_ptr = CURRENT_THREAD; 145 144 146 #if CONFIG_DEBUG_ LOCKS147 148 145 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 146 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , XPTR_NULL ); 147 xlist_unlink( XPTR( lock_cxy , &lock_ptr->list ) ); 149 148 #endif 150 149 … … 197 196 thread_ptr->remote_locks++; 198 197 199 #if CONFIG_DEBUG_LOCKS 200 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , 201 XPTR( local_cxy , thread_ptr) ); 202 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ) , 203 XPTR( lock_cxy , &lock_ptr->list ) ); 198 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 199 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ), 200 XPTR( local_cxy , thread_ptr) ); 201 xlist_add_first( XPTR( local_cxy , &thread_ptr->xlocks_root ), 202 XPTR( lock_cxy , &lock_ptr->list ) ); 203 204 // if( (uint32_t)lock_ptr == 0x66788 ) 205 // printk("\n@@@ %s : thread %x takes remote_spinlock %x\n", 206 //__FUNCTION__, thread_ptr, lock_ptr ); 207 204 208 #endif 205 209 … … 218 222 thread_t * thread_ptr = CURRENT_THREAD; 219 223 220 #if CONFIG_DEBUG_LOCKS 221 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , XPTR_NULL ); 222 xlist_unlink( XPTR( lock_cxy , &lock_ptr->list ) ); 224 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 225 hal_remote_swd( XPTR( lock_cxy , &lock_ptr->owner ) , XPTR_NULL ); 226 xlist_unlink( XPTR( lock_cxy , &lock_ptr->list ) ); 227 228 // if( (uint32_t)lock_ptr == 0x66788 ) 229 // printk("\n@@@ %s : thread %x releases remote_spinlock %x\n", 230 // __FUNCTION__, thread_ptr, lock_ptr ); 231 223 232 #endif 224 233 -
trunk/kernel/libk/remote_spinlock.h
r433 r436 2 2 * remote_spinlock.h - kernel remote spinlock definition. 3 3 * 4 * Authors Mohamed Karaoui (2016) 5 * Alain Greiner (2016) 4 * Author Alain Greiner (2016,2017,2018) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 42 41 volatile uint32_t taken; /*! free if 0 / taken if non zero */ 43 42 44 #if CONFIG_ LOCKS_DEBUG43 #if CONFIG_DEBUG_REMOTE_SPINLOCKS 45 44 xptr_t owner; /*! extended pointer on the owner thread */ 46 45 xlist_entry_t list; /*! list of all remote_lock taken by owner */ -
trunk/kernel/libk/rwlock.c
r433 r436 2 2 * rwlock.c - kernel read/write lock synchronization. 3 3 * 4 * Author Alain Greiner (2016 }4 * Author Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 38 38 lock->count = 0; 39 39 40 #if CONFIG_DEBUG_ LOCKS41 42 40 #if CONFIG_DEBUG_RWLOCKS 41 lock->owner = NULL; 42 list_entry_init( &lock->list ); 43 43 #endif 44 44 … … 70 70 this->local_locks++; 71 71 72 #if CONFIG_DEBUG_ LOCKS73 72 #if CONFIG_DEBUG_RWLOCKS 73 list_add_first( &this->locks_root , &lock->list ); 74 74 #endif 75 75 … … 98 98 this->local_locks--; 99 99 100 #if CONFIG_DEBUG_ LOCKS101 100 #if CONFIG_DEBUG_RWLOCKS 101 list_unlink( &lock->list ); 102 102 #endif 103 103 … … 138 138 this->local_locks++; 139 139 140 #if CONFIG_DEBUG_ LOCKS141 142 140 #if CONFIG_DEBUG_RWLOCKS 141 lock->owner = this; 142 list_add_first( &this->locks_root , &lock->list ); 143 143 #endif 144 144 … … 157 157 hal_disable_irq( &mode ); 158 158 159 #if CONFIG_DEBUG_ LOCKS160 161 159 #if CONFIG_DEBUG_RWLOCKS 160 lock->owner = NULL; 161 list_unlink( &lock->list ); 162 162 #endif 163 163 -
trunk/kernel/libk/rwlock.h
r423 r436 2 2 * rwlock.h - kernel read/write lock definition. 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 59 59 uint32_t count; /*! number of simultaneous readers threads */ 60 60 61 #if CONFIG_ LOCKS_DEBUG61 #if CONFIG_DEBUG_RWLOCKS 62 62 struct thread_s * owner; /*! pointer on curent writer thread */ 63 63 list_entry_t list; /*! member of list of locks taken by owner */ -
trunk/kernel/libk/spinlock.c
r433 r436 38 38 lock->taken = 0; 39 39 40 #if CONFIG_DEBUG_ LOCKS41 42 40 #if CONFIG_DEBUG_SPINLOCKS 41 lock->owner = NULL; 42 list_entry_init( &lock->list ); 43 43 #endif 44 44 … … 71 71 this->local_locks++; 72 72 73 #if CONFIG_DEBUG_ LOCKS74 75 73 #if CONFIG_DEBUG_SPINLOCKS 74 lock->owner = this; 75 list_add_first( &this->locks_root , &lock->list ); 76 76 #endif 77 77 … … 86 86 thread_t * this = CURRENT_THREAD;; 87 87 88 #if CONFIG_DEBUG_ LOCKS89 90 88 #if CONFIG_DEBUG_SPINLOCKS 89 lock->owner = NULL; 90 list_unlink( &lock->list ); 91 91 #endif 92 92 … … 132 132 this->local_locks++; 133 133 134 #if CONFIG_DEBUG_ LOCKS135 136 134 #if CONFIG_DEBUG_SPINLOCKS 135 lock->owner = this; 136 list_add_first( &this->locks_root , &lock->list ); 137 137 #endif 138 138 … … 162 162 this->local_locks++; 163 163 164 #if CONFIG_DEBUG_ LOCKS165 166 164 #if CONFIG_DEBUG_SPINLOCKS 165 lock->owner = this; 166 list_add_first( &this->locks_root , &lock->list ); 167 167 #endif 168 168 … … 177 177 thread_t * this = CURRENT_THREAD; 178 178 179 #if CONFIG_DEBUG_ LOCKS180 181 179 #if CONFIG_DEBUG_SPINLOCKS 180 lock->owner = NULL; 181 list_unlink( &lock->list ); 182 182 #endif 183 183 -
trunk/kernel/libk/spinlock.h
r409 r436 2 2 * spinlock.h: kernel spinlock definition 3 3 * 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016) 4 * Authors Alain Greiner (2016,2017,2018) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 63 62 uint32_t taken; /*! state : free if zero / taken if non zero */ 64 63 65 #if CONFIG_ LOCKS_DEBUG64 #if CONFIG_DEBUG_SPINLOCKS 66 65 struct thread_s * owner; /*! pointer on curent owner thread */ 67 66 list_entry_t list; /*! member of list of locks taken by owner */ -
trunk/kernel/mm/page.c
r433 r436 180 180 181 181 // deschedule the calling thread 182 thread_block( thread, THREAD_BLOCKED_PAGE );182 thread_block( XPTR( local_cxy , thread ) , THREAD_BLOCKED_PAGE ); 183 183 sched_yield("cannot lock a page"); 184 184 } -
trunk/kernel/syscalls/sys_display.c
r435 r436 37 37 reg_t arg1 ) 38 38 { 39 // get thread, process and core40 thread_t * this = CURRENT_THREAD;41 process_t * process = this->process;42 core_t * core = this->core;43 39 44 40 #if CONFIG_DEBUG_SYS_DISPLAY 45 41 uint64_t tm_start; 46 42 uint64_t tm_end; 43 thread_t * this; 44 this = CURRENT_THREAD; 47 45 tm_start = hal_get_cycles(); 48 46 if( CONFIG_DEBUG_SYS_DISPLAY < tm_start ) 49 printk("\n[DBG] %s : thread %d enter / process %x / cycle = %d\n",50 __FUNCTION__, this, process->pid, (uint32_t)tm_start );47 printk("\n[DBG] %s : thread %d enter / process %x / type %d / cycle = %d\n", 48 __FUNCTION__, this, this->process->pid, type, (uint32_t)tm_start ); 51 49 #endif 52 50 … … 80 78 81 79 // print message on TXT0 kernel terminal 82 printk("\n[USER] thread %x / process %x / core[%x,%d] / cycle %d\n %s", 83 this->trdid , process->pid , local_cxy, core->lid , 84 (uint32_t)hal_get_cycles() , kbuf ); 80 printk("\n[USER] %s / cycle %d\n", kbuf, (uint32_t)hal_get_cycles() ); 85 81 } 86 82 else if( type == DISPLAY_VMM ) … … 191 187 if( CONFIG_DEBUG_SYS_DISPLAY < tm_end ) 192 188 printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n", 193 __FUNCTION__, this, process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end );189 __FUNCTION__, this, this->process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end ); 194 190 #endif 195 191 -
trunk/kernel/syscalls/sys_exit.c
r435 r436 41 41 process_t * process = this->process; 42 42 pid_t pid = process->pid; 43 trdid_t trdid = this->trdid; 43 44 44 45 #if CONFIG_DEBUG_SYS_EXIT … … 55 56 56 57 // exit must be called by the main thread 57 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID( t his->trdid ) != 0) )58 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ) != 0) ) 58 59 { 59 60 60 61 #if CONFIG_DEBUG_SYSCALLS_ERROR 61 printk("\n[ERROR] %s must be called by thread 0 in process owner cluster\n" 62 " trdid = %x / pid = %x / local_cxy = %x\n", 63 __FUNCTION__, this->trdid, pid, local_cxy ); 62 printk("\n[ERROR] in %s : calling thread %x is not thread 0 in owner cluster %x\n", 63 __FUNCTION__, trdid, owner_cxy ); 64 64 #endif 65 65 this->errno = EINVAL; … … 73 73 process->term_state = status; 74 74 75 // remove TXT ownership from owner process descriptor 76 process_txt_reset_ownership( XPTR( local_cxy , process ) ); 75 #if( CONFIG_DEBUG_SYS_EXIT & 1) 76 printk("\n[DBG] %s : set exit status in process term_state\n", __FUNCTION__); 77 #endif 77 78 78 // block all process threads in all clusters79 process_ sigaction( pid , BLOCK_ALL_THREADS);79 // remove process from TXT list 80 process_txt_detach( XPTR( local_cxy , process ) ); 80 81 81 // mark all process threads in all clusters for delete 82 #if( CONFIG_DEBUG_SYS_EXIT & 1) 83 printk("\n[DBG] %s : removed from TXT list\n", __FUNCTION__); 84 #endif 85 86 // mark for delete all process threads in all clusters (but the main) 82 87 process_sigaction( pid , DELETE_ALL_THREADS ); 88 89 #if( CONFIG_DEBUG_SYS_EXIT & 1) 90 printk("\n[DBG] %s : deleted all other threads than main\n", __FUNCTION__); 91 #endif 83 92 84 93 // restore IRQs 85 94 hal_restore_irq( save_sr ); 86 95 87 // atomically update owner process descriptor term_state 96 // block the main thread itself 97 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL ); 98 99 #if( CONFIG_DEBUG_SYS_EXIT & 1) 100 printk("\n[DBG] %s : blocked the main thread\n", __FUNCTION__); 101 #endif 102 103 // atomically update owner process descriptor term_state to ask 104 // the parent process sys_wait() function to delete this main thread 88 105 hal_remote_atomic_or( XPTR( local_cxy , &process->term_state ) , 89 106 PROCESS_TERM_EXIT ); 107 108 #if( CONFIG_DEBUG_SYS_EXIT & 1) 109 printk("\n[DBG] %s : set EXIT flag in process term_state\n", __FUNCTION__); 110 #endif 111 90 112 hal_fence(); 91 113 … … 97 119 #endif 98 120 121 // main thread deschedule 122 sched_yield( "process exit" ); 123 124 // this code should never be executed 125 assert( false , __FUNCTION__ , "this code should not be executed...\n" ); 99 126 return 0; 100 127 -
trunk/kernel/syscalls/sys_fg.c
r421 r436 45 45 thread_t * this = CURRENT_THREAD; 46 46 47 #if CONFIG_ SYSCALL_DEBUG47 #if CONFIG_DEBUG_SYS_FG 48 48 uint64_t tm_start; 49 49 uint64_t tm_end; 50 50 tm_start = hal_get_cycles(); 51 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle %d\n", 52 __FUNCTION__ , local_cxy , this->core->lid , pid, (uint32_t)tm_start ); 51 if( CONFIG_DEBUG_SYS_FG < tm_start ) 52 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 53 __FUNCTION__ , CURRENT_THREAD , pid, (uint32_t)tm_start ); 53 54 #endif 54 55 … … 58 59 if( process_xp == XPTR_NULL ) 59 60 { 60 syscall_dmsg("\n[ERROR] in %s : process %x not found\n", 61 __FUNCTION__ , pid ); 61 62 #if CONFIG_DEBUG_SYSCALLS_ERROR 63 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid ); 64 #endif 62 65 this->errno = EINVAL; 63 66 return -1; … … 72 75 73 76 // get chdev cluster and local pointer 74 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );77 chdev_ptr = GET_PTR( chdev_xp ); 75 78 chdev_cxy = GET_CXY( chdev_xp ); 76 79 … … 80 83 hal_fence(); 81 84 82 #if CONFIG_ SYSCALL_DEBUG85 #if CONFIG_DEBUG_SYS_FG 83 86 tm_end = hal_get_cycles(); 84 printk("\n[DBG] %s : core[%x,%d] exit / process %x / cost = %d\n", 85 __FUNCTION__ , local_cxy , this->core->lid , pid, (uint32_t)(tm_end - tm_start) ); 87 if( CONFIG_DEBUG_SYS_FG < tm_end ) 88 printk("\n[DBG] %s : thread %x exit / process %x get TXT_%d ownership / cycle %d\n", 89 __FUNCTION__ , CURRENT_THREAD , pid, 90 hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) ) , (uint32_t)tm_end ); 86 91 #endif 87 92 88 93 return 0; 89 94 90 } // end sys_ kill()95 } // end sys_fg() 91 96 -
trunk/kernel/syscalls/sys_get_config.c
r435 r436 87 87 tm_end = hal_get_cycles(); 88 88 if( CONFIG_DEBUG_SYS_GET_CONFIG < tm_end ) 89 printk("\n[DBG] %s : thread %x exit / process %x / cost %d / tycle %d\n",89 printk("\n[DBG] %s : thread %x exit / process %x / cost %d / cycle %d\n", 90 90 __FUNCTION__, this, process->pid, (uint32_t)(tm_end-tm_start), (uint32_t)tm_end ); 91 91 #endif -
trunk/kernel/syscalls/sys_kill.c
r435 r436 37 37 uint32_t sig_id ) 38 38 { 39 uint32_t save_sr; // required to enable IRQs 40 xptr_t owner_xp; // extended pointer on target reference process 41 cxy_t owner_cxy; // target process cluster 42 process_t * owner_ptr; // local pointer on target process 39 xptr_t owner_xp; // extended pointer on target process in owner cluster 40 cxy_t owner_cxy; // target process owner cluster 41 process_t * owner_ptr; // local pointer on target process in owner cluster 43 42 xptr_t parent_xp; // extended pointer on parent process 44 43 cxy_t parent_cxy; // parent process cluster … … 49 48 thread_t * this = CURRENT_THREAD; 50 49 process_t * process = this->process; 50 trdid_t trdid = this->trdid; 51 51 52 52 #if CONFIG_DEBUG_SYS_KILL … … 59 59 #endif 60 60 61 // process cannot kill itself 62 if( pid == process->pid ) 61 // get pointers on process descriptor in owner cluster 62 owner_xp = cluster_get_owner_process_from_pid( pid ); 63 owner_cxy = GET_CXY( owner_xp ); 64 owner_ptr = GET_PTR( owner_xp ); 65 66 // check process found 67 if( owner_xp == XPTR_NULL) 63 68 { 64 69 65 70 #if CONFIG_DEBUG_SYSCALLS_ERROR 66 printk("\n[ERROR] in %s : process % d cannot kill itself\n", __FUNCTION__, pid );71 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__, pid ); 67 72 #endif 68 73 this->errno = EINVAL; … … 70 75 } 71 76 72 // get cluster and pointers on owner target process descriptor 73 owner_xp = cluster_get_owner_process_from_pid( pid ); 74 owner_cxy = GET_CXY( owner_xp ); 75 owner_ptr = GET_PTR( owner_xp ); 76 77 // check process existence 78 if( owner_xp == XPTR_NULL ) 77 // process can kill itself only when calling thread is the main thread 78 if( (pid == process->pid) && ((owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ))) ) 79 79 { 80 80 81 81 #if CONFIG_DEBUG_SYSCALLS_ERROR 82 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid);82 printk("\n[ERROR] in %s : only main thread can kill itself\n", __FUNCTION__ ); 83 83 #endif 84 84 this->errno = EINVAL; 85 85 return -1; 86 86 } 87 87 88 88 // get parent process PID 89 89 parent_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); … … 92 92 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 93 93 94 // processesINIT94 // check processe INIT 95 95 if( pid == 1 ) 96 96 { … … 103 103 } 104 104 105 // enable IRQs106 hal_enable_irq( &save_sr );107 108 105 // analyse signal type / supported values are : 0, SIGSTOP, SIGCONT, SIGKILL 109 106 switch( sig_id ) 110 107 { 111 case 0 : 108 case 0 : // does nothing 112 109 { 113 // does nothing114 110 retval = 0; 115 111 break; 116 112 } 117 case SIGSTOP: 113 case SIGSTOP: // block all target process threads 118 114 { 119 // remove TXT ownership from target process120 process_txt_ reset_ownership( owner_xp );115 // transfer TXT ownership 116 process_txt_transfer_ownership( owner_xp ); 121 117 122 // block all threads in all clusters 118 // block all threads in all clusters, but the main thread 123 119 process_sigaction( pid , BLOCK_ALL_THREADS ); 120 121 // get pointer on target process main thread 122 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 123 124 // block main thread 125 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 124 126 125 127 // atomically update owner process termination state 126 128 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 127 129 PROCESS_TERM_STOP ); 128 129 130 retval = 0; 130 131 break; 131 132 } 132 case SIGCONT: 133 case SIGCONT: // unblock all target process threads 133 134 { 134 135 // unblock all threads in all clusters 135 136 process_sigaction( pid , UNBLOCK_ALL_THREADS ); 136 137 137 // atomically update referenceprocess termination state138 // atomically update owner process termination state 138 139 hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) , 139 140 ~PROCESS_TERM_STOP ); … … 144 145 case SIGKILL: 145 146 { 146 // remove TXT ownership from owner process descriptor147 process_txt_ reset_ownership( owner_xp );147 // remove process from TXT list 148 process_txt_detach( owner_xp ); 148 149 149 // block all process threads in all clusters 150 process_sigaction( pid , BLOCK_ALL_THREADS ); 151 152 // mark all process threads in all clusters for delete 150 // mark for delete all process threads in all clusters, but the main 153 151 process_sigaction( pid , DELETE_ALL_THREADS ); 154 152 155 // atomically update owner process descriptor flags 153 // get pointer on target process main thread 154 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 155 156 // block main thread 157 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 158 159 // atomically update owner process descriptor term_state to ask 160 // the parent process sys_wait() function to delete this main thread 156 161 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 157 162 PROCESS_TERM_KILL ); 158 159 163 retval = 0; 160 164 break; … … 172 176 } 173 177 174 // restore IRQs175 hal_restore_irq( save_sr );176 177 178 hal_fence(); 178 179 … … 180 181 tm_end = hal_get_cycles(); 181 182 if( CONFIG_DEBUG_SYS_KILL < tm_end ) 182 printk("\n[DBG] %s : thread %x e nter/ process %x / sig %d / cost = %d / cycle %d\n",183 printk("\n[DBG] %s : thread %x exit / process %x / sig %d / cost = %d / cycle %d\n", 183 184 __FUNCTION__ , this, pid, sig_id, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 184 185 #endif -
trunk/kernel/syscalls/sys_read.c
r435 r436 37 37 38 38 extern uint32_t enter_sys_read; 39 extern uint32_t enter_devfs_ move;39 extern uint32_t enter_devfs_read; 40 40 extern uint32_t enter_txt_read; 41 extern uint32_t enter_chdev_cmd ;42 extern uint32_t enter_chdev_server ;43 extern uint32_t enter_tty_cmd ;44 extern uint32_t enter_tty_isr ;45 extern uint32_t exit_tty_isr ;46 extern uint32_t exit_tty_cmd ;47 extern uint32_t exit_chdev_server ;48 extern uint32_t exit_chdev_cmd ;41 extern uint32_t enter_chdev_cmd_read; 42 extern uint32_t enter_chdev_server_read; 43 extern uint32_t enter_tty_cmd_read; 44 extern uint32_t enter_tty_isr_read; 45 extern uint32_t exit_tty_isr_read; 46 extern uint32_t exit_tty_cmd_read; 47 extern uint32_t exit_chdev_server_read; 48 extern uint32_t exit_chdev_cmd_read; 49 49 extern uint32_t exit_txt_read; 50 extern uint32_t exit_devfs_ move;50 extern uint32_t exit_devfs_read; 51 51 extern uint32_t exit_sys_read; 52 52 … … 63 63 reg_t save_sr; // required to enable IRQs during syscall 64 64 65 #if (CONFIG_DEBUG_SYS_READ & 1)66 enter_sys_read = (uint32_t)tm_start;67 #endif68 69 65 thread_t * this = CURRENT_THREAD; 70 66 process_t * process = this->process; … … 79 75 #endif 80 76 77 #if (CONFIG_DEBUG_SYS_READ & 1) 78 enter_sys_read = (uint32_t)tm_start; 79 #endif 80 81 81 // check file_id argument 82 82 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) … … 122 122 123 123 // get file descriptor cluster and local pointer 124 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );124 vfs_file_t * file_ptr = GET_PTR( file_xp ); 125 125 cxy_t file_cxy = GET_CXY( file_xp ); 126 126 … … 165 165 else if( type == INODE_TYPE_DEV ) // check ownership & read from from device 166 166 { 167 // get cluster and pointers on TXT_RX chdev 168 xptr_t chdev_xp = chdev_from_file( file_xp ); 169 cxy_t chdev_cxy = GET_CXY( chdev_xp ); 170 chdev_t * chdev_ptr = GET_PTR( chdev_xp ); 171 172 volatile xptr_t owner_xp; 173 174 while( 1 ) 175 { 176 // extended pointer on owner process 177 owner_xp = hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) ); 178 179 // check TXT_RX ownership 180 if ( XPTR( local_cxy , process ) != owner_xp ) 181 { 182 // deschedule without blocking 183 sched_yield( "wait TXT ownership" ); 184 } 185 else 186 { 187 break; 188 } 189 } 190 167 191 // move count bytes from device 168 192 nbytes = devfs_user_move( true, // from device to buffer … … 171 195 count ); 172 196 173 // check ownership174 xptr_t chdev_xp = chdev_from_file( file_xp );175 cxy_t chdev_cxy = GET_CXY( chdev_xp );176 chdev_t * chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );177 xptr_t owner_xp = hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) );178 179 if( XPTR( local_cxy , process ) != owner_xp )180 {181 182 #if CONFIG_DEBUG_SYSCALLS_ERROR183 printk("\n[ERROR] in %s : process %x not in foreground for TXT%d\n",184 __FUNCTION__, process->pid, hal_remote_lw( XPTR(chdev_cxy,&chdev_ptr->channel) ) );185 #endif186 this->errno = EBADFD;187 return -1;188 }189 197 } 190 198 else … … 215 223 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n" 216 224 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 217 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid,225 __FUNCTION__ , this, process->pid, 218 226 (uint32_t)tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , 219 227 (uint32_t)(tm_end - tm_start) ); -
trunk/kernel/syscalls/sys_thread_cancel.c
r410 r436 1 1 /* 2 * sys_thread_cancel.c - terminate execution of a targetthread.2 * sys_thread_cancel.c - terminate execution of an user thread. 3 3 * 4 * Authors Alain Greiner (2016,2017 )4 * Authors Alain Greiner (2016,2017, 2018) 5 5 * 6 * Copyright (c) 2011,2012UPMC Sorbonne Universites6 * Copyright (c) UPMC Sorbonne Universites 7 7 * 8 8 * This file is part of ALMOS-MKH. … … 33 33 { 34 34 xptr_t target_xp; // target thread extended pointer 35 thread_t * target_ptr; // target thread local pointer36 cxy_t target_cxy; // target thread cluster37 ltid_t target_ltid; // target thread local index38 35 39 #if CONFIG_SYSCALL_DEBUG 40 uint32_t tm_start; 41 uint32_t tm_end; 42 tm_start = hal_get_cycles(); 43 #endif 44 36 // get killer thread pointers 45 37 thread_t * this = CURRENT_THREAD; 46 38 process_t * process = this->process; 47 48 // check kernel stack overflow49 assert( (this->signature == THREAD_SIGNATURE), __FUNCTION__, "kernel stack overflow\n" );50 51 // get target thread ltid and cxy52 target_ltid = LTID_FROM_TRDID( trdid );53 target_cxy = CXY_FROM_TRDID( trdid );54 55 // check trdid argument56 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) )57 {58 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );59 this->errno = EINVAL;60 return -1;61 }62 39 63 40 // get extended pointer on target thread 64 41 target_xp = thread_get_xptr( process->pid , trdid ); 65 42 43 // check target_xp 66 44 if( target_xp == XPTR_NULL ) 67 45 { 68 printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ ); 46 47 #if CONFIG_DEBUG_SYSCALLS_ERROR 48 printk("\n[ERROR] in %s : target thread %x not found\n", __FUNCTION__, trdid ); 49 #endif 69 50 this->errno = EINVAL; 70 51 return -1; 71 52 } 72 53 73 // get target thread local pointer 74 target_ptr = (thread_t *)GET_PTR( target_xp ); 54 #if CONFIG_DEBUG_SYS_THREAD_CANCEL 55 uint64_t tm_start; 56 uint64_t tm_end; 57 tm_start = hal_get_cycles(); 58 if( CONFIG_DEBUG_SYS_THREAD_CANCEL < tm_start ) 59 printk("\n[DBG] %s : thread %x enter to kill thread %x / cycle %d\n", 60 __FUCTION__, this, GET_PTR( target_xp ), (uint32_t)tm_start ); 61 #endif 75 62 76 63 // cal the relevant kernel function 77 if( target_cxy == local_cxy ) // target thread is local 78 { 79 thread_kill( target_ptr ); 80 } 81 else 82 { 83 rpc_thread_kill_client( target_cxy , target_ptr ); 84 } 64 thread_kill( target_xp, 65 0, // is_exit 66 0 ); // is forced 85 67 86 #if CONFIG_ SYSCALL_DEBUG68 #if CONFIG_DEBUG_SYS_THREAD_CANCEL 87 69 tm_end = hal_get_cycles(); 88 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 89 "thread %x killed / cost = %d\n", 90 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start , 91 trdid , (uint32_t)(tm_end - tm_start) ); 70 if( CONFIG_DEBUG_SYS_THREAD_CANCEL < tm_end ) 71 printk("\n[DBG] %s : thread %x exit after kill thread %x / cycle %d\n", 72 __FUCTION__, this, GET_PTR( target_xp ), (uint32_t)tm_end ); 92 73 #endif 93 74 -
trunk/kernel/syscalls/sys_thread_exit.c
r433 r436 32 32 int sys_thread_exit( void * exit_value ) 33 33 { 34 paddr_t paddr;35 error_t error;36 37 #if CONFIG_SYSCALL_DEBUG38 uint32_t tm_start;39 uint32_t tm_end;40 tm_start = hal_get_cycles();41 #endif42 43 34 thread_t * this = CURRENT_THREAD; 44 35 process_t * process = this->process; 45 36 46 // check all locks released 47 if( !thread_can_yield() ) 48 { 49 printk("\n[ERROR] in %s : locks not released / thread %x in process %x\n", 50 __FUNCTION__, this->trdid, process->pid ); 37 // check exit_value argument 38 if( exit_value != NULL ) 39 { 40 41 #if CONFIG_DEBUG_SYSCALLS_ERROR 42 printk("\n[ERROR] in %s : exit_value argument must be NULL for thread %x in process %x\n", 43 __FUNCTION__ , exit_value, this->trdid , process->pid ); 44 #endif 51 45 this->errno = EINVAL; 52 46 return -1; 53 47 } 54 48 55 // register the exit_value pointer in this thread descriptor 56 this->join_value = exit_value; 57 58 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) // this thread is joinable 59 { 60 // check exit_value in user space 61 error = vmm_v2p_translate( false , exit_value , &paddr ); 62 if( error ) 63 { 64 printk("\n[ERROR] in %s : illegal pointer = %x / thread %x in process %x\n", 65 __FUNCTION__ , (intptr_t)exit_value, this->trdid , process->pid ); 66 this->errno = EINVAL; 67 return -1; 68 } 69 70 // take the lock protecting the join 71 remote_spinlock_lock( XPTR( local_cxy, &this->join_lock ) ); 72 73 if( this->flags & THREAD_FLAG_JOIN_DONE ) // parent thread arrived first 74 { 75 // unblock the parent thread 76 thread_unblock( this->join_xp , THREAD_BLOCKED_EXIT ); 77 78 // reset the JOIN_DONE flag in this thread 79 this->flags &= ~THREAD_FLAG_JOIN_DONE; 80 81 // release the lock protecting the flags 82 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 83 } 84 else // this thread arrived first 85 { 86 // block this thread 87 thread_block( this , THREAD_BLOCKED_JOIN ); 88 89 // release the lock protecting the join 90 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 91 92 // deschedule 93 sched_yield( "WAITING JOIN" ); 94 } 95 } 96 97 #if CONFIG_SYSCALL_DEBUG 98 tm_end = hal_get_cycles(); 99 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 100 "thread %x killed / cost = %d\n", 101 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start , 102 this->trdid , (uint32_t)(tm_end - tm_start) ); 49 #if CONFIG_DEBUG_SYS_THREAD_EXIT 50 uint64_t tm_start; 51 uint64_t tm_end; 52 tm_start = hal_get_cycles(); 53 if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_start ) 54 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 55 __FUNCTION__ , this, process->pid , (uint32_t)tm_start ); 103 56 #endif 104 57 105 // suicide using a rpc because a thread cannot kill itself 106 rpc_thread_kill_client( local_cxy , this ); 58 // cal the relevant kernel function 59 thread_kill( XPTR( local_cxy , this ), 60 1, // is_exit 61 0 ); // is forced 107 62 63 #if CONFIG_DEBUG_SYS_THREAD_EXIT 64 tm_end = hal_get_cycles(); 65 if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_end ) 66 printk("\n[DBG] %s : thread %x exit / process %x / cost %d / cycle %d\n", 67 __FUNCTION__, this, this->process->pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 68 #endif 69 70 // deschedule <=> suicide, because blocked by thread_kill() 71 sched_yield( "suicide after thread_exit" ); 72 108 73 return 0; // never executed but required by compiler 109 74 -
trunk/kernel/syscalls/sys_thread_join.c
r421 r436 25 25 #include <hal_remote.h> 26 26 #include <hal_special.h> 27 #include <hal_irqmask.h> 27 28 #include <thread.h> 28 29 #include <vmm.h> … … 36 37 void ** exit_value ) 37 38 { 39 reg_t save_sr; 38 40 xptr_t target_xp; 39 41 thread_t * target_ptr; 40 42 cxy_t target_cxy; 41 43 ltid_t target_ltid; 42 uint32_t target_blocked; // target thread blocked bit-vector 43 uint32_t target_flags; // target thread flags bit-bector 44 paddr_t paddr; // required for vmm_v2p_translate() 44 xptr_t target_join_lock_xp; 45 xptr_t target_flags_xp; 46 xptr_t target_blocked_xp; 47 xptr_t target_join_xp_xp; 48 xptr_t killer_xp; 49 xptr_t joining_xp; 50 thread_t * joining_ptr; 51 process_t * process; 45 52 46 thread_t * this = CURRENT_THREAD; 47 process_t * process = this->process; 53 // get joining thread pointers 54 joining_ptr = CURRENT_THREAD; 55 joining_xp = XPTR( local_cxy , joining_ptr ); 56 process = joining_ptr->process; 48 57 49 58 // get target thread ltid and cxy … … 51 60 target_cxy = CXY_FROM_TRDID( trdid ); 52 61 62 #if CONFIG_DEBUG_SYS_THREAD_JOIN 63 uint64_t tm_start; 64 uint64_t tm_end; 65 tm_start = hal_get_cycles(); 66 if( CONFIG_DEBUG_SYS_THREAD_JOIN < tm_start ) 67 printk("\n[DBG] %s : parent thread %x enter / process %x / target trdid %x / cycle %d\n", 68 __FUNCTION__ , joining_ptr , process->pid , trdid , (uint32_t)tm_start ); 69 #endif 70 53 71 // check trdid argument 54 72 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 55 73 { 56 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ ); 57 this->errno = EINVAL; 74 75 #if CONFIG_DEBUG_SYSCALLS_ERROR 76 printk("\n[ERROR] in %s : illegal trdid argument %x\n", __FUNCTION__, trdid ); 77 #endif 78 joining_ptr->errno = EINVAL; 58 79 return -1; 59 80 } 60 81 61 82 // check exit_value argument 62 if( (exit_value != NULL) && (vmm_v2p_translate( false , exit_value , &paddr ) != 0 ))83 if( exit_value != NULL ) 63 84 { 64 printk("\n[ERROR] in %s : illegal exit_value argument\n", __FUNCTION__ ); 65 this->errno = EINVAL; 85 86 #if CONFIG_DEBUG_SYSCALLS_ERROR 87 printk("\n[ERROR] in %s : exit_value argument must be NULL\n", __FUNCTION__ ); 88 #endif 89 joining_ptr->errno = EINVAL; 66 90 return -1; 67 91 } 68 92 69 93 // check target thread != this thread 70 if( this->trdid == trdid )94 if( joining_ptr->trdid == trdid ) 71 95 { 72 printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ ); 73 this->errno = EDEADLK; 96 97 #if CONFIG_DEBUG_SYSCALLS_ERROR 98 printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ ); 99 #endif 100 joining_ptr->errno = EDEADLK; 74 101 return -1; 75 102 } 76 103 77 // get extended pointeron target thread104 // get pointers on target thread 78 105 target_xp = thread_get_xptr( process->pid , trdid ); 106 target_ptr = GET_PTR( target_xp ); 79 107 80 108 if( target_xp == XPTR_NULL ) 81 109 { 82 printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ ); 83 this->errno = ESRCH; 110 111 #if CONFIG_DEBUG_SYSCALLS_ERROR 112 printk("\n[ERROR] in %s : target thread %x not found\n", __FUNCTION__, trdid ); 113 #endif 114 joining_ptr->errno = ESRCH; 84 115 return -1; 85 116 } 86 117 87 // get cluster and local pointer on target thread 88 target_ptr = (thread_t *)GET_PTR( target_xp ); 118 // get extended pointers on various fields in target thread 119 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 120 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 121 target_blocked_xp = XPTR( target_cxy , &target_ptr->blocked ); 122 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 89 123 90 124 // check target thread joinable 91 target_flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) ); 92 if( target_flags & THREAD_FLAG_DETACHED ) 125 if( (hal_remote_lw( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0 ) 93 126 { 94 printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ ); 95 this->errno = EINVAL; 127 128 #if CONFIG_DEBUG_SYSCALLS_ERROR 129 printk("\n[ERROR] in %s : target thread %x not joinable\n", __FUNCTION__, trdid ); 130 #endif 131 joining_ptr->errno = EINVAL; 96 132 return -1; 97 133 } 98 134 99 // check kernel stack overflow 100 if( target_ptr->signature != THREAD_SIGNATURE ) 135 // mask IRQs 136 hal_disable_irq( &save_sr ); 137 138 // get the lock protecting the join in target thread 139 remote_spinlock_lock( target_join_lock_xp ); 140 141 // test the kill_done flag from the target thread 142 if( hal_remote_lw( target_flags_xp ) & THREAD_FLAG_KILL_DONE ) // killer thread is first 101 143 { 102 assert( false , __FUNCTION__ , "kernel stack overflow\n" ); 144 // get pointers on killer thread 145 killer_xp = (xptr_t)hal_remote_lwd( target_join_xp_xp ); 146 147 // reset the kill_done flag in target thread 148 hal_remote_atomic_and( target_flags_xp , ~THREAD_FLAG_KILL_DONE ); 149 150 // unblock the killer thread 151 thread_unblock( killer_xp , THREAD_BLOCKED_JOIN ); 152 153 // release the lock protecting join 154 remote_spinlock_unlock( target_join_lock_xp ); 155 156 // restore IRQs 157 hal_restore_irq( save_sr ); 158 } 159 else // joining thread is first 160 { 161 // set the join_done flag in target thread 162 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_JOIN_DONE ); 163 164 // block joining thread on BLOCKED_JOIN 165 thread_block( joining_xp , THREAD_BLOCKED_JOIN ); 166 167 // register the joining thread extended pointer in target thread 168 hal_remote_swd( target_join_xp_xp , joining_xp ); 169 170 // release the lock protecting the join 171 remote_spinlock_unlock( target_join_lock_xp ); 172 173 // deschedule 174 sched_yield( "joining thread waiting killer thread" ); 175 176 // restore IRQs 177 hal_restore_irq( save_sr ); 103 178 } 104 179 105 // get the lock protecting the join in target thread 106 remote_spinlock_lock( XPTR( target_cxy , &target_ptr->join_lock ) ); 107 108 // get the blocked bit_vector from the target thread 109 target_blocked = hal_remote_lw( XPTR( target_cxy , &target_ptr->blocked ) ); 110 111 if( target_blocked & THREAD_BLOCKED_JOIN ) // target thread arrived first 112 { 113 // unblock the target thread 114 thread_unblock( target_xp , THREAD_BLOCKED_JOIN ); 115 116 // release the lock protecting flags 117 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 118 119 // get the exit value from target thread 120 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 121 } 122 else // this thread arrived first 123 { 124 // register this thread extended pointer in target thread 125 hal_remote_swd( XPTR( target_cxy , &target_ptr->join_xp ) , 126 XPTR( local_cxy , this ) ); 127 128 // set the JOIN_DONE flag in target thread 129 hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) , 130 THREAD_FLAG_JOIN_DONE ); 131 132 // block this thread on BLOCKED_EXIT 133 thread_block( this , THREAD_BLOCKED_EXIT ); 134 135 // release the lock protecting flags 136 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 137 138 // deschedule 139 sched_yield( "WAITING_EXIT" ); 140 141 // get the exit value from target thread when resume 142 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 143 } 180 #if CONFIG_DEBUG_SYS_THREAD_JOIN 181 tm_end = hal_get_cycles(); 182 if( CONFIG_DEBUG_SYS_THREAD_JOIN < tm_end ) 183 printk("\n[DBG] %s : parent thread %x exit / process %x / target trdid %x / cycle %d\n", 184 __FUNCTION__, joining_ptr, process->pid, trdid, (uint32_t)tm_end ); 185 #endif 144 186 145 187 return 0; -
trunk/kernel/syscalls/sys_thread_sleep.c
r408 r436 30 30 int sys_thread_sleep() 31 31 { 32 32 33 thread_t * this = CURRENT_THREAD; 33 34 34 thread_dmsg("\n[DBG] %s : thread %x in process %x goes to sleep at cycle %d\n", 35 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 35 #if CONFIG_DEBUG_SYS_THREAD_SLEEP 36 uint64_t tm_start; 37 uint64_t tm_end; 38 tm_start = hal_get_cycles(); 39 if( CONFIG_DEBUG_SYS_THREAD_SLEEP < tm_start ) 40 printk("\n[DBG] %s : thread %x blocked / process %x / cycle %d\n", 41 __FUNCTION__ , this, this->process->pid , (uint32_t)tm_start ); 42 #endif 36 43 37 thread_block( this, THREAD_BLOCKED_GLOBAL );44 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL ); 38 45 sched_yield("blocked on sleep"); 39 46 40 thread_dmsg("\n[DBG] %s : thread %x in process %x resume at cycle\n", 41 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 47 #if CONFIG_DEBUG_SYS_THREAD_SLEEP 48 tm_end = hal_get_cycles(); 49 if( CONFIG_DEBUG_SYS_THREAD_SLEEP < tm_end ) 50 printk("\n[DBG] %s : thread %x resume / process %x / cycle %d\n", 51 __FUNCTION__ , this, this->process->pid , (uint32_t)tm_end ); 52 #endif 42 53 43 54 return 0; 55 44 56 } // end sys_thread_sleep() -
trunk/kernel/syscalls/sys_thread_wakeup.c
r23 r436 34 34 process_t * process = this->process; 35 35 36 #if CONFIG_DEBUG_SYS_THREAD_WAKEUP 37 uint64_t tm_start; 38 uint64_t tm_end; 39 tm_start = hal_get_cycles(); 40 if( CONFIG_DEBUG_SYS_THREAD_WAKEUP < tm_start ) 41 printk("\n[DBG] %s : thread %x enter / activate thread %x in process %x / cycle %d\n", 42 __FUNCTION__ , this, trdid, this->process->pid, (uint32_t)tm_start ); 43 #endif 44 36 45 // get target thread ltid and cxy 37 46 ltid_t target_ltid = LTID_FROM_TRDID( trdid ); … … 41 50 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 42 51 { 43 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ ); 52 53 #if CONFIG_DEBUG_SISCALLS_ERROR 54 printk("\n[ERROR] in %s : illegal trdid argument %x\n", __FUNCTION__, trdid ); 55 #endif 44 56 this->errno = EINVAL; 45 57 return -1; … … 51 63 if( thread_xp == XPTR_NULL ) 52 64 { 53 printk("\n[ERROR] in %s : cannot find thread %x in process %x/n", 54 __FUNCTION__ , trdid , CURRENT_THREAD->process->pid ); 65 66 #if CONFIG_DEBUG_SISCALLS_ERROR 67 printk("\n[ERROR] in %s : cannot find thread %x in process %x/n", 68 __FUNCTION__ , trdid , this->process->pid ); 69 #endif 55 70 CURRENT_THREAD->errno = EINVAL; 56 71 return -1; … … 60 75 thread_unblock( thread_xp , THREAD_BLOCKED_GLOBAL ); 61 76 77 #if CONFIG_DEBUG_SYS_THREAD_WAKEUP 78 tm_end = hal_get_cycles(); 79 if( CONFIG_DEBUG_SYS_THREAD_WAKEUP < tm_end ) 80 printk("\n[DBG] %s : thread %x exit / thread %x in process %x activated / cycle %d\n", 81 __FUNCTION__ , this, trdid, this->process->pid, (uint32_t)tm_end ); 82 #endif 83 62 84 return 0; 85 63 86 } // end sys_thread_wakeup() -
trunk/kernel/syscalls/sys_wait.c
r435 r436 68 68 __FUNCTION__ , this->trdid , process->pid ); 69 69 #endif 70 this->errno = E FAULT;70 this->errno = EINVAL; 71 71 return -1; 72 72 } 73 73 74 // get process owner cluster 75 cxy_t owner_cxy = CXY_FROM_PID( pid ); 74 // get process owner cluster and calling thread trdid 75 cxy_t owner_cxy = CXY_FROM_PID( pid ); 76 trdid_t trdid = this->trdid; 76 77 77 // This function must be executed in owner cluster78 assert( (owner_cxy == local_cxy) , __FUNCTION__ ,79 "calling thread must execute in owner cluster" );78 // wait must be executed by the main thread 79 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID(trdid) != 0) ) 80 { 80 81 81 // This function must be executed by the main thread 82 assert( (process->th_tbl[0] == this) , __FUNCTION__ , 83 "this function must be executed by the main thread" ); 84 82 #if CONFIG_DEBUG_SYSCALL_ERROR 83 printk("\n[ERROR] in %s : calling thread %x is not thread 0 in owner cluster %x\n", 84 __FUNCTION__ , trdid , owner_cxy ); 85 #endif 86 this->errno = EINVAL; 87 return -1; 88 } 89 85 90 // get extended pointer on children list root and lock 86 91 xptr_t children_root_xp = XPTR( owner_cxy , &process->children_root ); … … 96 101 remote_spinlock_lock( children_lock_xp ); 97 102 98 // scan the list of ownerchild process103 // scan the list of child process 99 104 XLIST_FOREACH( children_root_xp , iter_xp ) 100 105 { … … 115 120 { 116 121 // get pointer on main thread and PID from child owner process 117 child_pid = (pid_t) hal_remote_lw ( XPTR(child_cxy,&child_ptr->pid)); 118 child_thread = (thread_t *)hal_remote_lpt( XPTR(child_cxy,&child_ptr->th_tbl[0])); 122 child_pid = (pid_t) hal_remote_lw (XPTR( child_cxy , &child_ptr->pid )); 123 child_thread = (thread_t *)hal_remote_lpt(XPTR( child_cxy , 124 &child_ptr->th_tbl[0] )); 119 125 120 126 // set the PROCESS_FLAG_WAIT in owner child descriptor … … 135 141 __FUNCTION__, this, process->pid, child_pid, (uint32_t)tm_end ); 136 142 #endif 137 // return relevant info to callingparent process143 // return child termination state to parent process 138 144 hal_copy_to_uspace( status , &child_state , sizeof(int) ); 139 145 return child_pid; 140 146 } 141 } 147 } // end loop on children 142 148 143 149 // release lock protecting children list -
trunk/kernel/syscalls/syscalls.h
r435 r436 100 100 /****************************************************************************************** 101 101 * [5] This function requests a target thread identified by its <trdid> argument 102 * to be cancelled. Depending on killer thread and target thread location, it calls 103 * the thread_kil() function or the rpc_thread_kill_client() function to do the work. 104 * It actually set the THREAD_SIG_KILL signal, set the THREAD_BLOCKED_GLOBAL bit in the 105 * target thread descriptor and return. 102 * to be cancelled. It calls the thread_kill() function to block the target thread 103 * on the THREAD_BLOCKED_GLOBAL condition, and to set the THREAD_FLAG_REQ_DELETE. 106 104 * The thread will be detached from its process, and the memory allocated to the thread 107 * descriptor will be released later by the scheduler.105 * descriptor will be released by the scheduler at the next scheduling point. 108 106 ****************************************************************************************** 109 107 * @ trdid : thread identifier. -
trunk/kernel_config.h
r435 r436 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (2016 )6 * Alain Greiner (2016,2017,2018) 7 7 * 8 8 * Copyright (c) UPMC Sorbonne Universites … … 27 27 #define _ALMOS_CONFIG_H_ 28 28 29 #define CONFIG_ALMOS_VERSION "Version 1.0 / March 201 7"29 #define CONFIG_ALMOS_VERSION "Version 1.0 / March 2018" 30 30 31 31 //////////////////////////////////////////////////////////////////////////////////////////// … … 42 42 43 43 #define CONFIG_DEBUG_CLUSTER_INIT 0 44 45 #define CONFIG_DEBUG_DEV_TXT 0 44 #define CONFIG_DEBUG_CLUSTER_PROCESS_COPIES 0 45 46 #define CONFIG_DEBUG_DEV_TXT_RX 0 47 #define CONFIG_DEBUG_DEV_TXT_TX 0 46 48 #define CONFIG_DEBUG_DEV_IOC 0 47 #define CONFIG_DEBUG_DEV_NIC 0 49 #define CONFIG_DEBUG_DEV_NIC_RX 0 50 #define CONFIG_DEBUG_DEV_NIC_RX 0 48 51 #define CONFIG_DEBUG_DEV_FBF 0 49 52 #define CONFIG_DEBUG_DEV_MMC 0 … … 59 62 60 63 #define CONFIG_DEBUG_HAL_KENTRY 0 61 #define CONFIG_DEBUG_HAL_TXT 0 64 #define CONFIG_DEBUG_HAL_TXT_RX 0 65 #define CONFIG_DEBUG_HAL_TXT_TX 0 62 66 #define CONFIG_DEBUG_HAL_EXCEPTIONS 0 63 67 #define CONFIG_DEBUG_HAL_IRQS 0 … … 68 72 #define CONFIG_DEBUG_KERNEL_INIT 0 69 73 #define CONFIG_DEBUG_KMEM_ALLOC 0 70 71 #define CONFIG_DEBUG_LOCKS 072 74 73 75 #define CONFIG_DEBUG_MAPPER_GET_PAGE 0 … … 85 87 #define CONFIG_DEBUG_PROCESS_REFERENCE_INIT 0 86 88 #define CONFIG_DEBUG_PROCESS_SIGACTION 0 87 #define CONFIG_DEBUG_PROCESS_TXT_ATTACH 289 #define CONFIG_DEBUG_PROCESS_TXT_ATTACH 0 88 90 #define CONFIG_DEBUG_PROCESS_ZERO_CREATE 0 89 91 90 92 #define CONFIG_DEBUG_RPC_MARSHALING 0 91 #define CONFIG_DEBUG_RPC_GENERIC 0 92 93 #define CONFIG_DEBUG_SCHED_HANDLE_SIGNALS 0 93 #define CONFIG_DEBUG_RPC_SEND 0 94 #define CONFIG_DEBUG_RPC_SERVER 0 95 96 #define CONFIG_DEBUG_SCHED_HANDLE_SIGNALS 0 94 97 #define CONFIG_DEBUG_SCHED_YIELD 0 95 98 … … 97 100 98 101 #define CONFIG_DEBUG_SYS_DISPLAY 0 99 #define CONFIG_DEBUG_SYS_EXEC 2102 #define CONFIG_DEBUG_SYS_EXEC 0 100 103 #define CONFIG_DEBUG_SYS_EXIT 0 101 #define CONFIG_DEBUG_SYS_FORK 2 102 #define CONFIG_DEBUG_SYS_GET_CONFIG 2 103 #define CONFIG_DEBUG_SYS_KILL 2 104 #define CONFIG_DEBUG_SYS_FG 0 105 #define CONFIG_DEBUG_SYS_FORK 0 106 #define CONFIG_DEBUG_SYS_GET_CONFIG 0 107 #define CONFIG_DEBUG_SYS_KILL 0 104 108 #define CONFIG_DEBUG_SYS_MMAP 0 105 109 #define CONFIG_DEBUG_SYS_READ 0 106 #define CONFIG_DEBUG_SYS_WAIT 2 110 #define CONFIG_DEBUG_SYS_THREAD_CANCEL 0 111 #define CONFIG_DEBUG_SYS_THREAD_EXIT 0 112 #define CONFIG_DEBUG_SYS_THREAD_JOIN 0 113 #define CONFIG_DEBUG_SYS_THREAD_SLEEP 0 114 #define CONFIG_DEBUG_SYS_THREAD_WAKEUP 0 115 #define CONFIG_DEBUG_SYS_WAIT 0 107 116 #define CONFIG_DEBUG_SYS_WRITE 0 117 118 #define CONFIG_DEBUG_SPINLOCKS 0 119 #define CONFIG_DEBUG_REMOTE_SPINLOCKS 0 120 #define CONFIG_DEBUG_RWLOCKS 0 121 #define CONFIG_DEBUG_REMOTE_RWLOCKS 0 108 122 109 123 #define CONFIG_DEBUG_THREAD_DESTROY 0 -
trunk/user/init/init.c
r435 r436 20 20 #include <pthread.h> 21 21 22 #define DELAY_BETWEEN_FORK 10000023 24 22 ////////// 25 23 int main() … … 28 26 int ret_fork; // fork return value 29 27 int ret_exec; // fork return value 30 int r eceived_pid;// pid received from the wait syscall28 int rcv_pid; // pid received from the wait syscall 31 29 int status; // used by the wait syscall 32 30 char string[64]; … … 41 39 ret_fork = fork(); 42 40 43 if( ret_fork < 0 ) // error in fork41 if( ret_fork < 0 ) // error in fork 44 42 { 45 43 // INIT display error message on TXT0 terminal 46 snprintf( string , 64 , 47 "INIT cannot fork child[%d]\n" , i ); 44 snprintf( string , 64 , "INIT cannot fork child[%d]" , i ); 48 45 display_string( string ); 49 46 50 // INIT exit47 // INIT suicide 51 48 exit( 0 ); 52 49 } … … 58 55 if ( ret_exec ) // error in exec 59 56 { 60 // display error message on TXT0 terminal57 // CHILD[i] display error message on TXT0 terminal 61 58 snprintf( string , 64 , 62 "CHILD[%d] cannot exec KSH[%d] / ret_exec = %d \n" , i , i , ret_exec );59 "CHILD[%d] cannot exec KSH[%d] / ret_exec = %d" , i , i , ret_exec ); 63 60 display_string( string ); 64 61 } … … 67 64 { 68 65 // INIT display CHILD[i] process PID 69 snprintf( string , 64 , 70 "INIT forked CHILD[%d] / pid = %x\n", i , ret_fork ); 66 snprintf( string , 64 , "INIT created KSH[%d] / pid = %x", i , ret_fork ); 71 67 display_string( string ); 72 68 } 73 74 69 } 75 70 76 71 // This loop detects the termination of the KSH[i] processes, 77 // to recreate theseprocess when required.72 // and recreate a new KSH[i] process when required. 78 73 while( 1 ) 79 74 { 80 75 // block on child processes termination 81 r eceived_pid = wait( &status );76 rcv_pid = wait( &status ); 82 77 83 78 if( WIFSTOPPED( status ) ) // stopped => unblock it 84 79 { 85 80 // display string to report unexpected KSH process block 86 snprintf( string , 64 , "KSH process %x unexpectedly stopped" , received_pid );81 snprintf( string , 64 , "KSH process %x stopped => unblock it" , rcv_pid ); 87 82 display_string( string ); 88 83 89 } 84 // TODO : unblock KSH 85 86 } // end KSH stopped handling 90 87 91 88 if( WIFSIGNALED( status ) || WIFEXITED( status ) ) // killed => recreate it 92 89 { 93 90 // display string to report unexpected KSH process termination 94 snprintf( string , 64 , "KSH process %x unexpectedly terminated" , received_pid );91 snprintf( string , 64 , "KSH process %x terminated => recreate KSH", rcv_pid ); 95 92 display_string( string ); 96 } 93 94 // INIT process fork a new CHILD process 95 ret_fork = fork(); 96 97 if( ret_fork < 0 ) // error in fork 98 { 99 // INIT display error message on TXT0 terminal 100 snprintf( string , 64 , "INIT cannot fork child"); 101 display_string( string ); 102 103 // INIT suicide 104 exit( 0 ); 105 } 106 else if( ret_fork == 0 ) // we are in CHILD process 107 { 108 // CHILD process exec process KSH 109 ret_exec = exec( "/bin/user/ksh.elf" , NULL , NULL ); 110 111 if ( ret_exec ) // error in exec 112 { 113 // CHILD display error message on TXT0 terminal 114 snprintf( string , 64 , "CHILD cannot exec KSH" ); 115 display_string( string ); 116 } 117 } 118 else // we are in INIT process 119 { 120 // INIT display new CHILD process PID 121 snprintf( string , 64 , "INIT forked CHILD / pid = %x", ret_fork ); 122 display_string( string ); 123 } 124 } // end KSH kill handling 97 125 } 98 126 -
trunk/user/ksh/ksh.c
r435 r436 13 13 14 14 #define CMD_MAX_SIZE (256) // max number of characters in one command 15 #define LOG_DEPTH ( 256)// max number of registered commands15 #define LOG_DEPTH (32) // max number of registered commands 16 16 #define MAX_ARGS (32) // max number of arguments in a command 17 17 #define FIFO_SIZE (1024) // FIFO depth for recursive ls … … 228 228 } // end cmd_cp() 229 229 230 ///////////////////////////////////////////////// 231 static void cmd_display( int argc , char **argv ) 232 { 233 unsigned int cxy; 234 unsigned int lid; 235 unsigned int pid; 236 unsigned int txt_id; 237 238 if( strcmp( argv[1] , "vmm" ) == 0 ) 239 { 240 if( argc != 3 ) 241 { 242 printf(" usage: display vmm pid\n"); 243 return; 244 } 245 246 pid = atoi(argv[2]); 247 248 if( display_vmm( pid ) ) 249 { 250 printf(" error: illegal arguments pid = %x\n", pid ); 251 } 252 } 253 else if( strcmp( argv[1] , "sched" ) == 0 ) 254 { 255 if( argc != 4 ) 256 { 257 printf(" usage: display sched cxy lid\n"); 258 return; 259 } 260 261 cxy = atoi(argv[2]); 262 lid = atoi(argv[3]); 263 264 if( display_sched( cxy , lid ) ) 265 { 266 printf(" error: illegal arguments cxy = %x / lid = %d\n", cxy, lid ); 267 } 268 } 269 else if( strcmp( argv[1] , "process" ) == 0 ) 270 { 271 if( argc != 3 ) 272 { 273 printf(" usage: display process cxy\n"); 274 return; 275 } 276 277 cxy = atoi(argv[2]); 278 279 if( display_cluster_processes( cxy ) ) 280 { 281 printf(" error: illegal argument cxy = %x\n", cxy ); 282 } 283 } 284 else if( strcmp( argv[1] , "txt" ) == 0 ) 285 { 286 if( argc != 3 ) 287 { 288 printf(" usage: display txt txt_id\n"); 289 return; 290 } 291 292 txt_id = atoi(argv[2]); 293 294 if( display_txt_processes( txt_id ) ) 295 { 296 printf(" error: illegal argument txt_id = %x\n", txt_id ); 297 } 298 } 299 else if( strcmp( argv[1] , "vfs" ) == 0 ) 300 { 301 if( argc != 2 ) 302 { 303 printf(" usage: display vfs\n"); 304 return; 305 } 306 307 display_vfs(); 308 } 309 else if( strcmp( argv[1] , "chdev" ) == 0 ) 310 { 311 if( argc != 2 ) 312 { 313 printf(" usage: display chdev\n"); 314 return; 315 } 316 317 display_chdev(); 318 } 319 else 320 { 321 printf(" usage: display (vmm/sched/process/vfs/chdev/txt) [arg2] [arg3]\n"); 322 } 323 } // end cmd_display() 324 230 325 ///////////////////////////////////////// 231 326 static void cmd_fg(int argc, char **argv) … … 250 345 printf(" error: cannot find process %x\n", pid ); 251 346 } 252 } 347 } // end cmd_fg() 253 348 254 349 ////////////////////////////////////////////// … … 297 392 static void cmd_load( int argc , char **argv ) 298 393 { 299 int ret; 300 unsigned int ksh_pid; 301 char * pathname; 302 unsigned int background; 394 int ret_fork; // return value from fork 395 int ret_exec; // return value from exec 396 unsigned int ksh_pid; // KSH process PID 397 unsigned int new_pid; // new process PID 398 unsigned int rcv_pid; // terminating process PID 399 char * pathname; // path to .elf file 400 unsigned int background; // background execution if non zero 401 int status; // new process exit status 303 402 304 403 if( (argc < 2) || (argc > 3) ) … … 317 416 318 417 // KSH process fork CHILD process 319 ret = fork();320 321 if ( ret < 0 ) // it is a failure reported to parent418 ret_fork = fork(); 419 420 if ( ret_fork < 0 ) // it is a failure reported to KSH 322 421 { 323 422 printf(" error: ksh process unable to fork\n"); 324 423 } 325 else if (ret == 0)// it is the CHILD process326 { 327 // give back to KSH process the terminal ownership424 else if (ret_fork == 0) // it is the CHILD process 425 { 426 // give back to KSH terminal ownership if required 328 427 if( background ) fg( ksh_pid ); 329 428 330 429 // CHILD process exec NEW process 331 ret = exec( pathname , NULL , NULL );332 333 if( ret )430 ret_exec = exec( pathname , NULL , NULL ); 431 432 if( ret_exec ) 334 433 { 335 434 printf(" error: new process unable to exec <%s>\n", pathname ); 336 435 exit(0); 436 } 437 } 438 else // it is the parent KSH : ret_fork is the new process PID 439 { 440 new_pid = ret_fork; 441 442 // wait new process completion 443 rcv_pid = wait( &status ); 444 445 if( rcv_pid == new_pid ) 446 { 447 printf("\n\n exit %s / status = %x\n\n", pathname, (status &0xFF) ); 337 448 } 338 } 449 else 450 { 451 printf("\n\n abnormal termination for %s \n\n", pathname ); 452 } 453 } 454 339 455 } // end cmd_load 340 456 … … 347 463 for (i = 0; i < LOG_DEPTH; i++) 348 464 { 349 printf(" - % zu\t: %s\n", i, &log_entries[i].buf);465 printf(" - %d\t: %s\n", i, &log_entries[i].buf); 350 466 } 351 467 } … … 476 592 { 477 593 cmd_rm(argc, argv); 478 }479 480 /////////////////////////////////////////////////481 static void cmd_display( int argc , char **argv )482 {483 unsigned int cxy;484 unsigned int lid;485 unsigned int pid;486 unsigned int txt_id;487 488 if( strcmp( argv[1] , "vmm" ) == 0 )489 {490 if( argc != 3 )491 {492 printf(" usage: display vmm pid\n");493 return;494 }495 496 pid = atoi(argv[2]);497 498 if( display_vmm( pid ) )499 {500 printf(" error: illegal arguments pid = %x\n", pid );501 }502 }503 else if( strcmp( argv[1] , "sched" ) == 0 )504 {505 if( argc != 4 )506 {507 printf(" usage: display sched cxy lid\n");508 return;509 }510 511 cxy = atoi(argv[2]);512 lid = atoi(argv[3]);513 514 if( display_sched( cxy , lid ) )515 {516 printf(" error: illegal arguments cxy = %x / lid = %d\n", cxy, lid );517 }518 }519 else if( strcmp( argv[1] , "process" ) == 0 )520 {521 if( argc != 3 )522 {523 printf(" usage: display process cxy\n");524 return;525 }526 527 cxy = atoi(argv[2]);528 529 if( display_cluster_processes( cxy ) )530 {531 printf(" error: illegal argument cxy = %x\n", cxy );532 }533 }534 else if( strcmp( argv[1] , "txt" ) == 0 )535 {536 if( argc != 3 )537 {538 printf(" usage: display txt txt_id\n");539 return;540 }541 542 txt_id = atoi(argv[2]);543 544 if( display_txt_processes( txt_id ) )545 {546 printf(" error: illegal argument txt_id = %x\n", txt_id );547 }548 }549 else if( strcmp( argv[1] , "vfs" ) == 0 )550 {551 if( argc != 2 )552 {553 printf(" usage: display vfs\n");554 return;555 }556 557 display_vfs();558 }559 else if( strcmp( argv[1] , "chdev" ) == 0 )560 {561 if( argc != 2 )562 {563 printf(" usage: display chdev\n");564 return;565 }566 567 display_chdev();568 }569 else570 {571 printf(" usage: display (vmm/sched/process/vfs/chdev/txt) [arg2] [arg3]\n");572 }573 594 } 574 595 … … 687 708 // - ESCAPE : the character (ESC) has been found 688 709 // - BRAKET : the wo characters (ESC,[) have been found 710 689 711 unsigned int state = NORMAL; 690 691 712 692 713 // @@@ … … 694 715 // @@@ 695 716 717 char string[64]; 696 718 697 719 while (1) … … 738 760 { 739 761 } 740 else if (c == 0x1B) // ESC => start an escape sequence762 else if (c == (char)0x1B) // ESC => start an escape sequence 741 763 { 742 764 state = ESCAPE; … … 838 860 } 839 861 } 840 } 841 862 } // end main() 863 -
trunk/user/pgcd/pgcd.c
r434 r436 9 9 10 10 #include <stdlib.h> 11 #include <stdio.h> 11 12 12 13 … … 14 15 void main() 15 16 { 16 int opx; 17 int opy; 17 int opx; 18 int opy; 19 unsigned long long cycle; 18 20 19 printf( "*** Starting interactive pgcd ***\n\n" ); 21 get_cycle( &cycle ); 22 printf( "\n[PGCD] starts / cycle %d\n", (unsigned int)cycle ); 20 23 21 24 while (1) -
trunk/user/sort/sort.c
r435 r436 265 265 266 266 get_cycle( &cycle ); 267 printf("\n[SORT] completes barrier init at cycle %d continue ?\n", (unsigned int)cycle ); 268 getchar(); 267 printf("\n[SORT] completes barrier init at cycle %d\n", (unsigned int)cycle ); 269 268 270 269 // Array to sort initialization … … 356 355 { 357 356 printf("\n[SORT] failure at cycle %d\n", (unsigned int)cycle ); 358 exit( 0);357 exit( 1 ); 359 358 } 360 359
Note: See TracChangeset
for help on using the changeset viewer.