aboutsummaryrefslogtreecommitdiffstats
path: root/slirp/mbuf.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit55f4e4a5ec657a017e3bf75299ad71fd1c968dd3 (patch)
tree550ce922ea0e125ac6a9738210ce2939bf2fe901 /slirp/mbuf.c
parent413f05aaf54fa08c0ae7e997327a4f4a473c0a8d (diff)
downloadexternal_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.zip
external_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.tar.gz
external_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.tar.bz2
Initial Contribution
Diffstat (limited to 'slirp/mbuf.c')
-rw-r--r--slirp/mbuf.c195
1 files changed, 118 insertions, 77 deletions
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 3769baf..efc8141 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -17,16 +17,28 @@
#include <slirp.h>
-struct mbuf *mbutl;
-char *mclrefcnt;
-int mbuf_alloced = 0;
-struct mbuf m_freelist, m_usedlist;
-int mbuf_thresh = 30;
-int mbuf_max = 0;
-int msize;
+static int mbuf_alloced = 0;
+static MBufRec m_freelist, m_usedlist;
+static int mbuf_thresh = 30;
+static int mbuf_max = 0;
+static int msize;
+
+/*
+ * How much room is in the mbuf, from m_data to the end of the mbuf
+ */
+#define M_ROOM(m) ((m->m_flags & M_EXT)? \
+ (((m)->m_ext + (m)->m_size) - (m)->m_data) \
+ : \
+ (((m)->m_dat + (m)->m_size) - (m)->m_data))
+
+/*
+ * How much free room there is
+ */
+#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)
+
void
-m_init()
+mbuf_init()
{
m_freelist.m_next = m_freelist.m_prev = &m_freelist;
m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
@@ -40,10 +52,27 @@ msize_init()
* Find a nice value for msize
* XXX if_maxlinkhdr already in mtu
*/
- msize = (if_mtu>if_mru?if_mtu:if_mru) +
+ msize = (if_mtu > if_mru ? if_mtu : if_mru) +
if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
}
+static void
+mbuf_insque(MBuf m, MBuf head)
+{
+ m->m_next = head->m_next;
+ m->m_prev = head;
+ head->m_next = m;
+ m->m_next->m_prev = m;
+}
+
+static void
+mbuf_remque(MBuf m)
+{
+ m->m_prev->m_next = m->m_next;
+ m->m_next->m_prev = m->m_prev;
+ m->m_next = m->m_prev = m;
+}
+
/*
* Get an mbuf from the free list, if there are none
* malloc one
@@ -52,16 +81,16 @@ msize_init()
* free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
* which tells m_free to actually free() it
*/
-struct mbuf *
-m_get()
+MBuf
+mbuf_alloc(void)
{
- register struct mbuf *m;
+ register MBuf m;
int flags = 0;
- DEBUG_CALL("m_get");
+ DEBUG_CALL("mbuf_alloc");
if (m_freelist.m_next == &m_freelist) {
- m = (struct mbuf *)malloc(msize);
+ m = (MBuf) malloc(msize);
if (m == NULL) goto end_error;
mbuf_alloced++;
if (mbuf_alloced > mbuf_thresh)
@@ -70,36 +99,35 @@ m_get()
mbuf_max = mbuf_alloced;
} else {
m = m_freelist.m_next;
- remque(m);
+ mbuf_remque(m);
}
/* Insert it in the used list */
- insque(m,&m_usedlist);
+ mbuf_insque(m,&m_usedlist);
m->m_flags = (flags | M_USEDLIST);
/* Initialise it */
- m->m_size = msize - sizeof(struct m_hdr);
- m->m_data = m->m_dat;
- m->m_len = 0;
- m->m_nextpkt = 0;
- m->m_prevpkt = 0;
+ m->m_size = msize - sizeof(struct m_hdr);
+ m->m_data = m->m_dat;
+ m->m_len = 0;
+ m->m_next2 = NULL;
+ m->m_prev2 = NULL;
end_error:
DEBUG_ARG("m = %lx", (long )m);
return m;
}
void
-m_free(m)
- struct mbuf *m;
+mbuf_free(MBuf m)
{
- DEBUG_CALL("m_free");
+ DEBUG_CALL("mbuf_free");
DEBUG_ARG("m = %lx", (long )m);
if(m) {
/* Remove from m_usedlist */
if (m->m_flags & M_USEDLIST)
- remque(m);
+ mbuf_remque(m);
/* If it's M_EXT, free() it */
if (m->m_flags & M_EXT)
@@ -112,7 +140,7 @@ m_free(m)
free(m);
mbuf_alloced--;
} else if ((m->m_flags & M_FREELIST) == 0) {
- insque(m,&m_freelist);
+ mbuf_insque(m,&m_freelist);
m->m_flags = M_FREELIST; /* Clobber other flags */
}
} /* if(m) */
@@ -124,74 +152,62 @@ m_free(m)
* an M_EXT data segment
*/
void
-m_cat(m, n)
- register struct mbuf *m, *n;
+mbuf_append(MBuf m, MBuf n)
{
/*
* If there's no room, realloc
*/
if (M_FREEROOM(m) < n->m_len)
- m_inc(m,m->m_size+MINCSIZE);
+ mbuf_ensure(m, m->m_size+MINCSIZE);
memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
m->m_len += n->m_len;
- m_free(n);
+ mbuf_free(n);
}
/* make m size bytes large */
void
-m_inc(m, size)
- struct mbuf *m;
- int size;
+mbuf_ensure(MBuf m, int size)
{
int datasize;
/* some compiles throw up on gotos. This one we can fake. */
- if(m->m_size>size) return;
-
- if (m->m_flags & M_EXT) {
- datasize = m->m_data - m->m_ext;
- m->m_ext = (char *)realloc(m->m_ext,size);
-/* if (m->m_ext == NULL)
- * return (struct mbuf *)NULL;
- */
- m->m_data = m->m_ext + datasize;
- } else {
- char *dat;
- datasize = m->m_data - m->m_dat;
- dat = (char *)malloc(size);
-/* if (dat == NULL)
- * return (struct mbuf *)NULL;
- */
- memcpy(dat, m->m_dat, m->m_size);
-
- m->m_ext = dat;
- m->m_data = m->m_ext + datasize;
- m->m_flags |= M_EXT;
- }
-
- m->m_size = size;
+ if(m->m_size > size) return;
+
+ if (m->m_flags & M_EXT) {
+ datasize = m->m_data - m->m_ext;
+ m->m_ext = (char *)realloc(m->m_ext,size);
+ m->m_data = m->m_ext + datasize;
+ } else {
+ char *dat;
+ datasize = m->m_data - m->m_dat;
+ dat = (char *)malloc(size);
+ memcpy(dat, m->m_dat, m->m_size);
+ m->m_ext = dat;
+ m->m_data = m->m_ext + datasize;
+ m->m_flags |= M_EXT;
+ }
+
+ m->m_size = size;
}
void
-m_adj(m, len)
- struct mbuf *m;
- int len;
+mbuf_trim(MBuf m, int len)
{
if (m == NULL)
return;
if (len >= 0) {
/* Trim from head */
m->m_data += len;
- m->m_len -= len;
+ m->m_len -= len;
} else {
/* Trim from tail */
- len = -len;
+ len = -len;
m->m_len -= len;
}
}
@@ -201,9 +217,7 @@ m_adj(m, len)
* Copy len bytes from m, starting off bytes into n
*/
int
-m_copy(n, m, off, len)
- struct mbuf *n, *m;
- int off, len;
+mbuf_copy(MBuf n, MBuf m, int off, int len)
{
if (len > M_FREEROOM(n))
return -1;
@@ -213,34 +227,61 @@ m_copy(n, m, off, len)
return 0;
}
+int
+mbuf_freeroom( MBuf m )
+{
+ return M_FREEROOM(m);
+}
/*
* Given a pointer into an mbuf, return the mbuf
* XXX This is a kludge, I should eliminate the need for it
* Fortunately, it's not used often
*/
-struct mbuf *
-dtom(dat)
- void *dat;
+MBuf
+mbuf_from(void* dat)
{
- struct mbuf *m;
+ MBuf m;
- DEBUG_CALL("dtom");
+ DEBUG_CALL("mbuf_from");
DEBUG_ARG("dat = %lx", (long )dat);
/* bug corrected for M_EXT buffers */
for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
if (m->m_flags & M_EXT) {
- if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
- return m;
+ if( (unsigned)((char*)dat - m->m_ext) < (unsigned)m->m_size )
+ goto Exit;
} else {
- if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
- return m;
+ if( (unsigned)((char *)dat - m->m_dat) < (unsigned)m->m_size )
+ goto Exit;
}
}
+ m = NULL;
+ DEBUG_ERROR((dfd, "mbuf_from failed"));
+Exit:
+ return m;
+}
+
+void
+mbufstats()
+{
+ MBuf m;
+ int i;
- DEBUG_ERROR((dfd, "dtom failed"));
+ lprint(" \r\n");
- return (struct mbuf *)0;
-}
+ lprint("Mbuf stats:\r\n");
+ lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
+
+ i = 0;
+ for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
+ i++;
+ lprint(" %6d mbufs on free list\r\n", i);
+
+ i = 0;
+ for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
+ i++;
+ lprint(" %6d mbufs on used list\r\n", i);
+ lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
+}