Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset bbf159a in mainline


Ignore:
Timestamp:
2011-12-13T17:06:25Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
7a8c1c4e
Parents:
0d29e0cd
Message:

Eliminate busy waiting when TCP send buffer is full.

Location:
uspace/srv/net/tl/tcp
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/conn.c

    r0d29e0cd rbbf159a  
    9393
    9494        /** Allocate send buffer */
     95        fibril_mutex_initialize(&conn->snd_buf_lock);
     96        fibril_condvar_initialize(&conn->snd_buf_cv);
    9597        conn->snd_buf_size = SND_BUF_SIZE;
    9698        conn->snd_buf_used = 0;
     
    287289
    288290        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     291        fibril_condvar_broadcast(&conn->snd_buf_cv);
    289292}
    290293
  • uspace/srv/net/tl/tcp/tcp_type.h

    r0d29e0cd rbbf159a  
    204204        /** Send buffer contains FIN */
    205205        bool snd_buf_fin;
     206        /** Send buffer lock */
     207        fibril_mutex_t snd_buf_lock;
     208        /** Send buffer CV. Broadcast when space is made available in buffer */
     209        fibril_condvar_t snd_buf_cv;
    206210
    207211        /** Send unacknowledged */
  • uspace/srv/net/tl/tcp/tqueue.c

    r0d29e0cd rbbf159a  
    167167        log_msg(LVL_DEBUG, "%s: tcp_tqueue_new_data()", conn->name);
    168168
     169        fibril_mutex_lock(&conn->snd_buf_lock);
     170
    169171        /* Number of free sequence numbers in send window */
    170172        avail_wnd = (conn->snd_una + conn->snd_wnd) - conn->snd_nxt;
     
    176178            xfer_seqlen);
    177179
    178         if (xfer_seqlen == 0)
    179                 return;
     180        if (xfer_seqlen == 0) {
     181                fibril_mutex_unlock(&conn->snd_buf_lock);
     182                return;
     183        }
    180184
    181185        /* XXX Do not always send immediately */
     
    188192                /* We are sending out FIN */
    189193                ctrl = CTL_FIN;
    190                 tcp_conn_fin_sent(conn);
    191194        } else {
    192195                ctrl = 0;
     
    195198        seg = tcp_segment_make_data(ctrl, conn->snd_buf, data_size);
    196199        if (seg == NULL) {
     200                fibril_mutex_unlock(&conn->snd_buf_lock);
    197201                log_msg(LVL_ERROR, "Memory allocation failure.");
    198202                return;
     
    206210        if (send_fin)
    207211                conn->snd_buf_fin = false;
     212
     213        fibril_condvar_broadcast(&conn->snd_buf_cv);
     214        fibril_mutex_unlock(&conn->snd_buf_lock);
     215
     216        if (send_fin)
     217                tcp_conn_fin_sent(conn);
    208218
    209219        tcp_tqueue_seg(conn, seg);
  • uspace/srv/net/tl/tcp/ucall.c

    r0d29e0cd rbbf159a  
    121121        }
    122122
    123         if (conn->snd_buf_fin)
     123        fibril_mutex_lock(&conn->snd_buf_lock);
     124
     125        if (conn->snd_buf_fin) {
     126                fibril_mutex_unlock(&conn->snd_buf_lock);
    124127                return TCP_ECLOSING;
     128        }
    125129
    126130        while (size > 0) {
    127131                buf_free = conn->snd_buf_size - conn->snd_buf_used;
    128132                while (buf_free == 0 && !conn->reset) {
    129                         tcp_tqueue_new_data(conn);
     133                        log_msg(LVL_DEBUG, "%s: buf_free == 0, waiting.",
     134                            conn->name);
     135                        fibril_condvar_wait(&conn->snd_buf_cv,
     136                            &conn->snd_buf_lock);
    130137                        buf_free = conn->snd_buf_size - conn->snd_buf_used;
    131138                }
    132139
    133                 if (conn->reset)
     140                if (conn->reset) {
     141                        fibril_mutex_unlock(&conn->snd_buf_lock);
    134142                        return TCP_ERESET;
     143                }
    135144
    136145                xfer_size = min(size, buf_free);
     
    141150                conn->snd_buf_used += xfer_size;
    142151                size -= xfer_size;
    143         }
    144 
     152
     153                fibril_mutex_unlock(&conn->snd_buf_lock);
     154                tcp_tqueue_new_data(conn);
     155                fibril_mutex_lock(&conn->snd_buf_lock);
     156        }
     157
     158        fibril_mutex_unlock(&conn->snd_buf_lock);
    145159        tcp_tqueue_new_data(conn);
    146160
Note: See TracChangeset for help on using the changeset viewer.