00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <adt/dynamic_fifo.h>
00038
00039 #include <errno.h>
00040 #include <malloc.h>
00041 #include <mem.h>
00042
00044 #define DYN_FIFO_MAGIC_VALUE 0x58627659
00045
00053 #define NEXT_INDEX(fifo, index) (((index) + 1) % ((fifo)->size + 1))
00054
00061 static int dyn_fifo_is_valid(dyn_fifo_t *fifo)
00062 {
00063 return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE);
00064 }
00065
00075 int dyn_fifo_initialize(dyn_fifo_t *fifo, int size)
00076 {
00077 if (!fifo)
00078 return EBADMEM;
00079
00080 if (size <= 0)
00081 return EINVAL;
00082
00083 fifo->items = (int *) malloc(sizeof(int) * size + 1);
00084 if (!fifo->items)
00085 return ENOMEM;
00086
00087 fifo->size = size;
00088 fifo->head = 0;
00089 fifo->tail = 0;
00090 fifo->magic_value = DYN_FIFO_MAGIC_VALUE;
00091
00092 return EOK;
00093 }
00094
00106 int dyn_fifo_push(dyn_fifo_t *fifo, int value, int max_size)
00107 {
00108 int *new_items;
00109
00110 if (!dyn_fifo_is_valid(fifo))
00111 return EINVAL;
00112
00113 if (NEXT_INDEX(fifo, fifo->tail) == fifo->head) {
00114 if ((max_size > 0) && ((fifo->size * 2) > max_size)) {
00115 if(fifo->size >= max_size)
00116 return ENOMEM;
00117 } else {
00118 max_size = fifo->size * 2;
00119 }
00120
00121 new_items = realloc(fifo->items, sizeof(int) * max_size + 1);
00122 if (!new_items)
00123 return ENOMEM;
00124
00125 fifo->items = new_items;
00126 if (fifo->tail < fifo->head) {
00127 if (fifo->tail < max_size - fifo->size) {
00128 memcpy(fifo->items + fifo->size + 1,
00129 fifo->items, fifo->tail * sizeof(int));
00130 fifo->tail += fifo->size + 1;
00131 } else {
00132 memcpy(fifo->items + fifo->size + 1,
00133 fifo->items,
00134 (max_size - fifo->size) * sizeof(int));
00135 memcpy(fifo->items,
00136 fifo->items + max_size - fifo->size,
00137 fifo->tail - max_size + fifo->size);
00138 fifo->tail -= max_size - fifo->size;
00139 }
00140 }
00141 fifo->size = max_size;
00142 }
00143
00144 fifo->items[fifo->tail] = value;
00145 fifo->tail = NEXT_INDEX(fifo, fifo->tail);
00146 return EOK;
00147 }
00148
00156 int dyn_fifo_pop(dyn_fifo_t *fifo)
00157 {
00158 int value;
00159
00160 if (!dyn_fifo_is_valid(fifo))
00161 return EINVAL;
00162
00163 if (fifo->head == fifo->tail)
00164 return ENOENT;
00165
00166 value = fifo->items[fifo->head];
00167 fifo->head = NEXT_INDEX(fifo, fifo->head);
00168 return value;
00169 }
00170
00178 int dyn_fifo_value(dyn_fifo_t *fifo)
00179 {
00180 if (!dyn_fifo_is_valid(fifo))
00181 return EINVAL;
00182
00183 if (fifo->head == fifo->tail)
00184 return ENOENT;
00185
00186 return fifo->items[fifo->head];
00187 }
00188
00195 int dyn_fifo_destroy(dyn_fifo_t *fifo)
00196 {
00197 if (!dyn_fifo_is_valid(fifo))
00198 return EINVAL;
00199
00200 free(fifo->items);
00201 fifo->magic_value = 0;
00202 return EOK;
00203 }
00204