iPXE
iobuf.h
Go to the documentation of this file.
1 #ifndef _IPXE_IOBUF_H
2 #define _IPXE_IOBUF_H
3 
4 /** @file
5  *
6  * I/O buffers
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <assert.h>
14 #include <ipxe/list.h>
15 
16 /**
17  * Minimum I/O buffer length
18  *
19  * alloc_iob() will round up the allocated length to this size if
20  * necessary. This is used on behalf of hardware that is not capable
21  * of auto-padding.
22  */
23 #define IOB_ZLEN 128
24 
25 /**
26  * A persistent I/O buffer
27  *
28  * This data structure encapsulates a long-lived I/O buffer. The
29  * buffer may be passed between multiple owners, queued for possible
30  * retransmission, etc.
31  */
32 struct io_buffer {
33  /** List of which this buffer is a member
34  *
35  * The list must belong to the current owner of the buffer.
36  * Different owners may maintain different lists (e.g. a
37  * retransmission list for TCP).
38  */
39  struct list_head list;
40 
41  /** Start of the buffer */
42  void *head;
43  /** Start of data */
44  void *data;
45  /** End of data */
46  void *tail;
47  /** End of the buffer */
48  void *end;
49 };
50 
51 /**
52  * Reserve space at start of I/O buffer
53  *
54  * @v iobuf I/O buffer
55  * @v len Length to reserve
56  * @ret data Pointer to new start of buffer
57  */
58 static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) {
59  iobuf->data += len;
60  iobuf->tail += len;
61  return iobuf->data;
62 }
63 #define iob_reserve( iobuf, len ) ( { \
64  void *__result; \
65  __result = iob_reserve ( (iobuf), (len) ); \
66  assert ( (iobuf)->tail <= (iobuf)->end ); \
67  __result; } )
68 
69 /**
70  * Add data to start of I/O buffer
71  *
72  * @v iobuf I/O buffer
73  * @v len Length to add
74  * @ret data Pointer to new start of buffer
75  */
76 static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) {
77  iobuf->data -= len;
78  return iobuf->data;
79 }
80 #define iob_push( iobuf, len ) ( { \
81  void *__result; \
82  __result = iob_push ( (iobuf), (len) ); \
83  assert ( (iobuf)->data >= (iobuf)->head ); \
84  __result; } )
85 
86 /**
87  * Remove data from start of I/O buffer
88  *
89  * @v iobuf I/O buffer
90  * @v len Length to remove
91  * @ret data Pointer to new start of buffer
92  */
93 static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) {
94  iobuf->data += len;
95  assert ( iobuf->data <= iobuf->tail );
96  return iobuf->data;
97 }
98 #define iob_pull( iobuf, len ) ( { \
99  void *__result; \
100  __result = iob_pull ( (iobuf), (len) ); \
101  assert ( (iobuf)->data <= (iobuf)->tail ); \
102  __result; } )
103 
104 /**
105  * Add data to end of I/O buffer
106  *
107  * @v iobuf I/O buffer
108  * @v len Length to add
109  * @ret data Pointer to newly added space
110  */
111 static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) {
112  void *old_tail = iobuf->tail;
113  iobuf->tail += len;
114  return old_tail;
115 }
116 #define iob_put( iobuf, len ) ( { \
117  void *__result; \
118  __result = iob_put ( (iobuf), (len) ); \
119  assert ( (iobuf)->tail <= (iobuf)->end ); \
120  __result; } )
121 
122 /**
123  * Remove data from end of I/O buffer
124  *
125  * @v iobuf I/O buffer
126  * @v len Length to remove
127  */
128 static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) {
129  iobuf->tail -= len;
130 }
131 #define iob_unput( iobuf, len ) do { \
132  iob_unput ( (iobuf), (len) ); \
133  assert ( (iobuf)->tail >= (iobuf)->data ); \
134  } while ( 0 )
135 
136 /**
137  * Empty an I/O buffer
138  *
139  * @v iobuf I/O buffer
140  */
141 static inline void iob_empty ( struct io_buffer *iobuf ) {
142  iobuf->tail = iobuf->data;
143 }
144 
145 /**
146  * Calculate length of data in an I/O buffer
147  *
148  * @v iobuf I/O buffer
149  * @ret len Length of data in buffer
150  */
151 static inline size_t iob_len ( struct io_buffer *iobuf ) {
152  return ( iobuf->tail - iobuf->data );
153 }
154 
155 /**
156  * Calculate available space at start of an I/O buffer
157  *
158  * @v iobuf I/O buffer
159  * @ret len Length of data available at start of buffer
160  */
161 static inline size_t iob_headroom ( struct io_buffer *iobuf ) {
162  return ( iobuf->data - iobuf->head );
163 }
164 
165 /**
166  * Calculate available space at end of an I/O buffer
167  *
168  * @v iobuf I/O buffer
169  * @ret len Length of data available at end of buffer
170  */
171 static inline size_t iob_tailroom ( struct io_buffer *iobuf ) {
172  return ( iobuf->end - iobuf->tail );
173 }
174 
175 /**
176  * Create a temporary I/O buffer
177  *
178  * @v iobuf I/O buffer
179  * @v data Data buffer
180  * @v len Length of data
181  * @v max_len Length of buffer
182  *
183  * It is sometimes useful to use the iob_xxx() methods on temporary
184  * data buffers.
185  */
186 static inline void iob_populate ( struct io_buffer *iobuf,
187  void *data, size_t len, size_t max_len ) {
188  iobuf->head = iobuf->data = data;
189  iobuf->tail = ( data + len );
190  iobuf->end = ( data + max_len );
191 }
192 
193 /**
194  * Disown an I/O buffer
195  *
196  * @v iobuf I/O buffer
197  *
198  * There are many functions that take ownership of the I/O buffer they
199  * are passed as a parameter. The caller should not retain a pointer
200  * to the I/O buffer. Use iob_disown() to automatically nullify the
201  * caller's pointer, e.g.:
202  *
203  * xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
204  *
205  * This will ensure that iobuf is set to NULL for any code after the
206  * call to xfer_deliver_iob().
207  */
208 #define iob_disown( iobuf ) ( { \
209  struct io_buffer *__iobuf = (iobuf); \
210  (iobuf) = NULL; \
211  __iobuf; } )
212 
213 extern struct io_buffer * __malloc alloc_iob_raw ( size_t len, size_t align,
214  size_t offset );
215 extern struct io_buffer * __malloc alloc_iob ( size_t len );
216 extern void free_iob ( struct io_buffer *iobuf );
217 extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
218 extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
219 extern struct io_buffer * iob_concatenate ( struct list_head *list );
220 extern struct io_buffer * iob_split ( struct io_buffer *iobuf, size_t len );
221 
222 #endif /* _IPXE_IOBUF_H */
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
#define iob_put(iobuf, len)
Definition: iobuf.h:116
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition: iobuf.c:198
static void size_t size_t max_len
Definition: entropy.h:153
#define iob_push(iobuf, len)
Definition: iobuf.h:80
static void iob_populate(struct io_buffer *iobuf, void *data, size_t len, size_t max_len)
Create a temporary I/O buffer.
Definition: iobuf.h:186
A doubly-linked list entry (or list head)
Definition: list.h:18
void * tail
End of data.
Definition: iobuf.h:46
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void size_t min_len
Definition: entropy.h:152
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static void iob_empty(struct io_buffer *iobuf)
Empty an I/O buffer.
Definition: iobuf.h:141
struct io_buffer *__malloc alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
Linked lists.
#define iob_unput(iobuf, len)
Definition: iobuf.h:131
struct io_buffer * iob_split(struct io_buffer *iobuf, size_t len)
Split I/O buffer.
Definition: iobuf.c:246
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:171
void * end
End of the buffer.
Definition: iobuf.h:48
struct io_buffer *__malloc alloc_iob_raw(size_t len, size_t align, size_t offset)
Allocate I/O buffer with specified alignment and offset.
Definition: iobuf.c:48
#define iob_reserve(iobuf, len)
Definition: iobuf.h:63
static size_t iob_headroom(struct io_buffer *iobuf)
Calculate available space at start of an I/O buffer.
Definition: iobuf.h:161
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
uint32_t len
Length.
Definition: ena.h:14
#define __malloc
Declare a pointer returned by a function as a unique memory address as returned by malloc-type functi...
Definition: compiler.h:598
void * head
Start of the buffer.
Definition: iobuf.h:42
void * data
Start of data.
Definition: iobuf.h:44
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition: iobuf.c:183
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition: iobpad.c:49
A persistent I/O buffer.
Definition: iobuf.h:32