2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation version 2 of the License.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15 * Most ideas and some code are copied from the linux' kernels
16 * include/linux/skbuff.h
19 #ifndef __TOOLS_FRAME_H
20 #define __TOOLS_FRAME_H
26 * struct frame_queue - sk_buff_head like frame queue
28 * @list: pointer to head and tail
29 * @lock: mutex lock for serialize access
30 * @len: exact number of queued frames
34 struct list_head list;
40 * struct frame - frame data structure (like sk_buff)
42 * @list: storage for double-linked &struct frame_queue list
43 * @dev: pointer to private device/driver structure
44 * @timestamp: space for the current timestamp
45 * @cb: private driver data
46 * @dcb: more reserved space for low-level / backend driver
47 * @queue: selected frame queue / priority
48 * @ref: reference counter
49 * @alloced: maximum available space
50 * @total_len: currently consumed and reserved memory
51 * @len: current frame length
52 * @head: points to the buffer head
53 * @data: current frame data pointer
54 * @tail: frame data tail pointer
55 * @payload: frame data storage container
59 struct list_head list;
61 unsigned long timestamp;
64 struct list_head list;
71 unsigned int total_len;
77 /* payload must be the last entry */
82 * frame_put - append more data to &struct frame
84 * Allocate @size bytes from &struct frame tail and
85 * returns a pointer to the requested location.
87 * @frame: frame to alter
90 static inline void *frame_put(struct frame *frame, unsigned int size)
94 BUG_ON(frame->total_len + size > frame->alloced);
97 frame->total_len += size;
99 tmp = (void *) frame->tail;
102 BUG_ON(frame->tail > (frame->payload + frame->alloced));
108 * frame_push - allocate head
110 * returns a pointer to a newly allocate area at &struct frame head.
112 * @frame: frame to modify
113 * @size: requested extra size
115 static inline void *frame_push(struct frame *frame, unsigned int size)
120 BUG_ON(frame->data < frame->payload);
125 * frame_get - reference frame buffer
127 * grab a reference from the frame buffer, in order to
128 * prevent it from being freed prematurely by a different user.
130 * @frame: frame pointer
132 static inline struct frame *frame_get(struct frame *frame)
139 * frame_pull - remove space from &struct frame head
141 * Does the opposite of frame_push() and removes freed-up
142 * space at the frames's head.
144 * @frame: pointer to frame structure
145 * @size: bytes to remove from head
147 static inline void *frame_pull(struct frame *frame, unsigned int size)
149 BUG_ON(frame->len < size);
152 frame->total_len -= size;
159 * frame_reserve - reserve frame headroom
161 * Reserve a certain amount of space to allow headroom manipulations
164 * @frame: frame to adjust
165 * @size: bytes to reserve
167 static inline void frame_reserve(struct frame *frame, unsigned int size)
169 BUG_ON(frame->total_len + size > frame->alloced);
170 BUG_ON(frame->len != 0);
172 frame->total_len += size;
178 * frame_trim - set frame length
180 * cut the frame to @size length.
182 * @frame: frame to be trimmed
185 static inline void frame_trim(struct frame *frame, unsigned int size)
187 BUG_ON(size > frame->total_len);
190 frame->total_len = size;
191 frame->data = frame->head;
192 frame->tail = frame->head + size;
196 * frame_alloc - alloc and initialize new frame
198 * returns a newly created &struct frame object.
200 * @size: maximum frame size of the new frame
202 static inline struct frame *frame_alloc(unsigned int size)
206 tmp = malloc(size + sizeof(*tmp));
208 memset(tmp, 0, sizeof(*tmp));
209 init_list_head(&tmp->list);
210 init_list_head(&tmp->dcb.list);
215 tmp->head = tmp->payload;
216 tmp->data = tmp->payload;
217 tmp->tail = tmp->payload;
224 * frame_free - unref and free frame
226 * Unreference frame and free it up, if all users are gone.
228 * @frame: frame to be freed
230 static inline void frame_free(struct frame *frame)
237 * FRAME_WALK - MACRO walker
239 * Walks over all queued elements in &struct frame_queue
241 * NOTE: This function is vulnerable in concurrent access
242 * scenarios without proper locking.
244 * @pos: current position inside the queue
245 * @head: &struct frame_queue head
247 #define FRAME_WALK(pos, head) \
248 list_for_each_entry((pos), &(head)->list, list)
250 static inline void __frame_queue_init(struct frame_queue *queue)
253 init_list_head(&queue->list);
257 * frame_queue_init - initialize frame_queue
259 * Initialize the given &struct frame_queue object.
261 * @queue: frame_queue to be initialized
263 static inline void frame_queue_init(struct frame_queue *queue)
265 queue->lock = SDL_CreateMutex();
266 __frame_queue_init(queue);
270 * frame_queue_len - returns number of queue elements
272 * @queue: frame_queue object
274 static inline unsigned int frame_queue_len(struct frame_queue *queue)
280 * frame_queue_empty - returns %TRUE whenever queue is empty
282 * @queue: frame_queue object
284 static inline bool frame_queue_empty(struct frame_queue *queue)
286 return list_empty(&queue->list);
289 static inline void __frame_queue_head(struct frame_queue *queue, struct frame *frame)
291 list_add_head(&frame->list, &queue->list);
296 * frame_queue_head - queue a frame at the queues head
297 * @queue: queue to use
299 static inline void frame_queue_head(struct frame_queue *queue, struct frame *frame)
301 BUG_ON((SDL_mutexP(queue->lock) != 0));
302 __frame_queue_head(queue, frame);
303 SDL_mutexV(queue->lock);
306 static inline void __frame_queue_tail(struct frame_queue *queue, struct frame *frame)
308 list_add_tail(&frame->list, &queue->list);
313 * frame_queue_head - queue a frame at the queues tail
314 * @queue: queue to use
316 static inline void frame_queue_tail(struct frame_queue *queue, struct frame *frame)
318 BUG_ON((SDL_mutexP(queue->lock) != 0));
319 __frame_queue_tail(queue, frame);
320 SDL_mutexV(queue->lock);
323 static inline void __frame_unlink(struct frame_queue *queue, struct frame *frame)
325 list_del(&frame->list);
330 * frame_queue_unlink - remove a frame from the queue
331 * @queue: queue to use
332 * @frame: frame to remove
334 static inline void frame_unlink(struct frame_queue *queue, struct frame *frame)
336 BUG_ON((SDL_mutexP(queue->lock) != 0));
337 __frame_unlink(queue, frame);
338 SDL_mutexV(queue->lock);
342 static inline struct frame *__frame_dequeue(struct frame_queue *queue)
344 struct frame *tmp = NULL;
346 if (!frame_queue_empty(queue)) {
347 tmp = list_entry(queue->list.next, struct frame, list);
348 __frame_unlink(queue, tmp);
355 * frame_dequeue - remove frame from the head of the queue
357 * @queue: queue to dequeue from
359 static inline struct frame *frame_dequeue(struct frame_queue *queue)
363 BUG_ON((SDL_mutexP(queue->lock) != 0));
365 tmp = __frame_dequeue(queue);
366 SDL_mutexV(queue->lock);
370 static inline void __frame_queue_purge(struct frame_queue *queue)
372 while (list_empty(&queue->list) == false)
373 frame_free(__frame_dequeue(queue));
377 * frame_queue_purge - frees all queued &struct frame objects
379 * @queue: queue to be freed
381 static inline void frame_queue_purge(struct frame_queue *queue)
383 BUG_ON((SDL_mutexP(queue->lock) != 0));
384 __frame_queue_purge(queue);
385 SDL_mutexV(queue->lock);
389 * frame_queue_kill - destroys frame_queue object
391 * Destroy object and frees up all remaining elements
393 * @queue: frame_queue victim
395 static inline void frame_queue_kill(struct frame_queue *queue)
397 SDL_DestroyMutex(queue->lock);
398 __frame_queue_purge(queue);
401 #endif /* __TOOLS_FRAME_H */