RetroArch
Macros | Functions | Variables
pbuf.c File Reference
#include <string.h>
#include "lwip/opt.h"
#include "lwip/stats.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "arch/perf.h"
Include dependency graph for pbuf.c:

Macros

#define DEC_PBUF_STATS
 
#define PBUF_POOL_FAST_FREE(p)
 
#define PBUF_POOL_FREE(p)
 

Functions

void pbuf_init (void)
 
static struct pbufpbuf_pool_alloc (void)
 
struct pbufpbuf_alloc (pbuf_layer l, u16_t length, pbuf_flag flag)
 
void pbuf_realloc (struct pbuf *p, u16_t new_len)
 
u8_t pbuf_header (struct pbuf *p, s16_t header_size_increment)
 
u8_t pbuf_free (struct pbuf *p)
 
u8_t pbuf_clen (struct pbuf *p)
 
void pbuf_ref (struct pbuf *p)
 
void pbuf_cat (struct pbuf *h, struct pbuf *t)
 
void pbuf_chain (struct pbuf *h, struct pbuf *t)
 
struct pbufpbuf_take (struct pbuf *p)
 
struct pbufpbuf_dechain (struct pbuf *p)
 

Variables

static u8_t pbuf_pool_memory [MEM_ALIGNMENT - 1+PBUF_POOL_SIZE *MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE+sizeof(struct pbuf))]
 
static volatile u8_t pbuf_pool_free_lock
 
static volatile u8_t pbuf_pool_alloc_lock
 
static sys_sem pbuf_pool_free_sem
 
static struct pbufpbuf_pool = NULL
 

Detailed Description

Packet buffer management

Packets are built from the pbuf data structure. It supports dynamic memory allocation for packet contents or can reference externally managed packet contents both in RAM and ROM. Quick allocation for incoming packets is provided through pools with fixed sized pbufs.

A packet may span over multiple pbufs, chained as a singly linked list. This is called a "pbuf chain".

Multiple packets may be queued, also using this singly linked list. This is called a "packet queue".

So, a packet queue consists of one or more pbuf chains, each of which consist of one or more pbufs. Currently, queues are only supported in a limited section of lwIP, this is the etharp queueing code. Outside of this section no packet queues are supported yet.

The differences between a pbuf chain and a packet queue are very precise but subtle.

The last pbuf of a packet has a ->tot_len field that equals the ->len field. It can be found by traversing the list. If the last pbuf of a packet has a ->next field other than NULL, more packets are on the queue.

Therefore, looping through a pbuf of a single packet, has an loop end condition (tot_len == p->len), NOT (next == NULL).

Macro Definition Documentation

◆ DEC_PBUF_STATS

#define DEC_PBUF_STATS

◆ PBUF_POOL_FAST_FREE

#define PBUF_POOL_FAST_FREE (   p)
Value:
do { \
p->next = pbuf_pool; \
pbuf_pool = p; \
DEC_PBUF_STATS; \
} while (0)
GLfloat GLfloat p
Definition: glext.h:9809
static struct pbuf * pbuf_pool
Definition: pbuf.c:83

◆ PBUF_POOL_FREE

#define PBUF_POOL_FREE (   p)
Value:
do { \
LWP_SemWait(pbuf_pool_free_sem); \
PBUF_POOL_FAST_FREE(p); \
LWP_SemPost(pbuf_pool_free_sem); \
} while (0)
GLfloat GLfloat p
Definition: glext.h:9809
static sys_sem pbuf_pool_free_sem
Definition: pbuf.c:80

Function Documentation

◆ pbuf_alloc()

struct pbuf* pbuf_alloc ( pbuf_layer  l,
u16_t  length,
pbuf_flag  flag 
)

Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).

The actual memory allocated for the pbuf is determined by the layer at which the pbuf is allocated and the requested size (from the size parameter).

Parameters
flagthis parameter decides how and where the pbuf should be allocated as follows:
  • PBUF_RAM: buffer memory for pbuf is allocated as one large chunk. This includes protocol headers as well.
  • PBUF_ROM: no buffer memory is allocated for the pbuf, even for protocol headers. Additional headers must be prepended by allocating another pbuf and chain in to the front of the ROM pbuf. It is assumed that the memory used is really similar to ROM in that it is immutable and will not be changed. Memory which is dynamic should generally not be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  • PBUF_REF: no buffer memory is allocated for the pbuf, even for protocol headers. It is assumed that the pbuf is only being used in a single thread. If the pbuf gets queued, then pbuf_take should be called to copy the buffer.
  • PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from the pbuf pool that is allocated during pbuf_init().
Returns
the allocated pbuf. If multiple pbufs where allocated, this is the first pbuf of a pbuf chain.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pbuf_cat()

void pbuf_cat ( struct pbuf h,
struct pbuf t 
)

Concatenate two pbufs (each may be a pbuf chain) and take over the caller's reference of the tail pbuf.

Note
The caller MAY NOT reference the tail pbuf afterwards. Use pbuf_chain() for that purpose.
See also
pbuf_chain()
Here is the caller graph for this function:

