You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/11/20 23:45:36 UTC

incubator-mynewt-larva git commit: Implement os_mbuf_prepend().

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 34a6d69f2 -> 15a6aef47


Implement os_mbuf_prepend().


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/15a6aef4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/15a6aef4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/15a6aef4

Branch: refs/heads/master
Commit: 15a6aef478fbf01139c7a17014bbab3df4c29623
Parents: 34a6d69
Author: Christopher Collins <cc...@gmail.com>
Authored: Fri Nov 20 14:43:49 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Fri Nov 20 14:45:26 2015 -0800

----------------------------------------------------------------------
 libs/os/include/os/os_mbuf.h |  2 ++
 libs/os/src/os_mbuf.c        | 66 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/15a6aef4/libs/os/include/os/os_mbuf.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h
index 289e739..d056730 100644
--- a/libs/os/include/os/os_mbuf.h
+++ b/libs/os/include/os/os_mbuf.h
@@ -224,5 +224,7 @@ void os_mbuf_adj(struct os_mbuf_pool *omp, struct os_mbuf *mp, int req_len);
 int os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data,
                    int len);
 
+struct os_mbuf *os_mbuf_prepend(struct os_mbuf_pool *omp, struct os_mbuf *om,
+                                int len);
 
 #endif /* _OS_MBUF_H */ 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/15a6aef4/libs/os/src/os_mbuf.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_mbuf.c b/libs/os/src/os_mbuf.c
index 75f9074..0b51793 100644
--- a/libs/os/src/os_mbuf.c
+++ b/libs/os/src/os_mbuf.c
@@ -522,6 +522,72 @@ os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data, int len)
     }
 }
 
+/**
+ * Increases the length of an mbuf chain by adding data to the front.  If there
+ * is insufficient room in the leading mbuf, additional mbufs are allocated and
+ * prepended as necessary.  If this function fails to allocate an mbuf, the
+ * entire chain is freed.
+ *
+ * The specified mbuf chain does not need to contain a packet header.
+ *
+ * @param omp                   The mbuf pool to allocate from.
+ * @param om                    The head of the mbuf chain.
+ * @param len                   The number of bytes to prepend.
+ *
+ * @return                      The new head of the chain on success;
+ *                              NULL on failure.
+ */
+struct os_mbuf *
+os_mbuf_prepend(struct os_mbuf_pool *omp, struct os_mbuf *om, int len)
+{
+    struct os_mbuf *p;
+    int leading;
+
+    while (1) {
+        /* Fill the available space at the front of the head of the chain, as
+         * needed.
+         */
+        leading = min(len, OS_MBUF_LEADINGSPACE(omp, om));
+
+        om->om_data -= leading;
+        om->om_len += leading;
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            OS_MBUF_PKTHDR(om)->omp_len += leading;
+        }
+
+        len -= leading;
+        if (len == 0) {
+            break;
+        }
+
+        /* The current head didn't have enough space; allocate a new head. */
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            p = os_mbuf_get_pkthdr(omp);
+        } else {
+            p = os_mbuf_get(omp, 0);
+        }
+        if (p == NULL) {
+            os_mbuf_free_chain(omp, om);
+            om = NULL;
+            break;
+        }
+
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            _os_mbuf_copypkthdr(omp, p, om);
+            om->om_flags &= ~OS_MBUF_F_PKTHDR;
+        }
+
+        /* Move the new head's data pointer to the end so that data can be
+         * prepended.
+         */
+        p->om_data += OS_MBUF_TRAILINGSPACE(omp, p);
+
+        SLIST_NEXT(p, om_next) = om;
+        om = p;
+    }
+
+    return om;
+}
 
 #if 0