From 9e919c1cde77f017ee5759c2d225bf2ee046f80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 13 Sep 2013 21:42:32 +0200 Subject: [PATCH] Add mbuf documentation. have mbuf_free handle NULL pointer --- include/ucore/mbuf.h | 120 +++++++++++++++++++++++++++++++++++++++++-- src/mbuf.c | 12 +++-- 2 files changed, 124 insertions(+), 8 deletions(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 406f951..723d575 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -17,57 +17,171 @@ enum UC_MBUF_FLAGS { }; struct MBuf { + /** next pointer, user can use this for a linked list*/ struct MBuf *next; + /** Pointers the user can use to remember spots in + * the data. (these must either be NULL pointers or point into + * something in the buffer*/ uint8_t *p1; uint8_t *p2; uint8_t *p3; uint8_t *p4; + /**Arbitary pointer user can associate with the mbuf*/ void *cookie; + uint32_t flags; + /** Total no of bytes from bufstart*/ uint32_t allocated; + /** Start of the buffer*/ uint8_t *bufstart; + /** Start of the data in the buffer*/ uint8_t *head; + /** End of the buffer (one byte past the data) */ uint8_t *tail; + /** Internal data, if we allocate it inline */ uint8_t inline_data[0]; }; -/* Conventions: +/** + * Concept: + * <--------- allocated -----------> + * <--- len --> + * +--------------------------------+ + * |Headroom| Data |Tailroom | + * +--------------------------------+ + * ^ ^ ^ + * | | | + * | | tail + * | head + * bufstart + * + * Initially when empty, head == tail, and the length is 0. + * Data is added to the tail. + * + * If head == bufstart, there is no headroom + * if tail points one past the allocated space, there is no + * tailroom (the buffer is full) + * + * Conventions: * push - prepend data to the buffer (in the head room part) + * (move head to the left) * pull - remove data from the beginning of the message. + * (move head to the right) * put - Add data to the buffer. + * (move tail to the right) + */ + +/** Allocate an mbuf with a length and headroom, + * the buffer will have the flag UC_MBUF_FL_MALLOC + * The total length of the buffer will be length+headroom + * + * @param len the initial length of the mbuf + * @param the initial headroom of the mbuf + * @return NULL if the allocation fails */ struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom); + +/** As uc_mbuf_new_hr, but without any headroom*/ #define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0) + +/** Allocate an mbuf with a length and headroom, + * the buffer will have the flag UC_MBUF_FL_MALLOC_INLINE + * The total length of the buffer will be length+headroom + * + * @param len the initial length of the mbuf + * @param the initial headroom of the mbuf + * @return NULL if the allocation fails + */ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom); + +/** As uc_mbuf_new_inline_hr, but without any headroom*/ #define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0) +/** @param mbuf the mbuf to free. (passing NULL is a no-op)*/ void uc_mbuf_free(struct MBuf *mbuf); + +/** Create a new mbuf, with a copy of the data from the given + * mbuf. The new mbuf will have the same headroom as the old one. + * + * @param mbuf mbuf to copy + */ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf); +/** Initialize an mbuf. This function is mostly used internally, + * but can be used to e.g. create an mbuf based on a local array + * (in which case UC_MBUF_FL_STATIC must be set), or other data + * whose memory is already allocated. + * + * The whole buffer must have len + headroom available data + * + * @param mbuf to initialise + * @param buf start of the buffer + * @param len length of the buffer (not including the headroom) + * @param headroom the headroom in the buffer + * @param flags The appropriate UC_MBUF_FLAGS + */ void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags); -void uc_mbuf_zero(struct MBuf *mbuf); -void uc_mbuf_reset(struct MBuf *mbuf); +/** Zero out all the data in this mbuf, including the headroom + * + * @param mbuf mbuf to zero out + */ +void uc_mbuf_zero(struct MBuf *mbuf); + +/** + * @return the length of the data in this mbuf + */ static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf) { return (uint32_t)(mbuf->tail - mbuf->head); } +/** + * @return the length of the tailroom in this mbuf + */ static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf) { return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart); } +/** + * @return the length of the headroom in this mbuf + */ static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf) { return (uint32_t)(mbuf->head - mbuf->bufstart); } + +/** Append data data to this buffer + * The returned pointer points at the end of the current + * data in the buffer, advancing the tail be size bytes . + * You need to insert the size bytes at in the returned pointer. + * + * @param size bytes to put in the buffer + * @return NULL if the mbuf does not have room for the given size + */ uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size); +/** Prepend data to the buffer. The buffer needs to have enough + * headroom to allow this. + * The returned pointer points size bytes in front if the current + * data in the buffer, retreating the head pointer by size butes + * You need to insert the size bytes in the returned pointer. + * + * @oaram size bytes to prepend to the buffer + * @return NULL if the mbuf does not have enough headroom + */ uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size); +/** Remove data from the buffer ("read" data from it) + * The returned pointer is the beginning of the data in the + * buffer, advancing the head by size bytes. + * + * @param size number of bytes to pull + * @return NULL if the buffer does not have at least size bytes + **/ uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size); #undef UC_INLINE diff --git a/src/mbuf.c b/src/mbuf.c index 6d735ab..865612a 100644 --- a/src/mbuf.c +++ b/src/mbuf.c @@ -86,11 +86,13 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom) void uc_mbuf_free(struct MBuf *mbuf) { - if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF)) - free(mbuf->bufstart); - - if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE)) - free(mbuf); + if (mbuf != NULL) { + if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF)) + free(mbuf->bufstart); + + if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE)) + free(mbuf); + } } void uc_mbuf_zero(struct MBuf *mbuf)