Changeset 669 for trunk/kernel/kern/ksocket.c
- Timestamp:
- Nov 19, 2020, 11:44:34 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/ksocket.c
r668 r669 34 34 #include <thread.h> 35 35 #include <vfs.h> 36 #include <alarm.h> 37 #include <dev_nic.h> 36 38 #include <ksocket.h> 37 #include <dev_nic.h>38 39 39 40 ////////////////////////////////////////////////////////////////////////////////////// … … 127 128 } 128 129 130 /////////////////////////////////////////////////////////////////////////////////////////// 131 // This static function implements the alarm handler used by a TX client thread to 132 // handle a retransmission timeout for a TX command (ACCEPT / CONNECT / CLOSE / SEND). 133 // The <args_xp> argument is actually an extended pointer on the involved socket. 134 // First, it updates the retransmission timeout. Then, it get the type of TX command, 135 // and request the NIC_TX server thread to re-send the unacknowledged segment. 136 /////////////////////////////////////////////////////////////////////////////////////////// 137 // @ args_xp : extended pointer on the involved socket. 138 /////////////////////////////////////////////////////////////////////////////////////////// 139 static void __attribute__((noinline)) socket_alarm_handler( xptr_t args_xp ) 140 { 141 // get cluster and local pointer on socket descriptor 142 socket_t * sock_ptr = GET_PTR( args_xp ); 143 cxy_t sock_cxy = GET_CXY( args_xp ); 144 145 // get relevant infos from socket descriptor 146 uint32_t tx_cmd = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_cmd )); 147 uint32_t channel = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->nic_channel )); 148 xptr_t thread_xp = hal_remote_l64( XPTR( sock_cxy , &sock_ptr->tx_client )); 149 150 assert( __FUNCTION__, (thread_xp != XPTR_NULL), 151 "illegal tx_client field for a retransmission timeout" ); 152 153 // get TX client thread cluster and local pointer 154 thread_t * thread_ptr = GET_PTR( thread_xp ); 155 cxy_t thread_cxy = GET_CXY( thread_xp ); 156 157 assert( __FUNCTION__, (thread_cxy == local_cxy), 158 "the client thread must be running in the same cluster as the alarm handler" ); 159 160 // get pointers on NIC_TX[index] chdev 161 xptr_t tx_chdev_xp = chdev_dir.nic_tx[channel]; 162 chdev_t * tx_chdev_ptr = GET_PTR( tx_chdev_xp ); 163 cxy_t tx_chdev_cxy = GET_CXY( tx_chdev_xp ); 164 165 // get pointers on NIC_TX[channel] server thread 166 thread_t * tx_server_ptr = hal_remote_lpt( XPTR( tx_chdev_cxy , &tx_chdev_ptr->server )); 167 xptr_t tx_server_xp = XPTR( tx_chdev_cxy , tx_server_ptr ); 168 169 // update the date in alarm 170 alarm_update( thread_ptr , hal_get_cycles() + TCP_RETRANSMISSION_TIMEOUT ); 171 172 ////////////////////////////// 173 if( tx_cmd == CMD_TX_CONNECT ) 174 { 175 176 #if DEBUG_SOCKET_ALARM 177 uint32_t cycle = (uint32_t)hal_get_cycles(); 178 printk("\n[%s] rings for TX_CONNECT : request a new SYN segment / cycle %d\n", 179 __FUNCTION__ , cycle ); 180 #endif 181 // set tx_valid to request the NIC_TX server to send a new SYN segment 182 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_valid ) , true ); 183 184 // update socket state 185 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->state ) , TCP_STATE_BOUND ); 186 187 // unblock the NIC_TX server thread 188 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 189 } 190 ///////////////////////////// 191 if( tx_cmd == CMD_TX_ACCEPT ) 192 { 193 194 #if DEBUG_SOCKET_ALARM 195 uint32_t cycle = (uint32_t)hal_get_cycles(); 196 printk("\n[%s] rings for TX_ACCEPT : request a new SYN-ACK segment / cycle %d\n", 197 __FUNCTION__ , cycle ); 198 #endif 199 // set tx_valid to request the NIC_TX server to send a new SYN-ACK segment 200 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_valid ) , true ); 201 202 // update socket state 203 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->state ) , TCP_STATE_SYN_RCVD ); 204 205 // unblock the NIC_TX server thread 206 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 207 } 208 //////////////////////////// 209 if( tx_cmd == CMD_TX_CLOSE ) 210 { 211 212 #if DEBUG_SOCKET_ALARM 213 uint32_t cycle = (uint32_t)hal_get_cycles(); 214 printk("\n[%s] rings for TX_CLOSE : request a new FIN-ACK segment / cycle %d\n", 215 __FUNCTION__ , cycle ); 216 #endif 217 // set tx_valid to request the NIC_TX server to send a new FIN-ACK segment 218 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_valid ) , true ); 219 220 // update socket state 221 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->state ) , TCP_STATE_ESTAB ); 222 223 // unblock the NIC_TX server thread 224 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 225 } 226 /////////////////////////// 227 if( tx_cmd == CMD_TX_SEND ) 228 { 229 // TODO build a new TX_SEND command 230 } 231 } // end socket_alarm_handler() 232 233 /////////////////////////////////////////////////////////////////////////////////////////// 234 // This static function activates the alarm embedded in the calling thread descriptor, 235 // using the <date> argument. 236 /////////////////////////////////////////////////////////////////////////////////////////// 237 // @ delay : number of cycles (from the current absolute date). 238 /////////////////////////////////////////////////////////////////////////////////////////// 239 static void socket_alarm_start( xptr_t socket_xp, 240 uint32_t delay ) 241 { 242 // compute absolute date 243 cycle_t date = hal_get_cycles() + delay; 244 245 // get pointer on calling threadf 246 thread_t * this = CURRENT_THREAD; 247 248 // start the alarm 249 alarm_start( date, 250 &socket_alarm_handler, // func_ptr 251 socket_xp, // args_xp 252 this ); 253 } 254 255 /////////////////////////////////////////////////////////////////////////////////////////// 256 // This static function activates the alarm embedded in the calling thread descriptor, 257 // using the <date> argument. 258 /////////////////////////////////////////////////////////////////////////////////////////// 259 // @ date : absolute date for this alarm. 260 /////////////////////////////////////////////////////////////////////////////////////////// 261 static void socket_alarm_stop( void ) 262 { 263 // get pointer on calling threadf 264 thread_t * this = CURRENT_THREAD; 265 266 // stop the alarm 267 alarm_stop( this ); 268 } 269 129 270 ///////////////////////////////////////////////////////////////////////////////////////// 130 271 // This static function registers the socket defined by the <socket_xp> argument into … … 222 363 223 364 // build various TX extended pointers 224 xptr_t tx_lock_xp = XPTR( tx_chdev_cxy , &tx_chdev_ptr->wait_lock ); 225 xptr_t tx_list_xp = XPTR( socket_cxy , &socket_ptr->tx_list ); 365 xptr_t tx_lock_xp = XPTR( tx_chdev_cxy , &tx_chdev_ptr->wait_lock ); 366 xptr_t tx_list_xp = XPTR( socket_cxy , &socket_ptr->tx_list ); 367 xptr_t tx_list_next = hal_remote_l64( tx_list_xp ); 368 xptr_t tx_list_pred = hal_remote_l64( tx_list_xp + sizeof(xptr_t) ); 226 369 227 370 // get pointers on NIC_RX[channel] chdev … … 231 374 232 375 // build various RX extended pointers 233 xptr_t rx_lock_xp = XPTR( rx_chdev_cxy , &rx_chdev_ptr->wait_lock ); 234 xptr_t rx_list_xp = XPTR( socket_cxy , &socket_ptr->rx_list ); 235 236 // remove socket from the NIC_TX[channel] chdev clients queue 237 remote_busylock_acquire( tx_lock_xp ); 238 xlist_unlink( tx_list_xp ); 239 remote_busylock_release( tx_lock_xp ); 240 241 // remove socket from the NIC_RX[channel] chdev clients queue 242 remote_busylock_acquire( rx_lock_xp ); 243 xlist_unlink( rx_list_xp ); 244 remote_busylock_release( rx_lock_xp ); 376 xptr_t rx_lock_xp = XPTR( rx_chdev_cxy , &rx_chdev_ptr->wait_lock ); 377 xptr_t rx_list_xp = XPTR( socket_cxy , &socket_ptr->rx_list ); 378 xptr_t rx_list_next = hal_remote_l64( rx_list_xp ); 379 xptr_t rx_list_pred = hal_remote_l64( rx_list_xp + sizeof(xptr_t) ); 380 381 // remove socket from the NIC_TX[channel] chdev clients queue if registered 382 if( (tx_list_next != XPTR_NULL) || (tx_list_pred != XPTR_NULL) ) 383 { 384 remote_busylock_acquire( tx_lock_xp ); 385 xlist_unlink( tx_list_xp ); 386 remote_busylock_release( tx_lock_xp ); 387 } 388 389 // remove socket from the NIC_RX[channel] chdev clients queue if registered 390 if( (rx_list_next != XPTR_NULL) || (rx_list_pred != XPTR_NULL) ) 391 { 392 remote_busylock_acquire( rx_lock_xp ); 393 xlist_unlink( rx_list_xp ); 394 remote_busylock_release( rx_lock_xp ); 395 } 245 396 246 397 #if DEBUG_SOCKET_LINK … … 253 404 } // end socket_unlink_from_servers() 254 405 406 ///////////////////////////////////////////////////////////////////////////////////////// 407 // This function registers the socket defined by the <socket_xp> argument into the 408 // list of listening sockets rooted in the nic_rx[0] chdev. 409 ///////////////////////////////////////////////////////////////////////////////////////// 410 // @ socket_xp : [in] extended pointer on socket descriptor 411 ///////////////////////////////////////////////////////////////////////////////////////// 412 static void socket_link_to_listen( xptr_t socket_xp ) 413 { 414 // get socket cluster and local pointer 415 socket_t * socket_ptr = GET_PTR( socket_xp ); 416 cxy_t socket_cxy = GET_CXY( socket_xp ); 417 418 // get pointers on NIC_RX[0] chdev 419 xptr_t rx0_chdev_xp = chdev_dir.nic_rx[0]; 420 chdev_t * rx0_chdev_ptr = GET_PTR( rx0_chdev_xp ); 421 cxy_t rx0_chdev_cxy = GET_CXY( rx0_chdev_xp ); 422 423 // build extended pointers on list of listening sockets 424 xptr_t rx0_root_xp = XPTR( rx0_chdev_cxy , &rx0_chdev_ptr->ext.nic.root ); 425 xptr_t rx0_lock_xp = XPTR( rx0_chdev_cxy , &rx0_chdev_ptr->ext.nic.lock ); 426 427 // build extended pointer on socket rx_list field 428 xptr_t list_entry_xp = XPTR( socket_cxy , &socket_ptr->rx_list ); 429 430 // register socket in listening sockets list 431 remote_busylock_acquire( rx0_lock_xp ); 432 xlist_add_last( rx0_root_xp , list_entry_xp ); 433 remote_busylock_release( rx0_lock_xp ); 434 435 } // end socket_link_to_listen() 436 437 ///////////////////////////////////////////////////////////////////////////////////////// 438 // This function removes the socket defined by the <socket_xp> argument from the 439 // list of listening sockets rooted in the nic_rx[0] chdev. 440 ///////////////////////////////////////////////////////////////////////////////////////// 441 // @ socket_xp : [in] extended pointer on socket descriptor 442 ///////////////////////////////////////////////////////////////////////////////////////// 443 static void socket_unlink_from_listen( xptr_t socket_xp ) 444 { 445 // get socket cluster and local pointer 446 socket_t * socket_ptr = GET_PTR( socket_xp ); 447 cxy_t socket_cxy = GET_CXY( socket_xp ); 448 449 // get pointers on NIC_RX[0] chdev 450 xptr_t rx0_chdev_xp = chdev_dir.nic_rx[0]; 451 chdev_t * rx0_chdev_ptr = GET_PTR( rx0_chdev_xp ); 452 cxy_t rx0_chdev_cxy = GET_CXY( rx0_chdev_xp ); 453 454 // build extended pointers on lock protecting list of listening sockets 455 xptr_t rx0_lock_xp = XPTR( rx0_chdev_cxy , &rx0_chdev_ptr->ext.nic.lock ); 456 457 // build extended pointer on socket rx_list field 458 xptr_t list_entry_xp = XPTR( socket_cxy , &socket_ptr->rx_list ); 459 460 // register socket in listening sockets list 461 remote_busylock_acquire( rx0_lock_xp ); 462 xlist_unlink( list_entry_xp ); 463 remote_busylock_release( rx0_lock_xp ); 464 465 } // end socket_unlink_from_listen() 466 255 467 ///////////////////////////////////////////////////////////////////////////////////////// 256 468 // This static function is called by the socket_build() and socket_accept() functions. … … 276 488 uint32_t * fdid_ptr ) 277 489 { 278 uint32_t fdid; 279 280 thread_t * this = CURRENT_THREAD; 281 process_t * process = this->process; 282 490 uint32_t fdid; 283 491 kmem_req_t req; 284 492 socket_t * socket; … … 287 495 error_t error; 288 496 497 thread_t * this = CURRENT_THREAD; 498 process_t * process = this->process; 499 289 500 #if DEBUG_SOCKET_CREATE 290 501 uint32_t cycle = (uint32_t)hal_get_cycles(); … … 294 505 #endif 295 506 296 // allocate memory for socket descriptor507 // 1. allocate memory for socket descriptor 297 508 req.type = KMEM_KCM; 298 509 req.order = bits_log2( sizeof(socket_t) ); … … 307 518 } 308 519 309 // allocate memory for rx_buf buffer520 // 2. allocate memory for rx_buf buffer 310 521 error = remote_buf_init( XPTR( cxy , &socket->rx_buf ), 311 NIC_RX_BUF_SIZE);522 bits_log2( CONFIG_SOCK_RX_BUF_SIZE ) ); 312 523 313 524 if( error ) … … 321 532 } 322 533 323 // allocate memory for r2tq queue534 // 3. allocate memory for r2tq queue 324 535 error = remote_buf_init( XPTR( cxy , &socket->r2tq ), 325 NIC_R2T_QUEUE_SIZE);536 bits_log2( CONFIG_SOCK_R2T_BUF_SIZE ) ); 326 537 if( error ) 327 538 { 328 539 printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x]\n", 329 540 __FUNCTION__, process->pid, this->trdid ); 330 remote_buf_ destroy( XPTR( cxy , &socket->rx_buf ) );541 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 331 542 req.type = KMEM_KCM; 332 543 req.ptr = socket; … … 337 548 // don't allocate memory for crqq queue, as it is done by the socket_listen function 338 549 339 // allocate memory for file descriptor550 // 4. allocate memory for file descriptor 340 551 req.type = KMEM_KCM; 341 552 req.order = bits_log2( sizeof(vfs_file_t) ); … … 347 558 printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x]\n", 348 559 __FUNCTION__, process->pid, this->trdid ); 349 remote_buf_ destroy( XPTR( cxy , &socket->r2tq ) );350 remote_buf_ destroy( XPTR( cxy , &socket->rx_buf ) );560 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); 561 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 351 562 req.type = KMEM_KCM; 352 563 req.ptr = socket; … … 355 566 } 356 567 357 // get an fdid value, and register file descriptor in fd_array[]568 // 5. get an fdid value, and register file descriptor in fd_array[] 358 569 error = process_fd_register( process->ref_xp, 359 570 XPTR( cxy , file ), … … 366 577 req.ptr = file; 367 578 kmem_free( &req ); 368 remote_buf_ destroy( XPTR( cxy , &socket->r2tq ) );369 remote_buf_ destroy( XPTR( cxy , &socket->rx_buf ) );579 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); 580 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 370 581 req.ptr = socket; 371 582 kmem_free( &req ); … … 388 599 389 600 // initialize file descriptor 390 hal_remote_s32( XPTR( cxy , &file->type ) , INODE_TYPE_SOCK );601 hal_remote_s32( XPTR( cxy , &file->type ) , FILE_TYPE_SOCK ); 391 602 hal_remote_spt( XPTR( cxy , &file->socket ) , socket ); 392 hal_remote_s32( XPTR( cxy , &file->refcount ) , 1 );393 603 394 604 // initialize socket lock … … 414 624 // It remove the associated file from the reference process fd_array. It unlink the 415 625 // socket from the NIC_TX [k] and NIC_RX[k] chdevs. It release all memory allocated 416 // for the structures associated to the target socket socket : file descriptor,417 // socketdescriptor, RX buffer, R2T queue, CRQ queue.626 // for the structures associated to the target socket : file descriptor, socket 627 // descriptor, RX buffer, R2T queue, CRQ queue. 418 628 ///////////////////////////////////////////////////////////////////////////////////////// 419 629 // @ file_xp : extended pointer on the file descriptor. … … 427 637 428 638 // check file_xp argument 429 assert( (file_xp != XPTR_NULL), "illegal argument\n" );639 assert( __FUNCTION__, (file_xp != XPTR_NULL), "illegal argument\n" ); 430 640 431 641 // get cluster & local pointer for file descriptor 432 642 vfs_file_t * file_ptr = GET_PTR( file_xp ); 433 643 cxy_t file_cxy = GET_CXY( file_xp ); 434 435 #if DEBUG_SOCKET_DESTROY436 uint32_t cycle = (uint32_t)hal_get_cycles();437 if( DEBUG_SOCKET_DESTROY < cycle )438 printk("\n[%s] thread[%x,%x] enter / file[%x,%x] / cycle %d\n",439 __FUNCTION__, process->pid, this->trdid, file_cxy, file_ptr, cycle );440 #endif441 644 442 645 // get local pointer for socket and file type … … 445 648 446 649 // check file descriptor type 447 assert( (file_type == INODE_TYPE_SOCK), "illegal file type\n" );448 449 // get socket nic_channel and fdid450 uint32_t channel = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel));650 assert( __FUNCTION__, (file_type == FILE_TYPE_SOCK), "illegal file type\n" ); 651 652 // get socket nic_channel, state, pid and fdid 653 uint32_t state = hal_remote_l32( XPTR( file_cxy , &socket_ptr->state )); 451 654 uint32_t fdid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->fdid )); 452 453 // remove socket from NIC_TX & NIC_RX chdev queues when socket is connected 454 if( channel < LOCAL_CLUSTER->nb_nic_channels ) 655 656 #if DEBUG_SOCKET_DESTROY 657 uint32_t cycle = (uint32_t)hal_get_cycles(); 658 pid_t pid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->pid )); 659 if( DEBUG_SOCKET_DESTROY < cycle ) 660 printk("\n[%s] thread[%x,%x] enter / file[%x,%x] / cycle %d\n", 661 __FUNCTION__, process->pid, this->trdid, pid, fdid, cycle ); 662 #endif 663 664 // remove socket from NIC_TX & NIC_RX chdev queues 665 // or from the listening sockets list 666 if( state == TCP_STATE_LISTEN ) 667 { 668 socket_unlink_from_listen( XPTR( file_cxy , socket_ptr ) ); 669 } 670 else 455 671 { 456 672 socket_unlink_from_servers( XPTR( file_cxy , socket_ptr ) ); … … 466 682 467 683 // release memory allocated for buffers attached to socket descriptor 468 remote_buf_ destroy( XPTR( file_cxy , &socket_ptr->crqq ) );469 remote_buf_ destroy( XPTR( file_cxy , &socket_ptr->r2tq ) );470 remote_buf_ destroy( XPTR( file_cxy , &socket_ptr->rx_buf ) );684 remote_buf_release_data( XPTR( file_cxy , &socket_ptr->crqq ) ); 685 remote_buf_release_data( XPTR( file_cxy , &socket_ptr->r2tq ) ); 686 remote_buf_release_data( XPTR( file_cxy , &socket_ptr->rx_buf ) ); 471 687 472 688 // release memory allocated for socket descriptor … … 619 835 uint16_t port ) 620 836 { 621 vfs_ inode_type_t file_type;837 vfs_file_type_t file_type; 622 838 socket_t * socket; 623 839 uint32_t socket_type; … … 651 867 652 868 // check file descriptor type 653 if( file_type != INODE_TYPE_SOCK )869 if( file_type != FILE_TYPE_SOCK ) 654 870 { 655 871 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]", … … 691 907 vfs_file_t * file_ptr; 692 908 cxy_t file_cxy; 693 vfs_ inode_type_t file_type;909 vfs_file_type_t file_type; 694 910 socket_t * socket_ptr; 695 911 uint32_t socket_type; … … 726 942 727 943 // check file descriptor type 728 if( file_type != INODE_TYPE_SOCK )944 if( file_type != FILE_TYPE_SOCK ) 729 945 { 730 946 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n", … … 733 949 } 734 950 735 // get relevant infos from <fdid>socket descriptor951 // get relevant infos from socket descriptor 736 952 socket_type = hal_remote_l32( XPTR( file_cxy , &socket_ptr->type )); 737 953 socket_state = hal_remote_l32( XPTR( file_cxy , &socket_ptr->state )); … … 755 971 } 756 972 757 // compute CRQ queue depth : max( crq_depth , NIC_CRQ_QUEUE_SIZE ) 758 uint32_t depth = ( crq_depth > NIC_CRQ_QUEUE_SIZE ) ? crq_depth : NIC_CRQ_QUEUE_SIZE; 973 // compute CRQ queue depth : max( crq_depth , CONFIG_SOCK_CRQ_BUF_SIZE ) 974 uint32_t depth = ( crq_depth > CONFIG_SOCK_CRQ_BUF_SIZE ) ? 975 crq_depth : CONFIG_SOCK_CRQ_BUF_SIZE; 759 976 760 977 // allocate memory for the CRQ queue 761 978 error = remote_buf_init( XPTR( file_cxy , &socket_ptr->crqq ), 762 depth * sizeof(connect_request_t) );979 bits_log2( depth * sizeof(connect_request_t)) ); 763 980 if( error ) 764 981 { … … 771 988 hal_remote_s32( XPTR( file_cxy , &socket_ptr->state ) , TCP_STATE_LISTEN ); 772 989 773 // get pointers on NIC_RX[0] chdev 774 xptr_t rx0_chdev_xp = chdev_dir.nic_rx[0]; 775 chdev_t * rx0_chdev_ptr = GET_PTR( rx0_chdev_xp ); 776 cxy_t rx0_chdev_cxy = GET_CXY( rx0_chdev_xp ); 777 778 // build extended pointers on list of listening sockets 779 xptr_t rx0_root_xp = XPTR( rx0_chdev_cxy , &rx0_chdev_ptr->ext.nic.root ); 780 xptr_t rx0_lock_xp = XPTR( rx0_chdev_cxy , &rx0_chdev_ptr->ext.nic.lock ); 781 782 // build extended pointer on socket rx_list field 783 xptr_t list_entry_xp = XPTR( file_cxy , &socket_ptr->rx_list ); 784 785 // register <fdid> socket in listening sockets list 786 remote_busylock_acquire( rx0_lock_xp ); 787 xlist_add_last( rx0_root_xp , list_entry_xp ); 788 remote_busylock_release( rx0_lock_xp ); 990 // register socket in the list of listening socket 991 socket_link_to_listen( XPTR( file_cxy , socket_ptr ) ); 789 992 790 993 #if DEBUG_SOCKET_LISTEN … … 808 1011 vfs_file_t * file_ptr; 809 1012 cxy_t file_cxy; 810 vfs_ inode_type_t file_type; // file descriptor type1013 vfs_file_type_t file_type; // file descriptor type 811 1014 socket_t * socket_ptr; // local pointer on remote waiting socket 812 1015 uint32_t socket_type; // listening socket type … … 866 1069 867 1070 // check file descriptor type 868 if( file_type != INODE_TYPE_SOCK )1071 if( file_type != FILE_TYPE_SOCK ) 869 1072 { 870 1073 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n", … … 976 1179 crq_status = remote_buf_status( crq_xp ); 977 1180 978 assert( (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)),1181 assert( __FUNCTION__, (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)), 979 1182 "illegal socket state when client thread resumes after RX_ACCEPT" ); 980 1183 … … 999 1202 &new_remote_window ); 1000 1203 1001 assert( (error == 0),1204 assert( __FUNCTION__, (error == 0), 1002 1205 "cannot get a connection request from a non-empty CRQ" ); 1003 1206 … … 1082 1285 // unblock NIC_TX server thread 1083 1286 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 1084 1287 1288 // start retransmission timer 1289 socket_alarm_start( new_socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1290 1085 1291 #if DEBUG_SOCKET_ACCEPT 1086 1292 cycle = (uint32_t)hal_get_cycles(); … … 1100 1306 __FUNCTION__, process->pid, this->trdid, process->pid, new_fdid, cycle ); 1101 1307 #endif 1308 1309 // stop retransmission timer 1310 socket_alarm_stop(); 1102 1311 1103 1312 // get new socket state, tx_valid and tx_sts … … 1106 1315 cmd_status = hal_remote_l32( XPTR( new_socket_cxy , &new_socket_ptr->tx_sts )); 1107 1316 1108 assert( (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))1317 assert( __FUNCTION__, (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS)) 1109 1318 && (cmd_valid == false)), 1110 1319 "illegal socket state when client thread resumes after TX_ACCEPT" ); … … 1143 1352 uint16_t remote_port ) 1144 1353 { 1145 vfs_inode_type_t file_type; 1146 socket_t * socket_ptr; // local pointer on thread descriptor 1354 vfs_file_type_t file_type; 1355 xptr_t socket_xp; // extended pointer on socket descriptor 1356 socket_t * socket_ptr; // local pointer on socket descriptor 1147 1357 volatile uint32_t socket_state; // socket state (modified by the NIC_TX thread) 1148 1358 uint32_t socket_type; // socket type … … 1175 1385 file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) ); 1176 1386 socket_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->socket ) ); 1387 socket_xp = XPTR( file_cxy , socket_ptr ); 1177 1388 1178 1389 #if DEBUG_SOCKET_CONNECT … … 1184 1395 1185 1396 // check file descriptor type 1186 if( file_type != INODE_TYPE_SOCK )1397 if( file_type != FILE_TYPE_SOCK ) 1187 1398 { 1188 1399 printk("\n[ERROR] in %s : illegal file type %s", … … 1263 1474 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 1264 1475 1476 // start retransmission timer 1477 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1478 1265 1479 #if DEBUG_SOCKET_CONNECT 1266 1480 cycle = (uint32_t)hal_get_cycles(); … … 1279 1493 __FUNCTION__, pid, trdid, pid, fdid, cycle ); 1280 1494 #endif 1495 1496 // stop retransmission timer 1497 socket_alarm_stop(); 1281 1498 1282 1499 // get socket state, tx_valid and tx_sts … … 1285 1502 socket_state = hal_remote_l32( XPTR( file_cxy , &socket_ptr->state )); 1286 1503 1287 assert( (((socket_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))1504 assert( __FUNCTION__, (((socket_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS)) 1288 1505 && (cmd_valid == false)), 1289 1506 "illegal socket state when client thread resumes after TX_CONNECT" ); … … 1331 1548 trdid_t trdid = this->trdid; 1332 1549 1333 // get pointer on socket descriptor1334 cxy_t file_cxy 1335 vfs_file_t * file_ptr 1550 // get pointers on socket descriptor 1551 cxy_t file_cxy = GET_CXY( file_xp ); 1552 vfs_file_t * file_ptr = GET_PTR( file_xp ); 1336 1553 socket_t * socket_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->socket ) ); 1337 1338 assert( (hal_remote_l32( XPTR( file_cxy , &socket_ptr->fdid )) == fdid), 1554 xptr_t socket_xp = XPTR( file_cxy , socket_ptr ); 1555 1556 assert( __FUNCTION__, (hal_remote_l32( XPTR( file_cxy , &socket_ptr->fdid )) == fdid), 1339 1557 "unconsistent file_xp & fdid arguments"); 1340 1558 … … 1380 1598 cycle = (uint32_t)hal_get_cycles(); 1381 1599 if( cycle > DEBUG_DEV_NIC_TX ) 1382 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s /destroy socket / cycle %d\n",1600 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s => directly destroy socket / cycle %d\n", 1383 1601 __FUNCTION__, pid, trdid, pid, fdid, socket_state_str( socket_state ), cycle ); 1384 1602 #endif … … 1396 1614 cycle = (uint32_t)hal_get_cycles(); 1397 1615 if( cycle > DEBUG_DEV_NIC_TX ) 1398 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s /destroy socket / cycle %d\n",1616 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s => directly destroy socket / cycle %d\n", 1399 1617 __FUNCTION__, pid, trdid, pid, fdid, socket_state_str( socket_state ), cycle ); 1400 1618 #endif … … 1420 1638 hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_valid ), true ); 1421 1639 1640 // release socket lock 1641 remote_queuelock_release( socket_lock_xp ); 1642 1422 1643 // unblock NIC_TX server thread 1423 1644 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 1424 1425 // release socket lock1426 remote_queuelock_release( socket_lock_xp);1645 1646 // start retransmission timer 1647 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1427 1648 1428 1649 #if DEBUG_SOCKET_CLOSE 1429 1650 cycle = (uint32_t)hal_get_cycles(); 1430 1651 if( DEBUG_SOCKET_CLOSE < cycle ) 1431 printk("\n[%s] thread[%x,%x] socket[%x,%d] blocks on <IO> waiting close / cycle %d \n",1432 __FUNCTION__, pid, trdid, pid, fdid, cycle );1433 #endif 1434 // block itself and deschedule1652 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s => blocks on <IO> waiting close / cycle %d \n", 1653 __FUNCTION__, pid, trdid, pid, fdid, socket_state_str( socket_state ), cycle ); 1654 #endif 1655 // client thread block itself and deschedule 1435 1656 thread_block( client_xp , THREAD_BLOCKED_IO ); 1436 1657 sched_yield( "blocked in close" ); … … 1442 1663 __FUNCTION__, pid, trdid, pid, fdid, cycle ); 1443 1664 #endif 1665 // stop retransmission timer 1666 socket_alarm_stop(); 1667 1444 1668 // take socket lock 1445 1669 remote_queuelock_acquire( socket_lock_xp ); … … 1450 1674 cmd_valid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid ) ); 1451 1675 1452 assert( (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS))1676 assert( __FUNCTION__, (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS)) 1453 1677 && (cmd_valid == false)), 1454 1678 "illegal socket state when client thread resumes after TX_CLOSE\n" … … 1483 1707 1484 1708 //////////////////////////////////////////////////////////////////////////////////////// 1485 // This static and blocking function is executed by an user thread calling one of the 1486 // four functions: socket_send() / socket_recv() / socket_sendto() / socket_recvfrom() 1709 // This static function is called by the two functions socket_send() & socket_recv(). 1487 1710 // It can be used for both UDP and TCP sockets. 1488 1711 //////////////////////////////////////////////////////////////////////////////////////// … … 1491 1714 // @ u_buf : pointer on user buffer in user space. 1492 1715 // @ length : number of bytes. 1493 // @ explicit : explicit remote IP address and port when true.1494 1716 //////////////////////////////////////////////////////////////////////////////////////// 1495 1717 // Implementation note : The behavior is different for SEND & RECV … … 1512 1734 uint32_t fdid, 1513 1735 uint8_t * u_buf, 1514 uint32_t length, 1515 bool_t explicit, 1516 uint32_t explicit_addr, 1517 uint32_t explicit_port ) 1518 { 1519 vfs_inode_type_t file_type; // file descriptor type 1736 uint32_t length ) 1737 { 1738 vfs_file_type_t file_type; // file descriptor type 1739 xptr_t socket_xp; // extended pointer on socket descriptor 1520 1740 socket_t * socket_ptr; // local pointer on socket descriptor 1521 1741 uint32_t socket_state; // current socket state … … 1529 1749 chdev_t * chdev_ptr; 1530 1750 cxy_t chdev_cxy; 1531 uint32_t remote_addr;1532 uint32_t remote_port;1533 1751 uint32_t buf_status; // number of bytes in rx_buf 1534 1752 int32_t moved_bytes; // total number of moved bytes (fot return) … … 1562 1780 file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) ); 1563 1781 1564 // get local pointeron socket1782 // get pointers on socket 1565 1783 socket_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->socket ) ); 1784 socket_xp = XPTR( file_cxy , socket_ptr ); 1566 1785 1567 1786 // check file descriptor type 1568 if( file_type != INODE_TYPE_SOCK )1787 if( file_type != FILE_TYPE_SOCK ) 1569 1788 { 1570 1789 printk("\n[ERROR] in %s : illegal file type %s / socket[%x,%d]\n", … … 1584 1803 nic_channel = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel )); 1585 1804 1586 // handle the explicit remote address and port 1587 if( socket_type == SOCK_DGRAM ) // UDP socket 1588 { 1589 if( socket_state == UDP_STATE_UNBOUND ) 1590 { 1591 // release socket lock 1592 remote_queuelock_release( socket_lock_xp ); 1593 1594 printk("\n[ERROR] in %s : SEND/RECV for socket[%x,%d] in state %s\n", 1595 __FUNCTION__, process->pid, fdid, socket_state_str(socket_state) ); 1596 return -1; 1597 } 1598 1599 if( explicit ) 1600 { 1601 // update remote IP address and port into socket descriptor 1602 hal_remote_s32( XPTR( file_cxy , &socket_ptr->remote_addr ), explicit_addr ); 1603 hal_remote_s32( XPTR( file_cxy , &socket_ptr->remote_port ), explicit_port ); 1604 1605 // update socket state if required 1606 if( socket_state == UDP_STATE_BOUND ) 1607 { 1608 hal_remote_s32( XPTR( file_cxy , &socket_ptr->state ), UDP_STATE_ESTAB ); 1609 } 1610 } 1611 } 1612 else // TCP socket 1613 { 1614 if( explicit ) 1615 { 1616 // get remote IP address and port from socket descriptor 1617 remote_addr = hal_remote_l32( XPTR( file_cxy , &socket_ptr->remote_addr )); 1618 remote_port = hal_remote_l32( XPTR( file_cxy , &socket_ptr->remote_port )); 1619 1620 if( (remote_addr != explicit_addr) || (remote_port != explicit_port) ) 1621 { 1622 // release socket lock 1623 remote_queuelock_release( socket_lock_xp ); 1624 1625 printk("\n[ERROR] in %s : wrong expliciy access for socket[%x,%d]\n", 1626 __FUNCTION__, process->pid, fdid ); 1627 return -1; 1628 } 1629 } 1630 } 1631 1632 /////////////////////////////////////////////////////// 1633 if( is_send ) // TX_SEND command 1805 ///////////// 1806 if( is_send ) // SEND command 1634 1807 { 1635 1808 … … 1696 1869 thread_unblock( server_xp , THREAD_BLOCKED_CLIENT ); 1697 1870 1871 // start retransmission timer 1872 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1873 1698 1874 #if DEBUG_SOCKET_SEND 1699 1875 cycle = (uint32_t)hal_get_cycles(); … … 1712 1888 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle ); 1713 1889 #endif 1890 // stop retransmission timer 1891 socket_alarm_stop(); 1892 1714 1893 // take socket lock 1715 1894 remote_queuelock_acquire( socket_lock_xp ); … … 1727 1906 1728 1907 // check SEND command completed when TX client thread resumes 1729 assert( (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),1908 assert( __FUNCTION__, (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 1730 1909 "illegal socket state when client thread resumes after TX_SEND\n" 1731 1910 " tx_todo = %d / tx_status = %d / tx_valid = %d\n", … … 1759 1938 } 1760 1939 1761 } // end TX_SEND command1762 1763 //// ////////////////////////////////////////////////////1764 else // R X_RECV command1940 } // end SEND command 1941 1942 //// 1943 else // RECV command 1765 1944 { 1766 1945 … … 1837 2016 buf_status = remote_buf_status( rx_buf_xp ); 1838 2017 1839 assert( (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),2018 assert( __FUNCTION__, (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 1840 2019 "illegal socket state when client thread resumes after RX_RECV\n" 1841 2020 " buf_status = %d / rx_sts = %d / rx_valid = %d\n", … … 1891 2070 return moved_bytes; 1892 2071 1893 } // end R X_RECV command2072 } // end RECV command 1894 2073 } // end socket_move_data() 1895 1896 2074 1897 2075 /////////////////////////////////// … … 1900 2078 uint32_t length ) 1901 2079 { 1902 int nbytes = socket_move_data( true, // SEND 1903 fdid, 1904 u_buf, 1905 length, 1906 false, 0, 0 ); // no explicit remote socket 1907 return nbytes; 1908 2080 return socket_move_data( true, // SEND 2081 fdid, 2082 u_buf, 2083 length ); 1909 2084 } // end socket_send() 1910 1911 /////////////////////////////////////1912 int socket_sendto( uint32_t fdid,1913 uint8_t * u_buf,1914 uint32_t length,1915 uint32_t remote_addr,1916 uint32_t remote_port )1917 {1918 int nbytes = socket_move_data( true, // SEND1919 fdid,1920 u_buf,1921 length,1922 true, // explicit remote socket1923 remote_addr,1924 remote_port );1925 return nbytes;1926 1927 } // end socket_sendto()1928 2085 1929 2086 /////////////////////////////////// … … 1932 2089 uint32_t length ) 1933 2090 { 1934 int nbytes = socket_move_data( false, // RECV 1935 fdid, 1936 u_buf, 1937 length, 1938 false, 0, 0 ); // no explicit remote socket 1939 return nbytes; 1940 2091 return socket_move_data( false, // RECV 2092 fdid, 2093 u_buf, 2094 length ); 1941 2095 } // end socket_recv() 1942 1943 1944 ///////////////////////////////////////1945 int socket_recvfrom( uint32_t fdid,1946 uint8_t * u_buf,1947 uint32_t length,1948 uint32_t remote_addr,1949 uint32_t remote_port )1950 {1951 int nbytes = socket_move_data( false, // RECV1952 fdid,1953 u_buf,1954 length,1955 true, // explicit remote socket1956 remote_addr,1957 remote_port );1958 return nbytes;1959 1960 } // end socket_recvfrom()1961 2096 1962 2097 ////////////////////////////////////////////
Note: See TracChangeset
for help on using the changeset viewer.