VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/sbuf.c@ 20377

最後變更 在這個檔案從20377是 20377,由 vboxsync 提交於 16 年 前

NAT: sbuf perfomance counters

  • 屬性 svn:eol-style 設為 native
檔案大小: 5.5 KB
 
1/*
2 * Copyright (c) 1995 Danny Gasparovski.
3 *
4 * Please read the file COPYRIGHT for the
5 * terms and conditions of the copyright.
6 */
7
8#include <slirp.h>
9
10/* Done as a macro in socket.h */
11/* int
12 * sbspace(struct sockbuff *sb)
13 * {
14 * return SB_DATALEN - sb->sb_cc;
15 * }
16 */
17
18void
19sbfree(struct sbuf *sb)
20{
21 RTMemFree(sb->sb_data);
22}
23
24void
25sbdrop(struct sbuf *sb, int num)
26{
27 /*
28 * We can only drop how much we have
29 * This should never succeed
30 */
31 if (num > sb->sb_cc)
32 num = sb->sb_cc;
33 sb->sb_cc -= num;
34 sb->sb_rptr += num;
35 if (sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
36 sb->sb_rptr -= sb->sb_datalen;
37
38}
39
40void
41sbreserve(PNATState pData, struct sbuf *sb, int size)
42{
43 if (sb->sb_data)
44 {
45 /* Already alloced, realloc if necessary */
46 if (sb->sb_datalen != size)
47 {
48 sb->sb_wptr =
49 sb->sb_rptr =
50 sb->sb_data = (char *)RTMemRealloc(sb->sb_data, size);
51 sb->sb_cc = 0;
52 if (sb->sb_wptr)
53 sb->sb_datalen = size;
54 else
55 sb->sb_datalen = 0;
56 }
57 }
58 else
59 {
60 sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)RTMemAlloc(size);
61 sb->sb_cc = 0;
62 if (sb->sb_wptr)
63 sb->sb_datalen = size;
64 else
65 sb->sb_datalen = 0;
66 }
67}
68
69/*
70 * Try and write() to the socket, whatever doesn't get written
71 * append to the buffer... for a host with a fast net connection,
72 * this prevents an unnecessary copy of the data
73 * (the socket is non-blocking, so we won't hang)
74 */
75void
76sbappend(PNATState pData, struct socket *so, struct mbuf *m)
77{
78 int ret = 0;
79
80 DEBUG_CALL("sbappend");
81 DEBUG_ARG("so = %lx", (long)so);
82 DEBUG_ARG("m = %lx", (long)m);
83 DEBUG_ARG("m->m_len = %d", m->m_len);
84
85 SLIRP_COUNTER_RESET(IOSBAppend);
86 SLIRP_COUNTER_RESET(IOSBAppend_zm);
87 SLIRP_COUNTER_RESET(IOSBAppend_wa);
88 SLIRP_COUNTER_RESET(IOSBAppend_wf);
89 SLIRP_COUNTER_RESET(IOSBAppend_wp);
90
91 SLIRP_COUNTER_INC(IOSBAppend);
92 /* Shouldn't happen, but... e.g. foreign host closes connection */
93 if (m->m_len <= 0)
94 {
95 SLIRP_COUNTER_INC(IOSBAppend_zm);
96 goto done;
97 }
98
99 /*
100 * If there is urgent data, call sosendoob
101 * if not all was sent, sowrite will take care of the rest
102 * (The rest of this function is just an optimisation)
103 */
104 if (so->so_urgc)
105 {
106 sbappendsb(pData, &so->so_rcv, m);
107 m_free(pData, m);
108 sosendoob(so);
109 return;
110 }
111
112 /*
113 * We only write if there's nothing in the buffer,
114 * ottherwise it'll arrive out of order, and hence corrupt
115 */
116 if (!so->so_rcv.sb_cc)
117 ret = send(so->s, m->m_data, m->m_len, 0);
118
119 if (ret <= 0)
120 {
121 SLIRP_COUNTER_INC(IOSBAppend_wf);
122 /*
123 * Nothing was written
124 * It's possible that the socket has closed, but
125 * we don't need to check because if it has closed,
126 * it will be detected in the normal way by soread()
127 */
128 sbappendsb(pData, &so->so_rcv, m);
129 goto done;
130 }
131 else if (ret != m->m_len)
132 {
133 SLIRP_COUNTER_INC(IOSBAppend_wp);
134 /*
135 * Something was written, but not everything..
136 * sbappendsb the rest
137 */
138 m->m_len -= ret;
139 m->m_data += ret;
140 sbappendsb(pData, &so->so_rcv, m);
141 goto done;
142 } /* else */
143 /* Whatever happened, we free the mbuf */
144 SLIRP_COUNTER_INC(IOSBAppend_wa);
145done:
146 m_free(pData, m);
147}
148
149/*
150 * Copy the data from m into sb
151 * The caller is responsible to make sure there's enough room
152 */
153void
154sbappendsb(PNATState pData, struct sbuf *sb, struct mbuf *m)
155{
156 int len, n, nn;
157
158 len = m->m_len;
159
160 SLIRP_COUNTER_RESET(IOSBAppendSB);
161 SLIRP_COUNTER_RESET(IOSBAppendSB_w_l_r);
162 SLIRP_COUNTER_RESET(IOSBAppendSB_w_ge_r);
163 SLIRP_COUNTER_RESET(IOSBAppendSB_w_alter);
164
165 SLIRP_COUNTER_INC(IOSBAppendSB);
166 if (sb->sb_wptr < sb->sb_rptr)
167 {
168 SLIRP_COUNTER_INC(IOSBAppendSB_w_l_r);
169 n = sb->sb_rptr - sb->sb_wptr;
170 if (n > len)
171 n = len;
172 memcpy(sb->sb_wptr, m->m_data, n);
173 }
174 else
175 {
176 SLIRP_COUNTER_INC(IOSBAppendSB_w_ge_r);
177 /* Do the right edge first */
178 n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
179 if (n > len)
180 n = len;
181 memcpy(sb->sb_wptr, m->m_data, n);
182 len -= n;
183 if (len)
184 {
185 /* Now the left edge */
186 nn = sb->sb_rptr - sb->sb_data;
187 if (nn > len)
188 nn = len;
189 memcpy(sb->sb_data, m->m_data+n, nn);
190 n += nn;
191 }
192 }
193
194 sb->sb_cc += n;
195 sb->sb_wptr += n;
196 if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
197 {
198 SLIRP_COUNTER_INC(IOSBAppendSB_w_alter);
199 sb->sb_wptr -= sb->sb_datalen;
200 }
201}
202
203/*
204 * Copy data from sbuf to a normal, straight buffer
205 * Don't update the sbuf rptr, this will be
206 * done in sbdrop when the data is acked
207 */
208void
209sbcopy(struct sbuf *sb, int off, int len, char *to)
210{
211 char *from;
212
213 from = sb->sb_rptr + off;
214 if (from >= sb->sb_data + sb->sb_datalen)
215 from -= sb->sb_datalen;
216
217 if (from < sb->sb_wptr)
218 {
219 if (len > sb->sb_cc)
220 len = sb->sb_cc;
221 memcpy(to, from, len);
222 }
223 else
224 {
225 /* re-use off */
226 off = (sb->sb_data + sb->sb_datalen) - from;
227 if (off > len)
228 off = len;
229 memcpy(to, from, off);
230 len -= off;
231 if (len)
232 memcpy(to+off, sb->sb_data, len);
233 }
234}
235
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette