Changeset 683 for trunk/kernel/kern/ksocket.c
- Timestamp:
- Jan 13, 2021, 12:36:17 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/ksocket.c
r669 r683 1 1 /* 2 * ksocket.c - kernel socket APIimplementation.2 * ksocket.c - kernel socket implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018,2019,2020)4 * Authors Alain Greiner (2016,2017,2018,2019,2020) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 117 117 switch( sts ) 118 118 { 119 case CMD_STS_SUCCESS : return " TX_CONNECT";119 case CMD_STS_SUCCESS : return "SUCCESS"; 120 120 case CMD_STS_EOF : return "EOF"; 121 121 case CMD_STS_RST : return "RST"; … … 135 135 // and request the NIC_TX server thread to re-send the unacknowledged segment. 136 136 /////////////////////////////////////////////////////////////////////////////////////////// 137 // @ args_xp : extended pointer on the involved socket.137 // @ sock_xp : extended pointer on the involved socket. 138 138 /////////////////////////////////////////////////////////////////////////////////////////// 139 static void __attribute__((noinline)) socket_alarm_handler( xptr_t args_xp )139 static void __attribute__((noinline)) socket_alarm_handler( xptr_t sock_xp ) 140 140 { 141 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 ); 142 socket_t * sock_ptr = GET_PTR( sock_xp ); 143 cxy_t sock_cxy = GET_CXY( sock_xp ); 144 145 #if DEBUG_SOCKET_ALARM 146 uint32_t cycle = (uint32_t)hal_get_cycles(); 147 #endif 148 149 // build extended pointer on lock protecting socket 150 xptr_t socket_lock_xp = XPTR( sock_cxy , &sock_ptr->lock ); 151 152 // take the socket lock 153 remote_queuelock_acquire( socket_lock_xp ); 144 154 145 155 // get relevant infos from socket descriptor … … 151 161 "illegal tx_client field for a retransmission timeout" ); 152 162 153 // get TX client thread cluster and local pointer 154 thread_t * thread_ptr = GET_PTR( thread_xp ); 163 // get TX client thread cluster 155 164 cxy_t thread_cxy = GET_CXY( thread_xp ); 156 165 … … 168 177 169 178 // update the date in alarm 170 alarm_update( thread_ ptr , hal_get_cycles() + TCP_RETRANSMISSION_TIMEOUT );179 alarm_update( thread_xp , hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT ); 171 180 172 181 ////////////////////////////// … … 175 184 176 185 #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",186 if( DEBUG_SOCKET_ALARM < cycle ) 187 printk("\n[%s] rings for CONNECT : request a new SYN segment / cycle %d\n", 179 188 __FUNCTION__ , cycle ); 180 189 #endif … … 193 202 194 203 #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",204 if( DEBUG_SOCKET_ALARM < cycle ) 205 printk("\n[%s] rings for ACCEPT : request a new SYN-ACK segment / cycle %d\n", 197 206 __FUNCTION__ , cycle ); 198 207 #endif … … 211 220 212 221 #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",222 if( DEBUG_SOCKET_ALARM < cycle ) 223 printk("\n[%s] rings for CLOSE : request a new FIN-ACK segment / cycle %d\n", 215 224 __FUNCTION__ , cycle ); 216 225 #endif … … 227 236 if( tx_cmd == CMD_TX_SEND ) 228 237 { 229 // TODO build a new TX_SEND command 230 } 238 // get get relevant infos from socket pointer 239 uint32_t tx_una = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_una )); 240 uint32_t tx_ack = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_ack )); 241 uint32_t tx_len = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_len )); 242 243 #if DEBUG_SOCKET_ALARM 244 if( DEBUG_SOCKET_ALARM < cycle ) 245 printk("\n[%s] rings for SEND : request %d bytes / cycle %d\n", 246 __FUNCTION__ , tx_len , cycle ); 247 #endif 248 // update command fields in socket 249 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_nxt ) , tx_una ); 250 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_todo ) , tx_len - tx_ack ); 251 hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_valid ) , true ); 252 253 // unblock the NIC_TX server thread 254 thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT ); 255 } 256 257 // release the socket lock 258 remote_queuelock_release( socket_lock_xp ); 259 231 260 } // 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 date243 cycle_t date = hal_get_cycles() + delay;244 245 // get pointer on calling threadf246 thread_t * this = CURRENT_THREAD;247 248 // start the alarm249 alarm_start( date,250 &socket_alarm_handler, // func_ptr251 socket_xp, // args_xp252 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 threadf264 thread_t * this = CURRENT_THREAD;265 266 // stop the alarm267 alarm_stop( this );268 }269 261 270 262 ///////////////////////////////////////////////////////////////////////////////////////// … … 470 462 // associated to a socket: file descriptor, socket descriptor, RX buffer, R2T queue, 471 463 // and CRQ queue. It allocates an fdid, and register it in the process fd_array. 472 // It initialise the thesocket desccriptor static fields, other than local_addr,464 // It initialise the socket desccriptor static fields, other than local_addr, 473 465 // local_port, remote_addr, remote_port), and set the socket state to UNBOUND. 474 466 // It returns the local pointer on socket descriptor and the fdid value in buffers … … 489 481 { 490 482 uint32_t fdid; 491 kmem_req_t req;492 483 socket_t * socket; 493 484 vfs_file_t * file; 494 485 uint32_t state; 486 void * tx_buf; 495 487 error_t error; 488 496 489 497 490 thread_t * this = CURRENT_THREAD; 498 491 process_t * process = this->process; 499 492 493 #if DEBUG_SOCKET_CREATE || DEBUG_SOCKET_ERROR 494 uint32_t cycle = (uint32_t)hal_get_cycles(); 495 #endif 496 500 497 #if DEBUG_SOCKET_CREATE 501 uint32_t cycle = (uint32_t)hal_get_cycles();502 498 if( DEBUG_SOCKET_CREATE < cycle ) 503 499 printk("\n[%s] thread[%x,%x] enter / cycle %d\n", … … 506 502 507 503 // 1. allocate memory for socket descriptor 508 req.type = KMEM_KCM; 509 req.order = bits_log2( sizeof(socket_t) ); 510 req.flags = AF_ZERO; 511 socket = kmem_remote_alloc( cxy , &req ); 504 socket = kmem_remote_alloc( cxy , bits_log2(sizeof(socket_t)) , AF_ZERO ); 512 505 513 506 if( socket == NULL ) 514 507 { 515 printk("\n[ERROR] in %s : cannot allocate socket descriptor / thread[%x,%x]\n", 516 __FUNCTION__, process->pid, this->trdid ); 517 return -1; 518 } 519 520 // 2. allocate memory for rx_buf buffer 508 509 #if DEBUG_SOCKET_ERROR 510 printk("\n[ERROR] in %s : cannot allocate socket descriptor / thread[%x,%x] / cycle %d\n", 511 __FUNCTION__, process->pid, this->trdid, cycle ); 512 #endif 513 return -1; 514 } 515 516 // 2. allocate memory for rx_buf data buffer 521 517 error = remote_buf_init( XPTR( cxy , &socket->rx_buf ), 522 bits_log2( CONFIG_SOCK_RX_BUF_SIZE ));518 CONFIG_SOCK_RX_BUF_ORDER ); 523 519 524 520 if( error ) 525 521 { 526 printk("\n[ERROR] in %s : cannot allocate rx_buf / thread[%x,%x]\n", 527 __FUNCTION__, process->pid, this->trdid ); 528 req.type = KMEM_KCM; 529 req.ptr = socket; 530 kmem_remote_free( cxy , &req ); 531 return -1; 532 } 533 534 // 3. allocate memory for r2tq queue 522 523 #if DEBUG_SOCKET_ERROR 524 printk("\n[ERROR] in %s : no memory for rx_buf / thread[%x,%x] / cycle %d\n", 525 __FUNCTION__, process->pid, this->trdid, cycle ); 526 #endif 527 kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) ); // 1 528 return -1; 529 } 530 531 // 3. allocate memory for tx_buf 532 tx_buf = kmem_remote_alloc( cxy , CONFIG_SOCK_TX_BUF_ORDER , AF_NONE ); 533 534 if( tx_buf == NULL ) 535 { 536 537 #if DEBUG_SOCKET_ERROR 538 printk("\n[ERROR] in %s : no memory for tx_buf / thread[%x,%x] / cycle %d\n", 539 __FUNCTION__, process->pid, this->trdid, cycle ); 540 #endif 541 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); // 2 542 kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) ); // 1 543 return -1; 544 } 545 546 // 4. allocate memory for r2tq queue 535 547 error = remote_buf_init( XPTR( cxy , &socket->r2tq ), 536 548 bits_log2( CONFIG_SOCK_R2T_BUF_SIZE ) ); 537 549 if( error ) 538 550 { 539 printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x]\n", 540 __FUNCTION__, process->pid, this->trdid ); 541 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 542 req.type = KMEM_KCM; 543 req.ptr = socket; 544 kmem_remote_free( cxy , &req ); 545 return -1; 546 } 547 548 // don't allocate memory for crqq queue, as it is done by the socket_listen function 549 550 // 4. allocate memory for file descriptor 551 req.type = KMEM_KCM; 552 req.order = bits_log2( sizeof(vfs_file_t) ); 553 req.flags = AF_ZERO; 554 file = kmem_remote_alloc( cxy , &req ); 551 552 #if DEBUG_SOCKET_ERROR 553 printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x] / cycle %d\n", 554 __FUNCTION__, process->pid, this->trdid, cycle ); 555 #endif 556 kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER ); // 3 557 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); // 2 558 kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) ); // 1 559 return -1; 560 } 561 562 // don't allocate memory for CRQ queue / done by the socket_listen function 563 564 // 5. allocate memory for file descriptor 565 file = kmem_remote_alloc( cxy , bits_log2(sizeof(vfs_file_t)) , AF_ZERO ); 555 566 556 567 if( file == NULL ) 557 568 { 558 printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x]\n", 559 __FUNCTION__, process->pid, this->trdid ); 560 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); 561 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 562 req.type = KMEM_KCM; 563 req.ptr = socket; 564 kmem_remote_free( cxy , &req ); 569 570 #if DEBUG_SOCKET_ERROR 571 printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x] / cycle %d\n", 572 __FUNCTION__, process->pid, this->trdid, cycle ); 573 #endif 574 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); // 4 575 kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER ); // 3 576 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); // 2 577 kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) ); // 1 565 578 return -1; 566 579 } 567 580 568 // 5. get an fdid value, and register file descriptor in fd_array[]581 // 6. get an fdid value, and register file descriptor in fd_array[] 569 582 error = process_fd_register( process->ref_xp, 570 583 XPTR( cxy , file ), … … 572 585 if ( error ) 573 586 { 574 printk("\n[ERROR] in %s : cannot register file descriptor / thread[%x,%x]\n", 575 __FUNCTION__, process->pid, this->trdid ); 576 req.type = KMEM_KCM; 577 req.ptr = file; 578 kmem_free( &req ); 579 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); 580 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); 581 req.ptr = socket; 582 kmem_free( &req ); 587 588 #if DEBUG_SOCKET_ERROR 589 if( DEBUG_SOCKET_ERROR < cycle ) 590 printk("\n[ERROR] in %s : cannot register file descriptor / thread[%x,%x] / cycle %d\n", 591 __FUNCTION__, process->pid, this->trdid, cycle ); 592 #endif 593 kmem_remote_free( cxy , file , bits_log2(sizeof(vfs_file_t)) ); // 5 594 remote_buf_release_data( XPTR( cxy , &socket->r2tq ) ); // 4 595 kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER ); // 3 596 remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) ); // 2 597 kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) ); // 1 583 598 return -1; 584 599 } … … 597 612 hal_remote_s32( XPTR( cxy , &socket->rx_valid ) , false ); 598 613 hal_remote_s32( XPTR( cxy , &socket->nic_channel ) , 0 ); 614 hal_remote_spt( XPTR( cxy , &socket->tx_buf ) , tx_buf ); 599 615 600 616 // initialize file descriptor … … 606 622 607 623 #if DEBUG_SOCKET_CREATE 624 cycle = (uint32_t)hal_get_cycles(); 608 625 if( DEBUG_SOCKET_CREATE < cycle ) 609 626 printk("\n[%s] thread[%x,%x] exit / socket[%x,%d] / xptr[%x,%x] / cycle %d\n", … … 631 648 static void socket_destroy( xptr_t file_xp ) 632 649 { 633 kmem_req_t req;634 635 650 thread_t * this = CURRENT_THREAD; 636 651 process_t * process = this->process; … … 677 692 678 693 // release memory allocated for file descriptor 679 req.type = KMEM_KCM; 680 req.ptr = file_ptr; 681 kmem_remote_free( file_cxy , &req ); 694 kmem_remote_free( file_cxy , file_ptr , bits_log2(sizeof(vfs_file_t)) ); 682 695 683 696 // release memory allocated for buffers attached to socket descriptor … … 687 700 688 701 // release memory allocated for socket descriptor 689 req.type = KMEM_KCM; 690 req.ptr = socket_ptr; 691 kmem_remote_free( file_cxy , &req ); 702 kmem_remote_free( file_cxy , socket_ptr , bits_log2(sizeof(socket_t)) ); 692 703 693 704 #if DEBUG_SOCKET_DESTROY … … 702 713 //////////////////////////////////////////////// 703 714 void socket_put_r2t_request( xptr_t queue_xp, 704 uint 32_tflags,715 uint8_t flags, 705 716 uint32_t channel ) 706 717 { … … 715 726 // try to register R2T request 716 727 error_t error = remote_buf_put_from_kernel( queue_xp, 717 (uint8_t *)(&flags),728 &flags, 718 729 1 ); 719 730 if( error ) … … 740 751 } 741 752 } // end socket_put_r2t_request() 753 754 /////////////////////////////////////////////////// 755 error_t socket_get_r2t_request( xptr_t queue_xp, 756 uint8_t * flags ) 757 { 758 // get one request from R2T queue 759 return remote_buf_get_to_kernel( queue_xp, 760 flags, 761 1 ); 762 } // end socket_get_r2T_request() 742 763 743 764 /////////////////////////////////////////////////// … … 843 864 process_t * process = this->process; 844 865 866 #if DEBUG_SOCKET_BIND || DEBUG_SOCKET_ERROR 867 uint32_t cycle = (uint32_t)hal_get_cycles(); 868 #endif 869 845 870 #if DEBUG_SOCKET_BIND 846 uint32_t cycle = (uint32_t)hal_get_cycles();847 871 if( DEBUG_SOCKET_BIND < cycle ) 848 872 printk("\n[%s] thread[%x,%x] enter / socket[%x,%d] / addr %x / port %x / cycle %d\n", … … 858 882 if( file_xp == XPTR_NULL ) 859 883 { 860 printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x]\n", 861 __FUNCTION__, fdid, process->pid, this->trdid ); 884 885 #if DEBUG_SOCKET_ERROR 886 printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d\n", 887 __FUNCTION__, fdid, process->pid, this->trdid, cycle ); 888 #endif 862 889 return -1; 863 890 } … … 869 896 if( file_type != FILE_TYPE_SOCK ) 870 897 { 871 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]", 872 __FUNCTION__, vfs_inode_type_str( file_type ), process->pid, this->trdid ); 898 899 #if DEBUG_SOCKET_ERROR 900 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d", 901 __FUNCTION__, vfs_inode_type_str( file_type ), process->pid, this->trdid, cycle ); 902 #endif 873 903 return -1; 874 904 } … … 918 948 process_t * process = this->process; 919 949 950 #if DEBUG_SOCKET_LISTEN || DEBUG_SOCKET_ERROR 951 uint32_t cycle = (uint32_t)hal_get_cycles(); 952 #endif 953 920 954 #if DEBUG_SOCKET_LISTEN 921 uint32_t cycle = (uint32_t)hal_get_cycles();922 955 if( DEBUG_SOCKET_LISTEN < cycle ) 923 956 printk("\n[%s] thread[%x,%x] enter / socket[%x,%d] / crq_depth %x / cycle %d\n", … … 933 966 if( file_xp == XPTR_NULL ) 934 967 { 935 printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x]\n", 936 __FUNCTION__, fdid, process->pid, this->trdid ); 968 969 #if DEBUG_SOCKET_ERROR 970 printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d\n", 971 __FUNCTION__, fdid, process->pid, this->trdid, cycle ); 972 #endif 937 973 return -1; 938 974 } … … 944 980 if( file_type != FILE_TYPE_SOCK ) 945 981 { 946 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n", 947 __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid ); 982 983 #if DEBUG_SOCKET_ERROR 984 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d\n", 985 __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid, cycle ); 986 #endif 948 987 return -1; 949 988 } … … 958 997 if( socket_type != SOCK_STREAM ) 959 998 { 960 printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x]\n", 961 __FUNCTION__, socket_type_str(socket_type), process->pid, this->trdid ); 999 1000 #if DEBUG_SOCKET_ERROR 1001 printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x] / cycle %d\n", 1002 __FUNCTION__, socket_type_str(socket_type), process->pid, this->trdid, cycle ); 1003 #endif 962 1004 return -1; 963 1005 } … … 966 1008 if( socket_state != TCP_STATE_BOUND ) 967 1009 { 968 printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x]\n", 969 __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid ); 1010 1011 #if DEBUG_SOCKET_ERROR 1012 printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x] / cycle %d\n", 1013 __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid, cycle ); 1014 #endif 970 1015 return -1; 971 1016 } … … 980 1025 if( error ) 981 1026 { 982 printk("\n[ERROR] in %s : cannot allocate CRQ queue / thread[%x,%x]\n", 983 __FUNCTION__, process->pid, this->trdid ); 1027 1028 #if DEBUG_SOCKET_ERROR 1029 printk("\n[ERROR] in %s : cannot allocate CRQ queue / thread[%x,%x] / cycle %d\n", 1030 __FUNCTION__, process->pid, this->trdid, cycle ); 1031 #endif 984 1032 return -1; 985 1033 } … … 1011 1059 vfs_file_t * file_ptr; 1012 1060 cxy_t file_cxy; 1013 vfs_file_type_t file_type; // file descriptor type1061 vfs_file_type_t file_type; // file descriptor type 1014 1062 socket_t * socket_ptr; // local pointer on remote waiting socket 1015 1063 uint32_t socket_type; // listening socket type … … 1045 1093 process_t * process = this->process; 1046 1094 1047 #if DEBUG_SOCKET_ACCEPT 1095 #if DEBUG_SOCKET_ACCEPT || DEBUG_SOCKET_ERROR 1048 1096 uint32_t cycle = (uint32_t)hal_get_cycles(); 1097 #endif 1098 1099 #if DEBUG_SOCKET_ACCEPT 1049 1100 if( DEBUG_SOCKET_ACCEPT < cycle ) 1050 1101 printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / cycle %d\n", … … 1060 1111 if( file_xp == XPTR_NULL ) 1061 1112 { 1062 printk("\n[ERROR] in %s : undefined fdid %d", 1063 __FUNCTION__, fdid ); 1113 1114 #if DEBUG_SOCKET_ERROR 1115 printk("\n[ERROR] in %s : undefined fdid %d / thead[%x,%x] / cycle %d", 1116 __FUNCTION__, fdid, process->pid, this->trdid, cycle ); 1117 #endif 1064 1118 return -1; 1065 1119 } … … 1071 1125 if( file_type != FILE_TYPE_SOCK ) 1072 1126 { 1073 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n", 1074 __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid ); 1127 1128 #if DEBUG_SOCKET_ERROR 1129 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d\n", 1130 __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid, cycle ); 1131 #endif 1075 1132 return -1; 1076 1133 } … … 1097 1154 if( socket_type != SOCK_STREAM ) 1098 1155 { 1099 // release listening socket lock 1156 1157 #if DEBUG_SOCKET_ERROR 1158 printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x] / cycle %d\n", 1159 __FUNCTION__, socket_type_str(socket_type), process->pid , this->trdid, cycle ); 1160 #endif 1100 1161 remote_queuelock_release( socket_lock_xp ); 1101 1102 printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x]\n",1103 __FUNCTION__, socket_type_str(socket_type), process->pid , this->trdid );1104 1162 return -1; 1105 1163 } … … 1108 1166 if( socket_state != TCP_STATE_LISTEN ) 1109 1167 { 1110 // release listening socket lock 1168 1169 #if DEBUG_SOCKET_ERROR 1170 printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x] / cycle %d\n", 1171 __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid, cycle ); 1172 #endif 1111 1173 remote_queuelock_release( socket_lock_xp ); 1112 1113 printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x]\n",1114 __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid );1115 1174 return -1; 1116 1175 } … … 1119 1178 if( (socket_rx_valid == true) || (socket_rx_client != XPTR_NULL) ) 1120 1179 { 1121 // release listening socket lock 1180 1181 #if DEBUG_SOCKET_ERROR 1182 printk("\n[ERROR] in %s : previous RX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1183 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 1184 #endif 1122 1185 remote_queuelock_release( socket_lock_xp ); 1123 1124 printk("\n[ERROR] in %s : previous RX cmd on socket[%x,%d] / thread[%x,%x]\n",1125 __FUNCTION__, process->pid, fdid, process->pid, this->trdid );1126 1186 return -1; 1127 1187 } … … 1130 1190 if( (socket_tx_valid == true) || (socket_tx_client != XPTR_NULL) ) 1131 1191 { 1132 // release socket lock 1192 1193 #if DEBUG_SOCKET_ERROR 1194 printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1195 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 1196 #endif 1133 1197 remote_queuelock_release( socket_lock_xp ); 1134 1135 printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x]\n", 1136 __FUNCTION__, process->pid, fdid, process->pid, this->trdid ); 1137 return -1; 1138 } 1139 1140 // 2) build extended pointer on listening socket.crq 1198 return -1; 1199 } 1200 1201 // 2) check the listenig socket CRQ 1141 1202 crq_xp = XPTR( file_cxy , &socket_ptr->crqq ); 1142 1203 … … 1144 1205 crq_status = remote_buf_status( crq_xp ); 1145 1206 1146 // block & deschedule when CRQ empty1207 // block & deschedule to wait a client request when CRQ empty 1147 1208 if( crq_status == 0 ) 1148 1209 { 1149 // register command arguments in listening socket1210 // register command arguments for NIC_RX server in listening socket 1150 1211 hal_remote_s32( XPTR( file_cxy , &socket_ptr->rx_cmd ), CMD_RX_ACCEPT ); 1151 1212 hal_remote_s64( XPTR( file_cxy , &socket_ptr->rx_client ), client_xp ); … … 1179 1240 crq_status = remote_buf_status( crq_xp ); 1180 1241 1181 assert( __FUNCTION__, (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)), 1242 assert( __FUNCTION__, 1243 (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)), 1182 1244 "illegal socket state when client thread resumes after RX_ACCEPT" ); 1183 1245 … … 1187 1249 if( cmd_status != CMD_STS_SUCCESS ) 1188 1250 { 1189 // release socket lock 1251 1252 #if DEBUG_SOCKET_ERROR 1253 printk("\n[ERROR] in %s : reported for RX / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1254 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 1255 #endif 1190 1256 remote_queuelock_release( socket_lock_xp ); 1191 1192 printk("\n[ERROR] in %s for RX_ACCEPT command / socket[%x,%d] / thread[%x,%x]\n",1193 __FUNCTION__, process->pid, fdid, process->pid, this->trdid );1194 1257 return -1; 1195 1258 } 1196 1197 // extract first request from the listening socket CRQ 1198 error = socket_get_crq_request( crq_xp, 1259 } // end blocking on CRQ empty 1260 1261 // from this point, we can extract a request from listening socket CRQ 1262 error = socket_get_crq_request( crq_xp, 1199 1263 &new_remote_addr, 1200 1264 &new_remote_port, 1201 1265 &new_remote_iss, 1202 1266 &new_remote_window ); 1203 1204 1267 assert( __FUNCTION__, (error == 0), 1205 1268 "cannot get a connection request from a non-empty CRQ" ); 1206 1269 1207 // reset listening socket rx_client 1208 hal_remote_s32( XPTR( file_cxy , &socket_ptr->rx_client ) , XPTR_NULL ); 1209 1210 // release socket lock 1211 remote_queuelock_release( socket_lock_xp ); 1212 1213 } // end blocking on CRQ status 1214 1215 // from this point, we can create a new socket 1216 // and ask the NIC_TX to send a SYN-ACK segment 1270 // release listening socket lock 1271 remote_queuelock_release( socket_lock_xp ); 1217 1272 1218 1273 #if DEBUG_SOCKET_ACCEPT 1219 1274 cycle = (uint32_t)hal_get_cycles(); 1220 1275 if( DEBUG_SOCKET_ACCEPT < cycle ) 1221 printk("\n[%s] thread[%x,%x] socket[%x,%d] / got a CRQ request / cycle %d\n", 1222 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle ); 1276 printk("\n[%s] thread[%x,%x] socket[%x,%d] / CRQ request [addr %x / port %x] / cycle %d\n", 1277 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, 1278 new_remote_addr, new_remote_port, cycle ); 1223 1279 #endif 1224 1280 … … 1234 1290 if( error ) 1235 1291 { 1236 printk("\n[ERROR] in %s : cannot allocate new socket / thread[%x,%x]\n", 1237 __FUNCTION__, process->pid, this->trdid ); 1292 1293 #if DEBUG_SOCKET_ERROR 1294 printk("\n[ERROR] in %s : cannot create new socket / thread[%x,%x] / cycle %d\n", 1295 __FUNCTION__, process->pid, this->trdid, cycle ); 1296 #endif 1238 1297 return -1; 1239 1298 } … … 1287 1346 1288 1347 // start retransmission timer 1289 socket_alarm_start( new_socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1348 alarm_start( client_xp, 1349 hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT, 1350 &socket_alarm_handler, 1351 new_socket_xp ); 1290 1352 1291 1353 #if DEBUG_SOCKET_ACCEPT 1292 1354 cycle = (uint32_t)hal_get_cycles(); 1293 1355 if( DEBUG_SOCKET_ACCEPT < cycle ) 1294 printk("\n[%s] thread[%x,%x] new_socket[%x,%d] blocks on <IO> waiting ESTAB/ cycle %d\n",1356 printk("\n[%s] thread[%x,%x] for socket[%x,%d] request SYN-ACK & blocks on <IO> / cycle %d\n", 1295 1357 __FUNCTION__, process->pid, this->trdid, process->pid, new_fdid, cycle ); 1296 1358 #endif … … 1307 1369 #endif 1308 1370 1309 // stop retransmission timer 1310 socket_alarm_stop();1371 // stop retransmission timer in thread descriptor 1372 alarm_stop( client_xp ); 1311 1373 1312 1374 // get new socket state, tx_valid and tx_sts … … 1315 1377 cmd_status = hal_remote_l32( XPTR( new_socket_cxy , &new_socket_ptr->tx_sts )); 1316 1378 1317 assert( __FUNCTION__, (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))1318 1379 assert( __FUNCTION__, 1380 (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 1319 1381 "illegal socket state when client thread resumes after TX_ACCEPT" ); 1320 1382 … … 1324 1386 if( cmd_status != CMD_STS_SUCCESS ) 1325 1387 { 1326 printk("\n[ERROR] in %s for TX_ACCEPT command / socket[%x,%d] / thread[%x,%x]\n", 1327 __FUNCTION__, process->pid, new_fdid, process->pid, this->trdid ); 1388 1389 #if DEBUG_SOCKET_ERROR 1390 printk("\n[ERROR] in %s reported for TX / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1391 __FUNCTION__, process->pid, new_fdid, process->pid, this->trdid, cycle ); 1392 #endif 1328 1393 return -1; 1329 1394 } … … 1370 1435 trdid_t trdid = this->trdid; 1371 1436 1437 #if DEBUG_SOCKET_CONNECT || DEBUG_SOCKET_ERROR 1438 uint32_t cycle = (uint32_t)hal_get_cycles(); 1439 #endif 1440 1372 1441 // get pointers on file descriptor 1373 1442 xptr_t file_xp = process_fd_get_xptr_from_local( this->process , fdid ); … … 1378 1447 if( file_xp == XPTR_NULL ) 1379 1448 { 1380 printk("\n[ERROR] in %s : undefined fdid %d", 1381 __FUNCTION__, fdid ); 1449 1450 #if DEBUG_SOCKET_ERROR 1451 printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d", 1452 __FUNCTION__, fdid, pid, trdid, cycle ); 1453 #endif 1382 1454 return -1; 1383 1455 } … … 1388 1460 1389 1461 #if DEBUG_SOCKET_CONNECT 1390 uint32_t cycle = (uint32_t)hal_get_cycles();1391 1462 if( DEBUG_SOCKET_CONNECT < cycle ) 1392 printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / addr %x / port % d/ cycle %d\n",1463 printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / addr %x / port %x / cycle %d\n", 1393 1464 __FUNCTION__, pid, trdid, pid, fdid, remote_addr, remote_port, cycle ); 1394 1465 #endif … … 1397 1468 if( file_type != FILE_TYPE_SOCK ) 1398 1469 { 1399 printk("\n[ERROR] in %s : illegal file type %s", 1400 __FUNCTION__, vfs_inode_type_str( file_type ) ); 1470 1471 #if DEBUG_SOCKET_ERROR 1472 printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d", 1473 __FUNCTION__, vfs_inode_type_str( file_type ), pid, trdid, cycle ); 1474 #endif 1401 1475 return -1; 1402 1476 } … … 1412 1486 if( socket_state != UDP_STATE_BOUND ) 1413 1487 { 1414 printk("\n[ERROR] in %s : illegal socket state %s for type %s", 1415 __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type) ); 1488 1489 #if DEBUG_SOCKET_ERROR 1490 printk("\n[ERROR] in %s : illegal socket state %s for type %s / thread[%x,%x] / cycle %d", 1491 __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type), pid, trdid, cycle ); 1492 #endif 1416 1493 return -1; 1417 1494 } … … 1421 1498 if( socket_state != TCP_STATE_BOUND ) 1422 1499 { 1423 printk("\n[ERROR] in %s : illegal socket state %s for type %s", 1424 __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type) ); 1500 1501 #if DEBUG_SOCKET_ERROR 1502 printk("\n[ERROR] in %s : illegal socket state %s for type %s / thread[%x,%x] / cycle %d", 1503 __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type), pid, trdid, cycle ); 1504 #endif 1425 1505 return -1; 1426 1506 } … … 1428 1508 else 1429 1509 { 1430 printk("\n[ERROR] in %s : illegal socket type %s", 1431 __FUNCTION__, socket_type_str(socket_type) ); 1510 1511 #if DEBUG_SOCKET_ERROR 1512 printk("\n[ERROR] in %s : illegal socket type / thread[%x,%x] / cycle %d", 1513 __FUNCTION__, pid, trdid, cycle ); 1514 #endif 1432 1515 return -1; 1433 1516 } … … 1475 1558 1476 1559 // start retransmission timer 1477 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1560 alarm_start( client_xp, 1561 hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT, 1562 &socket_alarm_handler, 1563 socket_xp ); 1478 1564 1479 1565 #if DEBUG_SOCKET_CONNECT … … 1494 1580 #endif 1495 1581 1496 // stop retransmission timer 1497 socket_alarm_stop();1582 // stop retransmission timer in thread descriptor 1583 alarm_stop( client_xp ); 1498 1584 1499 1585 // get socket state, tx_valid and tx_sts … … 1507 1593 1508 1594 // reset socket.tx_client 1509 hal_remote_s 32( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );1595 hal_remote_s64( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL ); 1510 1596 1511 1597 if( cmd_status != CMD_STS_SUCCESS ) 1512 1598 { 1513 printk("\n[ERROR] in %s : for command TX_CONNECT / socket[%x,%d] / thread[%x,%x]\n", 1514 __FUNCTION__, pid, fdid, pid, trdid ); 1599 1600 #if DEBUG_SOCKET_ERROR 1601 printk("\n[ERROR] in %s reported by server / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1602 __FUNCTION__, pid, fdid, pid, trdid, cycle ); 1603 #endif 1515 1604 return -1; 1516 1605 } … … 1548 1637 trdid_t trdid = this->trdid; 1549 1638 1639 #if DEBUG_SOCKET_CLOSE || DEBUG_SOCKET_ERROR 1640 uint32_t cycle = (uint32_t)hal_get_cycles(); 1641 #endif 1642 1550 1643 // get pointers on socket descriptor 1551 1644 cxy_t file_cxy = GET_CXY( file_xp ); … … 1558 1651 1559 1652 #if DEBUG_SOCKET_CLOSE 1560 uint32_t cycle = (uint32_t)hal_get_cycles();1561 1653 if (DEBUG_SOCKET_CLOSE < cycle ) 1562 1654 printk("\n[%s] thread[%x,%x] enters for socket[%x,%d] / cycle %d\n", … … 1574 1666 (hal_remote_l64( XPTR( file_cxy , &socket_ptr->tx_client)) != XPTR_NULL) ) 1575 1667 { 1576 // release socket lock 1668 1669 #if DEBUG_SOCKET_ERROR 1670 printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1671 __FUNCTION__, pid, fdid, pid, trdid, cycle ); 1672 #endif 1577 1673 remote_queuelock_release( socket_lock_xp ); 1578 1579 printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x]\n",1580 __FUNCTION__, pid, fdid, pid, trdid );1581 1674 return -1; 1582 1675 } … … 1645 1738 1646 1739 // start retransmission timer 1647 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1740 alarm_start( client_xp, 1741 hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT, 1742 &socket_alarm_handler, 1743 socket_xp ); 1648 1744 1649 1745 #if DEBUG_SOCKET_CLOSE … … 1663 1759 __FUNCTION__, pid, trdid, pid, fdid, cycle ); 1664 1760 #endif 1665 // stop retransmission timer 1666 socket_alarm_stop();1761 // stop retransmission timer in thread descriptor 1762 alarm_stop( client_xp ); 1667 1763 1668 1764 // take socket lock … … 1674 1770 cmd_valid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid ) ); 1675 1771 1676 assert( __FUNCTION__, (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS)) 1677 && (cmd_valid == false)), 1678 "illegal socket state when client thread resumes after TX_CLOSE\n" 1679 " socket_state = %s / cmd_status = %d / cmd_valid = %d\n", 1772 assert( __FUNCTION__, 1773 (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 1774 " socket_state = %s / cmd_status = %d / cmd_valid = %d", 1680 1775 socket_state_str(socket_state), cmd_status, cmd_valid ); 1681 1776 1682 1777 // reset socket.tx_client 1683 hal_remote_s 32( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );1778 hal_remote_s64( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL ); 1684 1779 1685 1780 if( cmd_status != CMD_STS_SUCCESS ) // error reported 1686 1781 { 1687 printk("\n[ERROR] in %s for command TX_CLOSE / socket[%x,%d] / thread[%x,%x]\n", 1688 __FUNCTION__, pid, fdid, pid, this->trdid ); 1782 1783 #if DEBUG_SOCKET_ERROR 1784 printk("\n[ERROR] in %s for command TX_CLOSE / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1785 __FUNCTION__, pid, fdid, pid, this->trdid, cycle ); 1786 #endif 1689 1787 return -1; 1690 1788 } … … 1708 1806 //////////////////////////////////////////////////////////////////////////////////////// 1709 1807 // This static function is called by the two functions socket_send() & socket_recv(). 1710 // It can beused for both UDP and TCP sockets.1808 // It is used for both UDP and TCP sockets. 1711 1809 //////////////////////////////////////////////////////////////////////////////////////// 1712 1810 // @ is_send : send when true / receive when false. 1713 1811 // @ fdid : socket identifier. 1714 1812 // @ u_buf : pointer on user buffer in user space. 1715 // @ length : number of bytes .1813 // @ length : number of bytes in buffer. 1716 1814 //////////////////////////////////////////////////////////////////////////////////////// 1717 1815 // Implementation note : The behavior is different for SEND & RECV … … 1749 1847 chdev_t * chdev_ptr; 1750 1848 cxy_t chdev_cxy; 1751 uint32_t buf_status; // number of bytes in rx_buf1752 1849 int32_t moved_bytes; // total number of moved bytes (fot return) 1753 xptr_t server_xp; // extended pointer on NIC_TX / NIC_RX server thread 1754 thread_t * server_ptr; // local pointer on NIC_TX / NIC_RX server thread 1755 kmem_req_t req; // KCM request for TX kernel buffer 1756 uint8_t * tx_buf; // kernel buffer for TX transfer 1757 bool_t cmd_valid; // from socket descriptor 1758 uint32_t cmd_status; // from socket descriptor 1759 uint32_t tx_todo; // from socket descriptor 1850 xptr_t server_xp; // ext pointer on NIC_TX / NIC_RX thread 1851 thread_t * server_ptr; // local pointer on NIC_TX / NIC_RX thread 1852 uint8_t * tx_buf; // pointer on kernel buffer for TX transfer 1853 bool_t cmd_valid; // RX or TX command from socket descriptor 1854 uint32_t cmd_sts; // RX or TX command from socket descriptor 1855 uint32_t tx_todo; // number of bytes still to send 1856 xptr_t rx_buf_xp; // extended pointer on socket rx_buf 1857 uint32_t rx_buf_sts; // current status of socket rx_buf 1760 1858 1761 1859 thread_t * this = CURRENT_THREAD; 1762 1860 process_t * process = this->process; 1861 1862 #if DEBUG_SOCKET_SEND || DEBUG_SOCKET_RECV || DEBUG_SOCKET_ERROR 1863 uint32_t cycle = (uint32_t)hal_get_cycles(); 1864 #endif 1865 1866 #if DEBUG_SOCKET_SEND || DEBUG_SOCKET_RECV 1867 if( is_send ) 1868 printk("\n[%s] thread[%x,%x] socket[%x,%d] enter : SEND / buf %x / length %d / cycle %d\n", 1869 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, u_buf, length, cycle ); 1870 else 1871 printk("\n[%s] thread[%x,%x] socket[%x,%d] enter : RECV / buf %x / length %d / cycle %d\n", 1872 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, u_buf, length, cycle ); 1873 #endif 1763 1874 1764 1875 // build extended pointer on client thread … … 1772 1883 if( file_xp == XPTR_NULL ) 1773 1884 { 1774 printk("\n[ERROR] in %s : undefined fdid %d / thread%x,%x]\n", 1775 __FUNCTION__, fdid , process->pid, this->trdid ); 1885 1886 #if DEBUG_SOCKET_ERROR 1887 printk("\n[ERROR] in %s : undefined fdid %d / thread%x,%x] / cycle %d\n", 1888 __FUNCTION__, fdid , process->pid, this->trdid, cycle ); 1889 #endif 1776 1890 return -1; 1777 1891 } … … 1787 1901 if( file_type != FILE_TYPE_SOCK ) 1788 1902 { 1789 printk("\n[ERROR] in %s : illegal file type %s / socket[%x,%d]\n", 1790 __FUNCTION__, vfs_inode_type_str(file_type), process->pid, fdid ); 1903 1904 #if DEBUG_SOCKET_ERROR 1905 printk("\n[ERROR] in %s : illegal file type thread[%x,%x] / cycle %d\n", 1906 __FUNCTION__, process->pid, this->trdid, cycle ); 1907 #endif 1791 1908 return -1; 1792 1909 } … … 1803 1920 nic_channel = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel )); 1804 1921 1805 ///////////// 1922 ////////////////////////////////////////////////////// 1806 1923 if( is_send ) // SEND command 1807 1924 { 1808 1925 1809 1926 #if DEBUG_SOCKET_SEND 1810 uint32_tcycle = (uint32_t)hal_get_cycles();1927 cycle = (uint32_t)hal_get_cycles(); 1811 1928 if (DEBUG_SOCKET_SEND < cycle ) 1812 printk("\n[%s] thread[%x,%x] received SEND command for socket[%x,%d]/ length %d / cycle %d\n",1929 printk("\n[%s] thread[%x,%x] / socket[%x,%d] get SEND / length %d / cycle %d\n", 1813 1930 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle ); 1814 1931 #endif 1932 1815 1933 // check no previous TX command 1816 if( (hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid )) == true) || 1817 (hal_remote_l64( XPTR( file_cxy , &socket_ptr->tx_client)) != XPTR_NULL) ) 1934 if( hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid )) == true ) 1818 1935 { 1819 // release socket lock 1936 1937 #if DEBUG_SOCKET_ERROR 1938 printk("\n[ERROR] in %s : previous TX command / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 1939 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 1940 #endif 1820 1941 remote_queuelock_release( socket_lock_xp ); 1821 1822 printk("\n[ERROR] in %s : previous TX command / socket[%x,%d] / thread[%x,%x]\n",1823 __FUNCTION__, process->pid, fdid, process->pid, this->trdid );1824 1942 return -1; 1825 1943 } 1826 1944 1827 // allocate a temporary kernel buffer 1828 req.type = KMEM_KCM; 1829 req.order = bits_log2( length ); 1830 req.flags = AF_NONE; 1831 tx_buf = kmem_alloc( &req ); 1832 1833 if( tx_buf == NULL ) 1834 { 1835 // release socket lock 1836 remote_queuelock_release( socket_lock_xp ); 1837 1838 printk("\n[ERROR] in %s : no memory for tx_buf / socket[%x,%d] / thread[%x,%x]\n", 1839 __FUNCTION__, process->pid, fdid, process->pid, this->trdid ); 1840 return -1; 1841 } 1842 1843 // copy data from user u_buf to kernel tx_buf 1844 hal_copy_from_uspace( XPTR( local_cxy , tx_buf ), 1945 // get tx_buf pointer from socket pointer 1946 tx_buf = (uint8_t*)hal_remote_lpt( XPTR( file_cxy , &socket_ptr->tx_buf )); 1947 1948 // copy data from user u_buf to kernel socket tx_buf 1949 hal_copy_from_uspace( XPTR( file_cxy , tx_buf ), 1845 1950 u_buf, 1846 1951 length ); 1952 #if DEBUG_SOCKET_SEND 1953 if (DEBUG_SOCKET_SEND < cycle ) 1954 printk("\n[%s] thread[%x,%x] / socket[%x,%d] copied %d bytes to tx_buf (%x,%x)\n", 1955 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, file_cxy, tx_buf ); 1956 putb("tx_buf : 16 first data bytes" , tx_buf , 16 ); 1957 #endif 1847 1958 1848 1959 // register command in socket descriptor … … 1852 1963 hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_len ) , length ); 1853 1964 hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_todo ) , length ); 1965 hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_ack ) , 0 ); 1854 1966 hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_valid ) , true ); 1855 1967 … … 1869 1981 thread_unblock( server_xp , THREAD_BLOCKED_CLIENT ); 1870 1982 1871 // start retransmission timer 1872 socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT ); 1983 // start retransmission timer for TCP socket 1984 if( socket_type == SOCK_STREAM ) 1985 { 1986 alarm_start( client_xp, 1987 hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT, 1988 &socket_alarm_handler, 1989 socket_xp ); 1990 } 1873 1991 1874 1992 #if DEBUG_SOCKET_SEND 1875 cycle = (uint32_t)hal_get_cycles();1876 1993 if( DEBUG_SOCKET_SEND < cycle ) 1877 printk("\n[%s] thread[%x,%x] socket[%x,%d] register SEND => blocks on <IO> / cycle %d\n",1878 __FUNCTION__, process->pid, this->trdid, process->pid, fdid , cycle);1994 printk("\n[%s] thread[%x,%x] / socket[%x,%d] registers SEND => blocks on <IO>\n", 1995 __FUNCTION__, process->pid, this->trdid, process->pid, fdid ); 1879 1996 #endif 1880 1997 // client thread blocks itself and deschedules … … 1885 2002 cycle = (uint32_t)hal_get_cycles(); 1886 2003 if( DEBUG_SOCKET_SEND < cycle ) 1887 printk("\n[%s] thread[%x,%x] socket[%x,%d] for SEND resumes/ cycle %d\n",2004 printk("\n[%s] thread[%x,%x] / socket[%x,%d] resumes for SEND / cycle %d\n", 1888 2005 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle ); 1889 2006 #endif 1890 // stop retransmission timer 1891 socket_alarm_stop(); 1892 1893 // take socket lock 2007 // stop retransmission timer for TCP socket 2008 if( socket_type == SOCK_STREAM ) 2009 { 2010 alarm_stop( client_xp ); 2011 } 2012 2013 // take socket lock 1894 2014 remote_queuelock_acquire( socket_lock_xp ); 1895 2015 … … 1897 2017 tx_todo = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_todo )); 1898 2018 cmd_valid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid )); 1899 cmd_st atus= hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_sts ));2019 cmd_sts = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_sts )); 1900 2020 1901 2021 // reset tx_client in socket descriptor … … 1906 2026 1907 2027 // check SEND command completed when TX client thread resumes 1908 assert( __FUNCTION__, (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 1909 "illegal socket state when client thread resumes after TX_SEND\n" 1910 " tx_todo = %d / tx_status = %d / tx_valid = %d\n", 1911 tx_todo, cmd_status, cmd_valid ); 1912 1913 // release the tx_buf 1914 req.ptr = tx_buf; 1915 kmem_free( &req ); 1916 1917 if( cmd_status != CMD_STS_SUCCESS ) 2028 assert( __FUNCTION__, 2029 (((tx_todo == 0) || (cmd_sts != CMD_STS_SUCCESS)) && (cmd_valid == false)), 2030 "client thread resumes from SEND / bad state : tx_todo %d / tx_sts %d / tx_valid %d", 2031 tx_todo, cmd_sts, cmd_valid ); 2032 2033 if( cmd_sts != CMD_STS_SUCCESS ) 1918 2034 { 1919 2035 1920 #if DEBUG_SOCKET_SEND 1921 cycle = (uint32_t)hal_get_cycles(); 1922 if( DEBUG_SOCKET_RECV < cycle ) 1923 printk("\n[%s] error %s for TX_SEND / socket[%x,%d] / thread[%x,%x]\n", 1924 __FUNCTION__, socket_cmd_sts_str(cmd_status), process->pid, fdid, process->pid, this->trdid ); 2036 #if DEBUG_SOCKET_ERROR 2037 printk("\n[ERROR] in %s : reported for SEND / socket[%x,%d] / thread[%x,%x] / cycle %d\n", 2038 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 1925 2039 #endif 1926 2040 return -1; … … 1932 2046 cycle = (uint32_t)hal_get_cycles(); 1933 2047 if (DEBUG_SOCKET_SEND < cycle ) 1934 printk("\n[%s] thread[%x,%x] success for SEND / socket[%x,%d] / length%d / cycle %d\n",2048 printk("\n[%s] thread[%x,%x] SEND success / socket[%x,%d] / bytes %d / cycle %d\n", 1935 2049 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle ); 1936 2050 #endif … … 1940 2054 } // end SEND command 1941 2055 1942 //// 1943 else // RECV command2056 ///////////////////////////////////////////////////////////// 2057 else // RECV command 1944 2058 { 1945 2059 1946 2060 #if DEBUG_SOCKET_RECV 1947 uint32_t cycle = (uint32_t)hal_get_cycles(); 1948 if (DEBUG_SOCKET_SEND < cycle ) 1949 printk("\n[%s] thread[%x,%x] received RECV command for socket[%x,%d] / length %d / cycle %d\n", 2061 if (DEBUG_SOCKET_RECV < cycle ) 2062 printk("\n[%s] thread[%x,%x] / socket[%x,%d] get RECV / length %d / cycle %d\n", 1950 2063 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle ); 1951 2064 #endif 1952 2065 // check no previous RX command 1953 if( (hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid )) == true) || 1954 (hal_remote_l64( XPTR( file_cxy , &socket_ptr->rx_client)) != XPTR_NULL) ) 2066 if( hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid )) == true ) 1955 2067 { 1956 // release socket lock 2068 2069 #if DEBUG_SOCKET_ERROR 2070 printk("\n[ERROR] in %s : previous RX command on socket[%x,%d] / thread[%x,%x] / cycle %d\n", 2071 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 2072 #endif 1957 2073 remote_queuelock_release( socket_lock_xp ); 1958 1959 printk("\n[ERROR] in %s : previous RX command on socket[%x,%d] / thread[%x,%x]\n",1960 __FUNCTION__, process->pid, fdid, process->pid, this->trdid );1961 2074 return -1; 1962 2075 } … … 1969 2082 1970 2083 #if DEBUG_SOCKET_RECV 1971 uint32_tcycle = (uint32_t)hal_get_cycles();2084 cycle = (uint32_t)hal_get_cycles(); 1972 2085 if( DEBUG_SOCKET_RECV < cycle ) 1973 printk("\n[%s] thread[%x,%x] socket[%x,%d] TCP connection closed / cycle %d\n",2086 printk("\n[%s] thread[%x,%x] / socket[%x,%d] TCP connection closed / cycle %d\n", 1974 2087 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle ); 1975 2088 #endif 1976 2089 return 0; 1977 2090 } 1978 // build extended pointer on socket.rx_buf 1979 xptr_t rx_buf_xp = XPTR( file_cxy , &socket_ptr->rx_buf ); 1980 1981 // get rx_buf status 1982 buf_status = remote_buf_status( rx_buf_xp ); 1983 1984 if( buf_status == 0 ) 2091 2092 // build extended pointer on socket rx_buf 2093 rx_buf_xp = XPTR( file_cxy , &socket_ptr->rx_buf ); 2094 2095 // get socket rx_buf status 2096 rx_buf_sts = remote_buf_status( rx_buf_xp ); 2097 2098 // register RECV command and deschedule when rx_buf empty 2099 if( rx_buf_sts == 0 ) 1985 2100 { 1986 2101 // registers RX_RECV command in socket descriptor … … 1993 2108 1994 2109 #if DEBUG_SOCKET_RECV 1995 uint32_t cycle = (uint32_t)hal_get_cycles();1996 2110 if( DEBUG_SOCKET_RECV < cycle ) 1997 printk("\n[%s] thread[%x,%x] socket[%x,%d] rx_buf empty => blocks on <IO> / cycle %d\n",1998 __FUNCTION__, process->pid, this->trdid, process->pid, fdid , cycle);2111 printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV : rx_buf empty => blocks on <IO>\n", 2112 __FUNCTION__, process->pid, this->trdid, process->pid, fdid ); 1999 2113 #endif 2000 2114 // client thread blocks itself and deschedules … … 2005 2119 cycle = (uint32_t)hal_get_cycles(); 2006 2120 if( DEBUG_SOCKET_RECV < cycle ) 2007 printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV resumes / cycle %d\n",2121 printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV : resumes / cycle %d\n", 2008 2122 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle ); 2009 2123 #endif … … 2011 2125 remote_queuelock_acquire( socket_lock_xp ); 2012 2126 2013 // get rx_stsand rx_buf status2127 // get command status, command valid, and rx_buf status 2014 2128 cmd_valid = hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid )); 2015 cmd_st atus= hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_sts ));2016 buf_status = remote_buf_status( rx_buf_xp );2129 cmd_sts = hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_sts )); 2130 rx_buf_sts = remote_buf_status( rx_buf_xp ); 2017 2131 2018 assert( __FUNCTION__, (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)), 2019 "illegal socket state when client thread resumes after RX_RECV\n" 2020 " buf_status = %d / rx_sts = %d / rx_valid = %d\n", 2021 buf_status , cmd_status , cmd_valid ); 2022 2023 // reset rx_client in socket descriptor 2024 hal_remote_s64( XPTR( file_cxy , &socket_ptr->rx_client ) , XPTR_NULL ); 2025 2026 // reset rx_buf for an UDP socket 2027 if( socket_type == SOCK_DGRAM ) remote_buf_reset( rx_buf_xp ); 2028 2029 // release socket lock 2030 remote_queuelock_release( socket_lock_xp ); 2031 2032 if( cmd_status == CMD_STS_EOF ) // EOF (remote close) reported 2132 assert( __FUNCTION__, (cmd_valid == false), 2133 "client thread resumes from RECV but rx_valid is true" ); 2134 2135 if( cmd_sts == CMD_STS_EOF ) // EOF reported by RX server 2033 2136 { 2034 2137 2035 2138 #if DEBUG_SOCKET_RECV 2036 cycle = (uint32_t)hal_get_cycles();2037 2139 if( DEBUG_SOCKET_RECV < cycle ) 2038 printk("\n[%s] EOF for RX_RECV /socket[%x,%d] / thread[%x,%x]\n",2140 printk("\n[%s] EOF received for socket[%x,%d] / thread[%x,%x]\n", 2039 2141 __FUNCTION__, process->pid, fdid, process->pid, this->trdid ); 2040 2142 #endif 2143 // release socket lock 2144 remote_queuelock_release( socket_lock_xp ); 2145 2041 2146 return 0; 2042 2147 } 2043 else if( cmd_st atus != CMD_STS_SUCCESS ) // other error reported2148 else if( cmd_sts != CMD_STS_SUCCESS ) // error reported by RX server 2044 2149 { 2045 2150 2046 #if DEBUG_SOCKET_RECV 2047 cycle = (uint32_t)hal_get_cycles(); 2048 if( DEBUG_SOCKET_RECV < cycle ) 2049 printk("\n[%s] error %s for RX_RECV / socket[%x,%d] / thread[%x,%x]\n", 2050 __FUNCTION__, socket_cmd_sts_str(cmd_status), process->pid, fdid, process->pid, this->trdid ); 2051 #endif 2151 #if DEBUG_SOCKET_ERROR 2152 printk("\n[ERROR] in %s : rx_server for socket[%x,%d] / thread[%x,%x] / cycle %d\n", 2153 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 2154 #endif 2155 // release socket lock 2156 remote_queuelock_release( socket_lock_xp ); 2157 2052 2158 return -1; 2053 2159 } 2054 2160 else if( rx_buf_sts == 0 ) // annormally empty rx_buf 2161 { 2162 2163 #if DEBUG_SOCKET_ERROR 2164 printk("\n[ERROR] in %s : rx_buf empty for socket[%x,%d] / thread[%x,%x] / cycle %d\n", 2165 __FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle ); 2166 #endif 2167 // release socket lock 2168 remote_queuelock_release( socket_lock_xp ); 2169 2170 return -1; 2171 } 2055 2172 } 2056 2173 2057 2174 // number of bytes extracted from rx_buf cannot be larger than u_buf size 2058 moved_bytes = ( length < buf_status ) ? length : buf_status;2175 moved_bytes = ( length < rx_buf_sts ) ? length : rx_buf_sts; 2059 2176 2060 2177 // move data from kernel rx_buf to user u_buf … … 2062 2179 u_buf, 2063 2180 moved_bytes ); 2064 #if DEBUG_SOCKET_ SEND2065 cycle = (uint32_t)hal_get_cycles(); 2066 if (DEBUG_SOCKET_ SEND< cycle )2067 printk("\n[%s] thread[%x,%x] success for RECV / socket[%x,%d] / length%d / cycle %d\n",2181 #if DEBUG_SOCKET_RECV 2182 cycle = (uint32_t)hal_get_cycles(); 2183 if (DEBUG_SOCKET_RECV < cycle ) 2184 printk("\n[%s] thread[%x,%x] : RECV success / socket[%x,%d] / bytes %d / cycle %d\n", 2068 2185 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, moved_bytes, cycle ); 2069 2186 #endif 2187 // release socket lock 2188 remote_queuelock_release( socket_lock_xp ); 2189 2070 2190 return moved_bytes; 2071 2191 … … 2095 2215 } // end socket_recv() 2096 2216 2217 //////////////////////////////////// 2218 int socket_sendto( uint32_t fdid, 2219 uint8_t * u_buf, 2220 uint32_t length, 2221 uint32_t remote_ip, 2222 uint16_t remote_port ) 2223 { 2224 printk("\n[ERROR] in %s : this function is not implemented yet\n", 2225 __FUNCTION__, fdid, u_buf, length, remote_ip, remote_port ); 2226 return -1; 2227 2228 } // end socket_sendto() 2229 2230 ////////////////////////////////////// 2231 int socket_recvfrom( uint32_t fdid, 2232 uint8_t * u_buf, 2233 uint32_t length, 2234 uint32_t remote_ip, 2235 uint16_t remote_port ) 2236 { 2237 printk("\n[ERROR] in %s : this function is not implemented yet\n", 2238 __FUNCTION__, fdid, u_buf, length, remote_ip, remote_port ); 2239 return -1; 2240 2241 } // end socket_recvfrom() 2242 2097 2243 //////////////////////////////////////////// 2098 2244 void socket_display( xptr_t socket_xp, 2099 const char * func_str ) 2100 { 2245 const char * func_str, 2246 const char * string ) 2247 { 2248 uint32_t cycle = (uint32_t)hal_get_cycles(); 2249 2101 2250 socket_t * socket = GET_PTR( socket_xp ); 2102 2251 cxy_t cxy = GET_CXY( socket_xp ); … … 2111 2260 uint32_t remote_port = hal_remote_l32( XPTR( cxy , &socket->remote_port )); 2112 2261 uint32_t tx_valid = hal_remote_l32( XPTR( cxy , &socket->tx_valid )); 2262 xptr_t tx_client = hal_remote_l64( XPTR( cxy , &socket->tx_client )); 2113 2263 uint32_t tx_cmd = hal_remote_l32( XPTR( cxy , &socket->tx_cmd )); 2114 2264 uint32_t tx_sts = hal_remote_l32( XPTR( cxy , &socket->tx_sts )); … … 2118 2268 uint32_t tx_nxt = hal_remote_l32( XPTR( cxy , &socket->tx_nxt )); 2119 2269 uint32_t tx_wnd = hal_remote_l32( XPTR( cxy , &socket->tx_wnd )); 2270 uint32_t tx_ack = hal_remote_l32( XPTR( cxy , &socket->tx_ack )); 2120 2271 uint32_t rx_valid = hal_remote_l32( XPTR( cxy , &socket->rx_valid )); 2272 xptr_t rx_client = hal_remote_l64( XPTR( cxy , &socket->rx_client )); 2121 2273 uint32_t rx_cmd = hal_remote_l32( XPTR( cxy , &socket->rx_cmd )); 2122 2274 uint32_t rx_sts = hal_remote_l32( XPTR( cxy , &socket->rx_sts )); 2123 2275 uint32_t rx_nxt = hal_remote_l32( XPTR( cxy , &socket->rx_nxt )); 2124 2276 uint32_t rx_wnd = hal_remote_l32( XPTR( cxy , &socket->rx_wnd )); 2125 uint32_t rx_irs = hal_remote_l32( XPTR( cxy , &socket->rx_irs )); 2126 2127 if( func_str == NULL ) 2128 { 2129 printk("\n****** socket[%x,%d] / xptr[%x,%x]*****\n", 2130 pid, fdid, cxy, socket ); 2277 uint32_t rx_irs = hal_remote_l32( XPTR( cxy , &socket->rx_irs )); 2278 2279 remote_queuelock_t * lock_ptr = &socket->lock; 2280 uint32_t taken = hal_remote_l32( XPTR( cxy , &lock_ptr->taken )); 2281 2282 thread_t * tx_ptr = GET_PTR( tx_client ); 2283 cxy_t tx_cxy = GET_CXY( tx_client ); 2284 trdid_t tx_tid = hal_remote_l32( XPTR( tx_cxy , &tx_ptr->trdid )); 2285 2286 thread_t * rx_ptr = GET_PTR( rx_client ); 2287 cxy_t rx_cxy = GET_CXY( rx_client ); 2288 trdid_t rx_tid = hal_remote_l32( XPTR( rx_cxy , &rx_ptr->trdid )); 2289 2290 if( string == NULL ) 2291 { 2292 printk("\n****** socket[%x,%d] / lock %d / in %s / cycle %d *****\n", 2293 pid, fdid, taken, func_str, cycle ); 2131 2294 } 2132 2295 else 2133 2296 { 2134 printk("\n***** socket[%x,%d] / xptr[%x,%x] / from %s *****\n", 2135 pid, fdid, cxy, socket, func_str ); 2136 } 2137 printk(" - state %s / channel %d\n" 2138 " - local_addr %x / local_port %x\n" 2139 " - remote_addr %x / remote_port %x\n" 2140 " - tx_valid %d (%s) / tx_sts %d / tx_len %x / tx_todo %x\n" 2141 " - tx_una %x / tx_nxt %x / tx_wnd %x\n" 2142 " - rx_valid %d (%s) / rx_sts %d\n" 2143 " - rx_nxt %x / rx_wnd %x / rx_irs %x\n", 2144 socket_state_str(state), channel , 2145 local_addr, local_port, 2146 remote_addr, remote_port, 2147 tx_valid, socket_cmd_type_str(tx_cmd), tx_sts, tx_len, tx_todo, 2148 tx_una, tx_nxt, tx_wnd, 2149 rx_valid, socket_cmd_type_str(rx_cmd), rx_sts, 2150 rx_nxt, rx_wnd, rx_irs ); 2297 printk("\n***** socket[%x,%d] / lock %d / in %s %s / cycle %d *****\n", 2298 pid, fdid, taken, func_str, string, cycle ); 2299 } 2300 printk(" - state %s / channel %d / local [%x,%x] / remote[%x,%x]\n" 2301 " - tx : valid %d / client [%x,%x] / cmd %s \n" 2302 " sts %d / len %x / todo %x / ack %x / una %x / nxt %x / wnd %x\n" 2303 " - rx : valid %d / client [%x,%x] / cmd %s\n" 2304 " sts %d / nxt %x / wnd %x / irs %x\n", 2305 socket_state_str(state), channel, 2306 local_addr, local_port, remote_addr, remote_port, 2307 tx_valid, pid, tx_tid, socket_cmd_type_str(tx_cmd), 2308 tx_sts, tx_len, tx_todo, tx_ack, tx_una, tx_nxt, tx_wnd, 2309 rx_valid, pid, rx_tid, socket_cmd_type_str(rx_cmd), 2310 rx_sts, rx_nxt, rx_wnd, rx_irs ); 2151 2311 2152 2312 } // end socket_display()
Note: See TracChangeset
for help on using the changeset viewer.