1 /*******************************************************************
2 uLan Utilities Library - C library of basic reusable constructions
4 ul_dqfifo.h - data queue FIFO for filters and other computations
6 (C) Copyright 2006 by Pavel Pisa - Originator
8 The uLan utilities library can be used, copied and modified under
10 - GPL - GNU General Public License
11 - LGPL - GNU Lesser General Public License
12 - MPL - Mozilla Public License
13 - and other licenses added by project originators
14 Code can be modified and re-distributed under any combination
15 of the above listed licenses. If contributor does not agree with
16 some of the licenses, he/she can delete appropriate line.
17 Warning, if you delete all lines, you are not allowed to
18 distribute source code and/or binaries utilizing code.
20 See files COPYING and README for details.
22 *******************************************************************/
27 typedef unsigned int ul_dqfifo_loc_t;
30 * struct ul_dqfifo_base_t - basic structure for data queues locations counting
31 * @locin: continuously increased location counter for data input position
32 * @locout: continuously increased location counter for data output position
33 * @locmask: number of allocated slots to hold actual data minus 1
35 typedef struct ul_dqfifo_base_t {
36 ul_dqfifo_loc_t locin;
37 ul_dqfifo_loc_t locout;
38 ul_dqfifo_loc_t locmask;
42 static inline unsigned int
43 ul_dqfifo_base_loc2idx(ul_dqfifo_base_t *dqf, ul_dqfifo_loc_t loc)
45 return loc & dqf->locmask;
48 static inline unsigned int
49 ul_dqfifo_base_is_full(ul_dqfifo_base_t *dqf)
51 ul_dqfifo_loc_t locx = dqf->locin ^ dqf->locout;
52 return (locx && !(locx & dqf->locmask));
55 static inline unsigned int
56 ul_dqfifo_base_is_empty(ul_dqfifo_base_t *dqf)
58 return (dqf->locin == dqf->locout);
61 #define UL_DQFIFO_CUST_DEC(cust_prefix, cust_data_t, cust_barrier, cust_static_inline) \
63 typedef struct cust_prefix##_t { \
64 ul_dqfifo_base_t dqf; \
68 cust_static_inline unsigned int \
69 cust_prefix##_loc2idx(cust_prefix##_t *cdqf, ul_dqfifo_loc_t loc) \
71 return ul_dqfifo_base_loc2idx(&cdqf->dqf, loc); \
74 cust_static_inline unsigned int \
75 cust_prefix##_is_full(cust_prefix##_t *cdqf) \
77 return ul_dqfifo_base_is_full(&cdqf->dqf); \
80 cust_static_inline unsigned int \
81 cust_prefix##_is_empty(cust_prefix##_t *cdqf) \
83 return ul_dqfifo_base_is_empty(&cdqf->dqf); \
86 cust_static_inline int \
87 cust_prefix##_put_no_check(cust_prefix##_t *cdqf, const cust_data_t *data) \
89 ul_dqfifo_loc_t locin; \
91 locin = cdqf->dqf.locin; \
92 cdqf->buff[cust_prefix##_loc2idx(cdqf, locin)] = *data; \
94 cdqf->dqf.locin = ++locin; \
99 cust_static_inline int \
100 cust_prefix##_put(cust_prefix##_t *cdqf, const cust_data_t *data) \
102 ul_dqfifo_loc_t locin; \
104 if(cust_prefix##_is_full(cdqf)) \
106 locin = cdqf->dqf.locin; \
107 cdqf->buff[cust_prefix##_loc2idx(cdqf, locin)] = *data; \
109 cdqf->dqf.locin = ++locin; \
114 cust_static_inline int \
115 cust_prefix##_get(cust_prefix##_t *cdqf, cust_data_t *data) \
117 ul_dqfifo_loc_t locout; \
119 if(cust_prefix##_is_empty(cdqf)) \
121 locout = cdqf->dqf.locout; \
122 *data = cdqf->buff[cust_prefix##_loc2idx(cdqf, locout)]; \
124 cdqf->dqf.locout = ++locout; \
129 cust_static_inline ul_dqfifo_loc_t \
130 cust_prefix##_skip(cust_prefix##_t *cdqf, ul_dqfifo_loc_t locinc) \
132 ul_dqfifo_loc_t locout; \
133 ul_dqfifo_loc_t locdiff; \
135 locdiff = cdqf->dqf.locin - cdqf->dqf.locout; \
136 if(locinc > locdiff) \
138 locout = cdqf->dqf.locout + locinc; \
139 cdqf->dqf.locout = locout; \
144 cust_static_inline void \
145 cust_prefix##_flush(cust_prefix##_t *cdqf) \
148 cdqf->dqf.locout = cdqf->dqf.locin; \
151 cust_static_inline ul_dqfifo_loc_t \
152 cust_prefix##_count(cust_prefix##_t *cdqf) \
153 { ul_dqfifo_loc_t loccount; \
155 loccount = cdqf->dqf.locin - cdqf->dqf.locout; \
160 cust_static_inline ul_dqfifo_loc_t \
161 cust_prefix##_get_locin(cust_prefix##_t *cdqf) \
163 ul_dqfifo_loc_t loc; \
165 loc = cdqf->dqf.locin; \
170 cust_static_inline ul_dqfifo_loc_t \
171 cust_prefix##_get_locout(cust_prefix##_t *cdqf) \
173 ul_dqfifo_loc_t loc; \
175 loc = cdqf->dqf.locout; \
180 cust_static_inline void \
181 cust_prefix##_init(cust_prefix##_t *cdqf, cust_data_t *databuff, \
182 ul_dqfifo_loc_t locmask) \
184 cdqf->buff = databuff; \
185 cdqf->dqf.locmask = locmask; \
186 cdqf->dqf.locout = cdqf->dqf.locin = 0; \
189 #define ul_dqfifo_for_last_x(cdqf, limit, loc, data) \
190 for((loc) = (cdqf)->dqf.locout; \
191 (data) = (cdqf)->buff[ul_dqfifo_base_loc2idx(&(cdqf)->dqf, (loc))], \
192 (((loc) != (cdqf)->dqf.locout + (limit)) && ((loc) != (cdqf)->dqf.locin)); (loc)++)
194 #define UL_DQFIFO_STATIC_INSTANCE(cust_instance, cust_prefix, slots) \
196 typeof(*((cust_prefix##_t*)0)->buff) cust_instance##_databuff[slots]; \
197 cust_prefix##_t cust_instance = { \
198 .dqf = {.locmask = slots - 1, .locout = 0, .locin = 0}, \
199 .buff = cust_instance##_databuff,\
202 #endif /*_UL_DQFIFO_H*/