◆ pbuf_chain()

void pbuf_chain ( struct pbuf h,
struct pbuf t 
)

Chain two pbufs (or pbuf chains) together.

The caller MUST call pbuf_free(t) once it has stopped using it. Use pbuf_cat() instead if you no longer use t.

Parameters
hhead pbuf (chain)
ttail pbuf (chain)
Note
The pbufs MUST belong to the same packet.
MAY NOT be called on a packet queue.

The ->tot_len fields of all pbufs of the head chain are adjusted. The ->next field of the last pbuf of the head chain is adjusted. The ->ref field of the first pbuf of the tail chain is adjusted.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pbuf_clen()

u8_t pbuf_clen ( struct pbuf p)

Count number of pbufs in a chain

Parameters
pfirst pbuf of chain
Returns
the number of pbufs in a chain

◆ pbuf_dechain()

struct pbuf* pbuf_dechain ( struct pbuf p)

Dechains the first pbuf from its succeeding pbufs in the chain.

Makes p->tot_len field equal to p->len.

Parameters
ppbuf to dechain
Returns
remainder of the pbuf chain, or NULL if it was de-allocated.
Note
May not be called on a packet queue.
Here is the call graph for this function:

◆ pbuf_free()

u8_t pbuf_free ( struct pbuf p)

Dereference a pbuf chain or queue and deallocate any no-longer-used pbufs at the head of this chain or queue.

Decrements the pbuf reference count. If it reaches zero, the pbuf is deallocated.

For a pbuf chain, this is repeated for each pbuf in the chain, up to the first pbuf which has a non-zero reference count after decrementing. So, when all reference counts are one, the whole chain is free'd.

Parameters
pbufThe pbuf (chain) to be dereferenced.
Returns
the number of pbufs that were de-allocated from the head of the chain.
Note
MUST NOT be called on a packet queue (Not verified to work yet).
the reference counter of a pbuf equals the number of pointers that refer to the pbuf (or into the pbuf).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pbuf_header()

u8_t pbuf_header ( struct pbuf p,
s16_t  header_size_increment 
)

Adjusts the payload pointer to hide or reveal headers in the payload.

Adjusts the ->payload pointer so that space for a header (dis)appears in the pbuf payload.

The ->payload, ->tot_len and ->len fields are adjusted.

Parameters
hdr_size_incNumber of bytes to increment header size which increases the size of the pbuf. New space is on the front. (Using a negative value decreases the header size.) If hdr_size_inc is 0, this function does nothing and returns succesful.

PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so the call will fail. A check is made that the increase in header size does not move the payload pointer in front of the start of the buffer.

Returns
non-zero on failure, zero on success.
Here is the caller graph for this function:

◆ pbuf_init()

void pbuf_init ( void  )

Initializes the pbuf module.

A large part of memory is allocated for holding the pool of pbufs. The size of the individual pbufs in the pool is given by the size parameter, and the number of pbufs in the pool by the num parameter.

After the memory has been allocated, the pbufs are set up. The ->next pointer in each pbuf is set up to point to the next pbuf in the pool.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pbuf_pool_alloc()

static struct pbuf* pbuf_pool_alloc ( void  )
static
Here is the caller graph for this function:

◆ pbuf_realloc()

void pbuf_realloc ( struct pbuf p,
u16_t  new_len 
)

Shrink a pbuf chain to a desired length.

Parameters
ppbuf to shrink.
new_lendesired new length of pbuf chain

Depending on the desired length, the first few pbufs in a chain might be skipped and left unchanged. The new last pbuf in the chain will be resized, and any remaining pbufs will be freed.

Note
If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
May not be called on a packet queue.
Bug:
Cannot grow the size of a pbuf (chain) (yet).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pbuf_ref()

void pbuf_ref ( struct pbuf p)

Increment the reference count of the pbuf.

Parameters
ppbuf to increase reference counter of
Here is the caller graph for this function:

◆ pbuf_take()

struct pbuf* pbuf_take ( struct pbuf p)

Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.

Used to queue packets on behalf of the lwIP stack, such as ARP based queueing.

Go through a pbuf chain and replace any PBUF_REF buffers with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of the referenced data.

Note
You MUST explicitly use p = pbuf_take(p); The pbuf you give as argument, may have been replaced by a (differently located) copy through pbuf_take()!
Any replaced pbufs will be freed through pbuf_free(). This may deallocate them if they become no longer referenced.
Parameters
pHead of pbuf chain to process
Returns
Pointer to head of pbuf chain
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ pbuf_pool

struct pbuf* pbuf_pool = NULL
static

◆ pbuf_pool_alloc_lock

volatile u8_t pbuf_pool_alloc_lock
static

◆ pbuf_pool_free_lock

volatile u8_t pbuf_pool_free_lock
static

◆ pbuf_pool_free_sem

sys_sem pbuf_pool_free_sem
static

◆ pbuf_pool_memory

u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1+PBUF_POOL_SIZE *MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE+sizeof(struct pbuf))]
static