mirror of
https://github.com/google/pebble.git
synced 2025-06-01 07:53:11 +00:00
108 lines
3.9 KiB
C
108 lines
3.9 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
/*
|
|
* Generally, an mbuf is a header for a buffer which adds some useful functionality with regards to
|
|
* grouping multiple distinct buffers together into a single packet. They are primarily used for
|
|
* networking. As you go down a tradditional network stack, headers need to be added to the data.
|
|
* Rather than having to allocate and copy every time a new header needs to be added, or forcing the
|
|
* upper layer to leave room for the header, mbufs allows for buffers to be chained together into an
|
|
* mbuf chain. With mbufs, as you go down the stack, you simply add the headers as new mbufs at the
|
|
* start of the chain. Then, the lowest layer can simply walk through the chain to get the content
|
|
* of the entire packet, and no copying is necessary at any point in the process. Going up the stack
|
|
* works the same way, except that MBufs are removed as you go up the stack instead of added.
|
|
*
|
|
* This is a very basic implementation of the mbuf type found in FreeBSD. If you're interested in
|
|
* learning more about real mbufs, the FreeBSD man page is a good read:
|
|
* https://www.freebsd.org/cgi/man.cgi?query=mbuf&sektion=9
|
|
*
|
|
* For the purposes of this implementation, MBuf headers are of a fixed size with a single pointer
|
|
* to the data which the header is responsible for. Linking multiple MBuf chains together is not
|
|
* supported.
|
|
*/
|
|
|
|
//! Helper macro for clearing an MBuf
|
|
#define MBUF_EMPTY ((MBuf){ 0 })
|
|
|
|
//! Flags used by consumers of MBufs (bits 0-23 are allocated for this purpose)
|
|
#define MBUF_FLAG_IS_FRAMING ((uint32_t)(1 << 0))
|
|
|
|
|
|
//! Consumers of MBufs which use mbuf_get() should add an enum value and add the maximum number of
|
|
//! MBufs which may be allocated for that pool to the MBUF_POOL_MAX_ALLOCATED array within mbuf.c.
|
|
typedef enum {
|
|
MBufPoolSmartstrap,
|
|
#if UNITTEST
|
|
MBufPoolUnitTest,
|
|
#endif
|
|
NumMBufPools
|
|
} MBufPool;
|
|
|
|
typedef struct MBuf {
|
|
//! The next MBuf in the chain
|
|
struct MBuf *next;
|
|
//! A pointer to the data itself
|
|
void *data;
|
|
//! The length of the data
|
|
uint32_t length;
|
|
//! Flags which are used by the consumers of MBufs
|
|
uint32_t flags;
|
|
} MBuf;
|
|
|
|
//! Initializes the MBuf code (called from main.c)
|
|
void mbuf_init(void);
|
|
|
|
//! Returns a new heap-allocated MBuf (either from an internal pool or by allocating a new one)
|
|
MBuf *mbuf_get(void *data, uint32_t length, MBufPool pool);
|
|
|
|
//! Frees an MBuf which was created via mbuf_get()
|
|
void mbuf_free(MBuf *m);
|
|
|
|
//! Sets the data and length fields of an MBuf
|
|
void mbuf_set_data(MBuf *m, void *data, uint32_t length);
|
|
|
|
//! Returns the data for the MBuf
|
|
void *mbuf_get_data(MBuf *m);
|
|
|
|
//! Returns whether or not the specified flag is set
|
|
bool mbuf_is_flag_set(MBuf *m, uint32_t flag);
|
|
|
|
//! Sets the specified flag to the specified value
|
|
void mbuf_set_flag(MBuf *m, uint32_t flag, bool is_set);
|
|
|
|
//! Gets the next MBuf in the chain
|
|
MBuf *mbuf_get_next(MBuf *m);
|
|
|
|
//! Gets the length of the specified MBuf (NOT the entire chain)
|
|
uint32_t mbuf_get_length(MBuf *m);
|
|
|
|
//! Gets the total number of bytes in the MBuf chain
|
|
uint32_t mbuf_get_chain_length(MBuf *m);
|
|
|
|
//! Appends a new MBuf chain to the end of the chain
|
|
void mbuf_append(MBuf *m, MBuf *new_mbuf);
|
|
|
|
//! Removes any MBufs in the chain after the specified one
|
|
void mbuf_clear_next(MBuf *m);
|
|
|
|
//! Dump an MBuf chain to dbgserial
|
|
void mbuf_debug_dump(MBuf *m);
|