source: mainline/uspace/srv/net/structures/dynamic_fifo.c@ aadf01e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since aadf01e was aadf01e, checked in by Lukas Mejdrech <lukasmejdrech@…>, 15 years ago

Coding style (no functional change)

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net
30 * @{
31 */
32
33/** @file
34 * Dynamic first in first out positive integer queue implementation.
35 */
36
37#include <errno.h>
38#include <malloc.h>
39#include <mem.h>
40
41#include "dynamic_fifo.h"
42
43/** Internal magic value for a&nbsp;consistency check.
44 */
45#define DYN_FIFO_MAGIC_VALUE 0x58627659
46
47/** Returns the next queue index.
48 * The queue field is circular.
49 * @param[in] fifo The dynamic queue.
50 * @param[in] index The actual index to be shifted.
51 */
52#define NEXT_INDEX(fifo, index) (((index) + 1) % ((fifo)->size + 1))
53
54/** Checks if the queue is valid.
55 * @param[in] fifo The dynamic queue.
56 * @returns TRUE if the queue is valid.
57 * @returns FALSE otherwise.
58 */
59int dyn_fifo_is_valid(dyn_fifo_ref fifo);
60
61int dyn_fifo_is_valid(dyn_fifo_ref fifo){
62 return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE);
63}
64
65int dyn_fifo_initialize(dyn_fifo_ref fifo, int size){
66 if(! fifo){
67 return EBADMEM;
68 }
69 if(size <= 0){
70 return EINVAL;
71 }
72 fifo->items = (int *) malloc(sizeof(int) * size + 1);
73 if(! fifo->items){
74 return ENOMEM;
75 }
76 fifo->size = size;
77 fifo->head = 0;
78 fifo->tail = 0;
79 fifo->magic_value = DYN_FIFO_MAGIC_VALUE;
80 return EOK;
81}
82
83int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size){
84 int * new_items;
85
86 if(! dyn_fifo_is_valid(fifo)){
87 return EINVAL;
88 }
89 if(NEXT_INDEX(fifo, fifo->tail) == fifo->head){
90 if((max_size > 0) && ((fifo->size * 2) > max_size)){
91 if(fifo->size >= max_size){
92 return ENOMEM;
93 }
94 }else{
95 max_size = fifo->size * 2;
96 }
97 new_items = realloc(fifo->items, sizeof(int) * max_size + 1);
98 if(! new_items){
99 return ENOMEM;
100 }
101 fifo->items = new_items;
102 if(fifo->tail < fifo->head){
103 if(fifo->tail < max_size - fifo->size){
104 memcpy(fifo->items + fifo->size + 1, fifo->items, fifo->tail * sizeof(int));
105 fifo->tail += fifo->size + 1;
106 }else{
107 memcpy(fifo->items + fifo->size + 1, fifo->items, (max_size - fifo->size) * sizeof(int));
108 memcpy(fifo->items, fifo->items + max_size - fifo->size, fifo->tail - max_size + fifo->size);
109 fifo->tail -= max_size - fifo->size;
110 }
111 }
112 fifo->size = max_size;
113 }
114 fifo->items[fifo->tail] = value;
115 fifo->tail = NEXT_INDEX(fifo, fifo->tail);
116 return EOK;
117}
118
119int dyn_fifo_pop(dyn_fifo_ref fifo){
120 int value;
121
122 if(! dyn_fifo_is_valid(fifo)){
123 return EINVAL;
124 }
125 if(fifo->head == fifo->tail){
126 return ENOENT;
127 }
128 value = fifo->items[fifo->head];
129 fifo->head = NEXT_INDEX(fifo, fifo->head);
130 return value;
131}
132
133int dyn_fifo_value(dyn_fifo_ref fifo){
134 if(! dyn_fifo_is_valid(fifo)){
135 return EINVAL;
136 }
137 if(fifo->head == fifo->tail){
138 return ENOENT;
139 }
140 return fifo->items[fifo->head];
141}
142
143int dyn_fifo_destroy(dyn_fifo_ref fifo){
144 if(! dyn_fifo_is_valid(fifo)){
145 return EINVAL;
146 }
147 free(fifo->items);
148 fifo->magic_value = 0;
149 return EOK;
150}
151
152/** @}
153 */
Note: See TracBrowser for help on using the repository browser.