Free (GPLv2) TCP/IP stack developed by TASS Belgium
Fork of PicoTCP by
include/pico_queue.h@51:18637a3d071f, 2013-08-03 (annotated)
- Committer:
- daniele
- Date:
- Sat Aug 03 08:50:27 2013 +0000
- Revision:
- 51:18637a3d071f
- Parent:
- 29:1a47b7151851
Branch for CDC-ECM: Work in progress
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
daniele | 29:1a47b7151851 | 1 | /********************************************************************* |
daniele | 29:1a47b7151851 | 2 | PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. |
daniele | 29:1a47b7151851 | 3 | See LICENSE and COPYING for usage. |
daniele | 29:1a47b7151851 | 4 | |
daniele | 29:1a47b7151851 | 5 | *********************************************************************/ |
daniele | 29:1a47b7151851 | 6 | #ifndef _INCLUDE_PICO_QUEUE |
daniele | 29:1a47b7151851 | 7 | #define _INCLUDE_PICO_QUEUE |
daniele | 29:1a47b7151851 | 8 | #include <stdint.h> |
daniele | 29:1a47b7151851 | 9 | #include "pico_config.h" |
daniele | 29:1a47b7151851 | 10 | #include "pico_frame.h" |
daniele | 29:1a47b7151851 | 11 | |
daniele | 29:1a47b7151851 | 12 | #define Q_LIMIT 0 |
daniele | 29:1a47b7151851 | 13 | |
daniele | 29:1a47b7151851 | 14 | #ifndef NULL |
daniele | 29:1a47b7151851 | 15 | #define NULL ((void *)0) |
daniele | 29:1a47b7151851 | 16 | #endif |
daniele | 29:1a47b7151851 | 17 | |
daniele | 29:1a47b7151851 | 18 | struct pico_queue { |
daniele | 29:1a47b7151851 | 19 | uint32_t frames; |
daniele | 29:1a47b7151851 | 20 | uint32_t size; |
daniele | 29:1a47b7151851 | 21 | uint32_t max_frames; |
daniele | 29:1a47b7151851 | 22 | uint32_t max_size; |
daniele | 29:1a47b7151851 | 23 | struct pico_frame *head; |
daniele | 29:1a47b7151851 | 24 | struct pico_frame *tail; |
daniele | 29:1a47b7151851 | 25 | #ifdef PICO_SUPPORT_MUTEX |
daniele | 29:1a47b7151851 | 26 | void * mutex; |
daniele | 29:1a47b7151851 | 27 | #endif |
daniele | 29:1a47b7151851 | 28 | uint8_t shared; |
daniele | 29:1a47b7151851 | 29 | }; |
daniele | 29:1a47b7151851 | 30 | |
daniele | 29:1a47b7151851 | 31 | #ifdef PICO_SUPPORT_MUTEX |
daniele | 29:1a47b7151851 | 32 | #define LOCK(x) {\ |
daniele | 29:1a47b7151851 | 33 | if (x == NULL) \ |
daniele | 29:1a47b7151851 | 34 | x = pico_mutex_init(); \ |
daniele | 29:1a47b7151851 | 35 | pico_mutex_lock(x); \ |
daniele | 29:1a47b7151851 | 36 | } |
daniele | 29:1a47b7151851 | 37 | #define UNLOCK(x) pico_mutex_unlock(x); |
daniele | 29:1a47b7151851 | 38 | |
daniele | 29:1a47b7151851 | 39 | #else |
daniele | 29:1a47b7151851 | 40 | #define LOCK(x) do{}while(0) |
daniele | 29:1a47b7151851 | 41 | #define UNLOCK(x) do{}while(0) |
daniele | 29:1a47b7151851 | 42 | #endif |
daniele | 29:1a47b7151851 | 43 | |
daniele | 29:1a47b7151851 | 44 | #ifdef PICO_SUPPORT_DEBUG_TOOLS |
daniele | 29:1a47b7151851 | 45 | static void debug_q(struct pico_queue *q) |
daniele | 29:1a47b7151851 | 46 | { |
daniele | 29:1a47b7151851 | 47 | struct pico_frame *p = q->head; |
daniele | 29:1a47b7151851 | 48 | dbg("%d: ", q->frames); |
daniele | 29:1a47b7151851 | 49 | while(p) { |
daniele | 29:1a47b7151851 | 50 | dbg("(%p)-->", p); |
daniele | 29:1a47b7151851 | 51 | p = p->next; |
daniele | 29:1a47b7151851 | 52 | } |
daniele | 29:1a47b7151851 | 53 | dbg("X\n"); |
daniele | 29:1a47b7151851 | 54 | } |
daniele | 29:1a47b7151851 | 55 | |
daniele | 29:1a47b7151851 | 56 | #else |
daniele | 29:1a47b7151851 | 57 | |
daniele | 29:1a47b7151851 | 58 | #define debug_q(x) do{}while(0) |
daniele | 29:1a47b7151851 | 59 | #endif |
daniele | 29:1a47b7151851 | 60 | |
daniele | 29:1a47b7151851 | 61 | static inline int pico_enqueue(struct pico_queue *q, struct pico_frame *p) |
daniele | 29:1a47b7151851 | 62 | { |
daniele | 29:1a47b7151851 | 63 | if ((q->max_frames) && (q->max_frames <= q->frames)) |
daniele | 29:1a47b7151851 | 64 | return -1; |
daniele | 29:1a47b7151851 | 65 | |
daniele | 29:1a47b7151851 | 66 | if ((Q_LIMIT) && (Q_LIMIT < p->buffer_len + q->size)) |
daniele | 29:1a47b7151851 | 67 | return -1; |
daniele | 29:1a47b7151851 | 68 | |
daniele | 29:1a47b7151851 | 69 | if ((q->max_size) && (q->max_size < (p->buffer_len + q->size))) |
daniele | 29:1a47b7151851 | 70 | return -1; |
daniele | 29:1a47b7151851 | 71 | |
daniele | 29:1a47b7151851 | 72 | if (q->shared) |
daniele | 29:1a47b7151851 | 73 | LOCK(q->mutex); |
daniele | 29:1a47b7151851 | 74 | |
daniele | 29:1a47b7151851 | 75 | p->next = NULL; |
daniele | 29:1a47b7151851 | 76 | if (!q->head) { |
daniele | 29:1a47b7151851 | 77 | q->head = p; |
daniele | 29:1a47b7151851 | 78 | q->tail = p; |
daniele | 29:1a47b7151851 | 79 | q->size = 0; |
daniele | 29:1a47b7151851 | 80 | q->frames = 0; |
daniele | 29:1a47b7151851 | 81 | } else { |
daniele | 29:1a47b7151851 | 82 | q->tail->next = p; |
daniele | 29:1a47b7151851 | 83 | q->tail = p; |
daniele | 29:1a47b7151851 | 84 | } |
daniele | 29:1a47b7151851 | 85 | q->size += p->buffer_len; |
daniele | 29:1a47b7151851 | 86 | q->frames++; |
daniele | 29:1a47b7151851 | 87 | debug_q(q); |
daniele | 29:1a47b7151851 | 88 | |
daniele | 29:1a47b7151851 | 89 | if (q->shared) |
daniele | 29:1a47b7151851 | 90 | UNLOCK(q->mutex); |
daniele | 29:1a47b7151851 | 91 | return q->size; |
daniele | 29:1a47b7151851 | 92 | } |
daniele | 29:1a47b7151851 | 93 | |
daniele | 29:1a47b7151851 | 94 | static inline struct pico_frame *pico_dequeue(struct pico_queue *q) |
daniele | 29:1a47b7151851 | 95 | { |
daniele | 29:1a47b7151851 | 96 | struct pico_frame *p = q->head; |
daniele | 29:1a47b7151851 | 97 | if (q->frames < 1) |
daniele | 29:1a47b7151851 | 98 | return NULL; |
daniele | 29:1a47b7151851 | 99 | if (q->shared) |
daniele | 29:1a47b7151851 | 100 | LOCK(q->mutex); |
daniele | 29:1a47b7151851 | 101 | |
daniele | 29:1a47b7151851 | 102 | q->head = p->next; |
daniele | 29:1a47b7151851 | 103 | q->frames--; |
daniele | 29:1a47b7151851 | 104 | q->size -= p->buffer_len; |
daniele | 29:1a47b7151851 | 105 | if (q->head == NULL) |
daniele | 29:1a47b7151851 | 106 | q->tail = NULL; |
daniele | 29:1a47b7151851 | 107 | debug_q(q); |
daniele | 29:1a47b7151851 | 108 | p->next = NULL; |
daniele | 29:1a47b7151851 | 109 | if (q->shared) |
daniele | 29:1a47b7151851 | 110 | UNLOCK(q->mutex); |
daniele | 29:1a47b7151851 | 111 | return p; |
daniele | 29:1a47b7151851 | 112 | } |
daniele | 29:1a47b7151851 | 113 | |
daniele | 29:1a47b7151851 | 114 | static inline struct pico_frame *pico_queue_peek(struct pico_queue *q) |
daniele | 29:1a47b7151851 | 115 | { |
daniele | 29:1a47b7151851 | 116 | struct pico_frame *p = q->head; |
daniele | 29:1a47b7151851 | 117 | if (q->frames < 1) |
daniele | 29:1a47b7151851 | 118 | return NULL; |
daniele | 29:1a47b7151851 | 119 | debug_q(q); |
daniele | 29:1a47b7151851 | 120 | return p; |
daniele | 29:1a47b7151851 | 121 | } |
daniele | 29:1a47b7151851 | 122 | |
daniele | 29:1a47b7151851 | 123 | static inline void pico_queue_empty(struct pico_queue *q) |
daniele | 29:1a47b7151851 | 124 | { |
daniele | 29:1a47b7151851 | 125 | struct pico_frame *p = pico_dequeue(q); |
daniele | 29:1a47b7151851 | 126 | while(p) { |
daniele | 29:1a47b7151851 | 127 | pico_free(p); |
daniele | 29:1a47b7151851 | 128 | p = pico_dequeue(q); |
daniele | 29:1a47b7151851 | 129 | } |
daniele | 29:1a47b7151851 | 130 | } |
daniele | 29:1a47b7151851 | 131 | |
daniele | 29:1a47b7151851 | 132 | static inline void pico_queue_protect(struct pico_queue *q) |
daniele | 29:1a47b7151851 | 133 | { |
daniele | 29:1a47b7151851 | 134 | q->shared = 1; |
daniele | 29:1a47b7151851 | 135 | } |
daniele | 29:1a47b7151851 | 136 | |
daniele | 29:1a47b7151851 | 137 | #endif |