Ignore:
Timestamp:
Nov 19, 2020, 11:44:34 PM (3 years ago)
Author:
alain
Message:

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/ksocket.c

    r668 r669  
    3434#include <thread.h>
    3535#include <vfs.h>
     36#include <alarm.h>
     37#include <dev_nic.h>
    3638#include <ksocket.h>
    37 #include <dev_nic.h>
    3839
    3940//////////////////////////////////////////////////////////////////////////////////////
     
    127128}
    128129
     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///////////////////////////////////////////////////////////////////////////////////////////
     139static 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
     150assert( __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
     157assert( __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
     177uint32_t cycle = (uint32_t)hal_get_cycles();
     178printk("\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
     195uint32_t cycle = (uint32_t)hal_get_cycles();
     196printk("\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
     213uint32_t cycle = (uint32_t)hal_get_cycles();
     214printk("\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///////////////////////////////////////////////////////////////////////////////////////////
     239static 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///////////////////////////////////////////////////////////////////////////////////////////
     261static 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
    129270/////////////////////////////////////////////////////////////////////////////////////////
    130271// This static function registers the socket defined by the <socket_xp> argument into
     
    222363
    223364    // 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) );
    226369
    227370    // get pointers on NIC_RX[channel] chdev
     
    231374
    232375    // 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    }
    245396
    246397#if DEBUG_SOCKET_LINK
     
    253404}  // end socket_unlink_from_servers()
    254405       
     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/////////////////////////////////////////////////////////////////////////////////////////
     412static 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/////////////////////////////////////////////////////////////////////////////////////////
     443static 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
    255467/////////////////////////////////////////////////////////////////////////////////////////
    256468// This static function is called by the socket_build() and socket_accept() functions.
     
    276488                              uint32_t  * fdid_ptr )
    277489{
    278     uint32_t    fdid;
    279 
    280     thread_t  * this    = CURRENT_THREAD;
    281     process_t * process = this->process;
    282 
     490    uint32_t       fdid;
    283491    kmem_req_t     req;
    284492    socket_t     * socket;
     
    287495    error_t        error;
    288496
     497    thread_t  * this    = CURRENT_THREAD;
     498    process_t * process = this->process;
     499
    289500#if DEBUG_SOCKET_CREATE
    290501uint32_t cycle = (uint32_t)hal_get_cycles();
     
    294505#endif
    295506   
    296     // allocate memory for socket descriptor
     507    // 1. allocate memory for socket descriptor
    297508    req.type   = KMEM_KCM;
    298509    req.order  = bits_log2( sizeof(socket_t) );
     
    307518    }
    308519
    309     // allocate memory for rx_buf buffer
     520    // 2. allocate memory for rx_buf buffer
    310521    error = remote_buf_init( XPTR( cxy , &socket->rx_buf ),
    311                              NIC_RX_BUF_SIZE );
     522                             bits_log2( CONFIG_SOCK_RX_BUF_SIZE ) );
    312523
    313524    if( error )
     
    321532    }
    322533
    323     // allocate memory for r2tq queue
     534    // 3. allocate memory for r2tq queue
    324535    error = remote_buf_init( XPTR( cxy , &socket->r2tq ),
    325                              NIC_R2T_QUEUE_SIZE );
     536                             bits_log2( CONFIG_SOCK_R2T_BUF_SIZE ) );
    326537    if( error )
    327538    {
    328539        printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x]\n",
    329540        __FUNCTION__, process->pid, this->trdid );
    330         remote_buf_destroy( XPTR( cxy , &socket->rx_buf ) );
     541        remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );
    331542        req.type = KMEM_KCM;
    332543        req.ptr  = socket;
     
    337548    // don't allocate memory for crqq queue, as it is done by the socket_listen function
    338549
    339     //  allocate memory for file descriptor
     550    //  4. allocate memory for file descriptor
    340551        req.type  = KMEM_KCM;
    341552        req.order = bits_log2( sizeof(vfs_file_t) );
     
    347558        printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x]\n",
    348559        __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 ) );
    351562        req.type = KMEM_KCM;
    352563        req.ptr  = socket;
     
    355566    }
    356567   
    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[]
    358569    error = process_fd_register( process->ref_xp,
    359570                                 XPTR( cxy , file ),
     
    366577        req.ptr  = file;
    367578        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 ) );
    370581        req.ptr  = socket;
    371582        kmem_free( &req );
     
    388599
    389600    // 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 );
    391602    hal_remote_spt( XPTR( cxy , &file->socket      ) , socket );
    392     hal_remote_s32( XPTR( cxy , &file->refcount    ) , 1 );
    393603
    394604    // initialize socket lock
     
    414624// It remove the associated file from the reference process fd_array. It unlink the
    415625// 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 // socket descriptor, 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.
    418628/////////////////////////////////////////////////////////////////////////////////////////
    419629// @ file_xp  : extended pointer on the file descriptor.
     
    427637
    428638// check file_xp argument
    429 assert( (file_xp != XPTR_NULL), "illegal argument\n" );
     639assert( __FUNCTION__, (file_xp != XPTR_NULL), "illegal argument\n" );
    430640
    431641    // get cluster & local pointer for file descriptor
    432642    vfs_file_t * file_ptr = GET_PTR( file_xp );
    433643    cxy_t        file_cxy = GET_CXY( file_xp );
    434 
    435 #if DEBUG_SOCKET_DESTROY
    436 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 #endif
    441644
    442645    // get local pointer for socket and file type
     
    445648   
    446649// check file descriptor type
    447 assert( (file_type == INODE_TYPE_SOCK), "illegal file type\n" );
    448 
    449     // get socket nic_channel and fdid
    450     uint32_t channel = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel ));
     650assert( __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 ));
    451654    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
     657uint32_t cycle = (uint32_t)hal_get_cycles();
     658pid_t    pid   = hal_remote_l32( XPTR( file_cxy , &socket_ptr->pid ));
     659if( DEBUG_SOCKET_DESTROY < cycle )
     660printk("\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
    455671    {
    456672        socket_unlink_from_servers( XPTR( file_cxy , socket_ptr ) );
     
    466682
    467683    // 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 ) );
    471687
    472688    // release memory allocated for socket descriptor
     
    619835                 uint16_t  port )
    620836{
    621     vfs_inode_type_t    file_type;
     837    vfs_file_type_t    file_type;
    622838    socket_t          * socket;
    623839    uint32_t            socket_type;
     
    651867
    652868    // check file descriptor type
    653     if( file_type != INODE_TYPE_SOCK )
     869    if( file_type != FILE_TYPE_SOCK )
    654870    {
    655871        printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]",
     
    691907    vfs_file_t        * file_ptr;
    692908    cxy_t               file_cxy;
    693     vfs_inode_type_t    file_type;
     909    vfs_file_type_t    file_type;
    694910    socket_t          * socket_ptr;
    695911    uint32_t            socket_type;
     
    726942
    727943    // check file descriptor type
    728     if( file_type != INODE_TYPE_SOCK )
     944    if( file_type != FILE_TYPE_SOCK )
    729945    {
    730946        printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n",
     
    733949    }
    734950
    735     // get relevant infos from <fdid> socket descriptor
     951    // get relevant infos from socket descriptor
    736952    socket_type       = hal_remote_l32( XPTR( file_cxy , &socket_ptr->type ));
    737953    socket_state      = hal_remote_l32( XPTR( file_cxy , &socket_ptr->state ));
     
    755971    }
    756972   
    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;
    759976
    760977    // allocate memory for the CRQ queue
    761978    error = remote_buf_init( XPTR( file_cxy , &socket_ptr->crqq ),
    762                                    depth * sizeof(connect_request_t) );
     979                                   bits_log2( depth * sizeof(connect_request_t)) );
    763980    if( error )
    764981    {
     
    771988    hal_remote_s32( XPTR( file_cxy , &socket_ptr->state ) , TCP_STATE_LISTEN );
    772989
    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 ) );
    789992
    790993#if DEBUG_SOCKET_LISTEN
     
    8081011    vfs_file_t        * file_ptr;
    8091012    cxy_t               file_cxy;
    810     vfs_inode_type_t    file_type;           // file descriptor type
     1013    vfs_file_type_t    file_type;           // file descriptor type
    8111014    socket_t          * socket_ptr;          // local pointer on remote waiting socket
    8121015    uint32_t            socket_type;         // listening socket type   
     
    8661069
    8671070    // check file descriptor type
    868     if( file_type != INODE_TYPE_SOCK )
     1071    if( file_type != FILE_TYPE_SOCK )
    8691072    {
    8701073        printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n",
     
    9761179        crq_status   = remote_buf_status( crq_xp );
    9771180
    978 assert( (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)),
     1181assert( __FUNCTION__, (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)),
    9791182"illegal socket state when client thread resumes after RX_ACCEPT" );
    9801183
     
    9991202                                    &new_remote_window );
    10001203
    1001 assert( (error == 0),
     1204assert( __FUNCTION__, (error == 0),
    10021205"cannot get a connection request from a non-empty CRQ" );
    10031206
     
    10821285    // unblock NIC_TX server thread
    10831286    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
    10851291#if DEBUG_SOCKET_ACCEPT
    10861292cycle = (uint32_t)hal_get_cycles();
     
    11001306__FUNCTION__, process->pid, this->trdid, process->pid, new_fdid, cycle );
    11011307#endif
     1308
     1309    // stop retransmission timer
     1310    socket_alarm_stop();
    11021311
    11031312    // get new socket state, tx_valid and tx_sts
     
    11061315    cmd_status = hal_remote_l32( XPTR( new_socket_cxy , &new_socket_ptr->tx_sts ));
    11071316
    1108 assert( (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))
     1317assert( __FUNCTION__, (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))
    11091318        && (cmd_valid == false)),
    11101319"illegal socket state when client thread resumes after TX_ACCEPT" );
     
    11431352                    uint16_t remote_port )
    11441353{
    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
    11471357    volatile uint32_t   socket_state;     // socket state (modified by the NIC_TX thread)
    11481358    uint32_t            socket_type;      // socket type 
     
    11751385    file_type  = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
    11761386    socket_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->socket ) );
     1387    socket_xp  = XPTR( file_cxy , socket_ptr );
    11771388
    11781389#if DEBUG_SOCKET_CONNECT
     
    11841395
    11851396    // check file descriptor type
    1186     if( file_type != INODE_TYPE_SOCK )
     1397    if( file_type != FILE_TYPE_SOCK )
    11871398    {
    11881399        printk("\n[ERROR] in %s : illegal file type %s",
     
    12631474        thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT );
    12641475 
     1476        // start retransmission timer
     1477        socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1478
    12651479#if DEBUG_SOCKET_CONNECT
    12661480cycle = (uint32_t)hal_get_cycles();
     
    12791493__FUNCTION__, pid, trdid, pid, fdid, cycle );
    12801494#endif
     1495
     1496        // stop retransmission timer
     1497        socket_alarm_stop();
    12811498
    12821499        // get socket state, tx_valid and tx_sts
     
    12851502        socket_state = hal_remote_l32( XPTR( file_cxy , &socket_ptr->state ));
    12861503
    1287 assert( (((socket_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))
     1504assert( __FUNCTION__, (((socket_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))
    12881505        && (cmd_valid == false)),
    12891506"illegal socket state when client thread resumes after TX_CONNECT" );
     
    13311548    trdid_t      trdid     = this->trdid;
    13321549
    1333     // get pointer on socket descriptor
    1334     cxy_t        file_cxy    = GET_CXY( file_xp );
    1335     vfs_file_t * file_ptr    = GET_PTR( file_xp );
     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 );
    13361553    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
     1556assert( __FUNCTION__, (hal_remote_l32( XPTR( file_cxy , &socket_ptr->fdid )) == fdid),
    13391557"unconsistent file_xp & fdid arguments");
    13401558
     
    13801598cycle = (uint32_t)hal_get_cycles();
    13811599if( cycle > DEBUG_DEV_NIC_TX )
    1382 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s / destroy socket / cycle %d\n",
     1600printk("\n[%s] thread[%x,%x] socket[%x,%d] %s => directly destroy socket / cycle %d\n",
    13831601__FUNCTION__, pid, trdid, pid, fdid, socket_state_str( socket_state ), cycle );
    13841602#endif
     
    13961614cycle = (uint32_t)hal_get_cycles();
    13971615if( cycle > DEBUG_DEV_NIC_TX )
    1398 printk("\n[%s] thread[%x,%x] socket[%x,%d] %s / destroy socket / cycle %d\n",
     1616printk("\n[%s] thread[%x,%x] socket[%x,%d] %s => directly destroy socket / cycle %d\n",
    13991617__FUNCTION__, pid, trdid, pid, fdid, socket_state_str( socket_state ), cycle );
    14001618#endif
     
    14201638        hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_valid  ), true );
    14211639       
     1640        // release socket lock
     1641        remote_queuelock_release( socket_lock_xp );
     1642
    14221643        // unblock NIC_TX server thread
    14231644        thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT );
    1424  
    1425         // release socket lock
    1426         remote_queuelock_release( socket_lock_xp );
     1645
     1646        // start retransmission timer
     1647        socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
    14271648
    14281649#if DEBUG_SOCKET_CLOSE
    14291650cycle = (uint32_t)hal_get_cycles();
    14301651if( 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 deschedule
     1652printk("\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
    14351656        thread_block( client_xp , THREAD_BLOCKED_IO );
    14361657        sched_yield( "blocked in close" );
     
    14421663__FUNCTION__, pid, trdid, pid, fdid, cycle );
    14431664#endif
     1665        // stop retransmission timer
     1666        socket_alarm_stop();
     1667
    14441668        // take socket lock
    14451669        remote_queuelock_acquire( socket_lock_xp );
     
    14501674        cmd_valid    = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid ) );
    14511675
    1452 assert( (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS))
     1676assert( __FUNCTION__, (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS))
    14531677         && (cmd_valid == false)),
    14541678"illegal socket state when client thread resumes after TX_CLOSE\n"
     
    14831707
    14841708////////////////////////////////////////////////////////////////////////////////////////
    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().
    14871710// It can be used for both UDP and TCP sockets.
    14881711////////////////////////////////////////////////////////////////////////////////////////
     
    14911714// @ u_buf     : pointer on user buffer in user space.
    14921715// @ length    : number of bytes.
    1493 // @ explicit  : explicit remote IP address and port when true.
    14941716////////////////////////////////////////////////////////////////////////////////////////
    14951717// Implementation note : The behavior is different for SEND & RECV
     
    15121734                      uint32_t   fdid,
    15131735                      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
    15201740    socket_t          * socket_ptr;      // local pointer on socket descriptor
    15211741    uint32_t            socket_state;    // current socket state
     
    15291749    chdev_t           * chdev_ptr;
    15301750    cxy_t               chdev_cxy;
    1531     uint32_t            remote_addr;
    1532     uint32_t            remote_port;
    15331751    uint32_t            buf_status;      // number of bytes in rx_buf
    15341752    int32_t             moved_bytes;     // total number of moved bytes (fot return)
     
    15621780    file_type  = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
    15631781
    1564     // get local pointer on socket
     1782    // get pointers on socket
    15651783    socket_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->socket ) );
     1784    socket_xp  = XPTR( file_cxy , socket_ptr );
    15661785
    15671786    // check file descriptor type
    1568     if( file_type != INODE_TYPE_SOCK )
     1787    if( file_type != FILE_TYPE_SOCK )
    15691788    {
    15701789        printk("\n[ERROR] in %s : illegal file type %s / socket[%x,%d]\n",
     
    15841803    nic_channel  = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel ));
    15851804
    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
    16341807    {
    16351808
     
    16961869        thread_unblock( server_xp , THREAD_BLOCKED_CLIENT );
    16971870
     1871        // start retransmission timer
     1872        socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1873
    16981874#if DEBUG_SOCKET_SEND   
    16991875cycle = (uint32_t)hal_get_cycles();
     
    17121888__FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
    17131889#endif
     1890        // stop retransmission timer
     1891        socket_alarm_stop();
     1892
    17141893        // take socket lock
    17151894        remote_queuelock_acquire( socket_lock_xp );
     
    17271906     
    17281907// check SEND command completed when TX client thread resumes
    1729 assert( (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
     1908assert( __FUNCTION__, (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
    17301909"illegal socket state when client thread resumes after TX_SEND\n"
    17311910" tx_todo = %d / tx_status = %d / tx_valid = %d\n",
     
    17591938        }
    17601939
    1761     }  // end TX_SEND command
    1762 
    1763     ////////////////////////////////////////////////////////
    1764     else                                 // RX_RECV command
     1940    }  // end SEND command
     1941
     1942    ////
     1943    else                                 // RECV command
    17651944    {
    17661945
     
    18372016            buf_status = remote_buf_status( rx_buf_xp );
    18382017       
    1839 assert( (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
     2018assert( __FUNCTION__, (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
    18402019"illegal socket state when client thread resumes after RX_RECV\n"
    18412020" buf_status = %d / rx_sts = %d / rx_valid = %d\n",
     
    18912070        return moved_bytes;
    18922071
    1893     }  // end RX_RECV command
     2072    }  // end RECV command
    18942073} // end socket_move_data()
    1895 
    18962074
    18972075///////////////////////////////////
     
    19002078                 uint32_t    length )
    19012079{
    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 );
    19092084}  // 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,          // SEND
    1919                                    fdid,
    1920                                    u_buf,
    1921                                    length,
    1922                                    true,          // explicit remote socket
    1923                                    remote_addr,
    1924                                    remote_port );
    1925     return nbytes;
    1926 
    1927 }  // end socket_sendto()
    19282085
    19292086///////////////////////////////////
     
    19322089                 uint32_t    length )
    19332090{
    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 );
    19412095} // 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,         // RECV
    1952                                    fdid,
    1953                                    u_buf,
    1954                                    length,
    1955                                    true,          // explicit remote socket
    1956                                    remote_addr,
    1957                                    remote_port );
    1958     return nbytes;
    1959 
    1960 }  // end socket_recvfrom()
    19612096
    19622097////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.