From: ppisa Date: Sun, 17 May 2009 09:35:52 +0000 (+0000) Subject: Data queue FIFO included in uLUt missing file added. X-Git-Tag: ul_drv-0.8.0-release~20 X-Git-Url: https://rtime.felk.cvut.cz/gitweb/ulut.git/commitdiff_plain/2a026445a0bf9d99c424bfd88305232212ca30b9 Data queue FIFO included in uLUt missing file added. --- diff --git a/ulut/ul_dqfifo.h b/ulut/ul_dqfifo.h new file mode 100644 index 0000000..bcc92c4 --- /dev/null +++ b/ulut/ul_dqfifo.h @@ -0,0 +1,189 @@ +/******************************************************************* + uLan Utilities Library - C library of basic reusable constructions + + ul_dqfifo.h - data queue FIFO for filters and other computations + + (C) Copyright 2006 by Pavel Pisa - Originator + + The uLan utilities library can be used, copied and modified under + next licenses + - GPL - GNU General Public License + - LGPL - GNU Lesser General Public License + - MPL - Mozilla Public License + - and other licenses added by project originators + Code can be modified and re-distributed under any combination + of the above listed licenses. If contributor does not agree with + some of the licenses, he/she can delete appropriate line. + Warning, if you delete all lines, you are not allowed to + distribute source code and/or binaries utilizing code. + + See files COPYING and README for details. + + *******************************************************************/ + +#ifndef _UL_DQFIFO_H +#define _UL_DQFIFO_H + +typedef unsigned int ul_dqfifo_loc_t; + +/** + * struct ul_dqfifo_base_t - basic structure for data queues locations counting + * @locin: continuously increased location counter for data input position + * @locout: continuously increased location counter for data output position + * @locmask: number of allocated slots to hold actual data minus 1 + */ +typedef struct ul_dqfifo_base_t { + ul_dqfifo_loc_t locin; + ul_dqfifo_loc_t locout; + ul_dqfifo_loc_t locmask; +} ul_dqfifo_base_t; + + +static inline unsigned int +ul_dqfifo_base_loc2idx(ul_dqfifo_base_t *dqf, ul_dqfifo_loc_t loc) +{ + return loc & dqf->locmask; +} + +static inline unsigned int +ul_dqfifo_base_is_full(ul_dqfifo_base_t *dqf) +{ + ul_dqfifo_loc_t locx = dqf->locin ^ dqf->locout; + return (locx && !(locx & dqf->locmask)); +} + +static inline unsigned int +ul_dqfifo_base_is_empty(ul_dqfifo_base_t *dqf) +{ + return (dqf->locin == dqf->locout); +} + +#define UL_DQFIFO_CUST_DEC(cust_prefix, cust_data_t, cust_barrier, cust_static_inline) \ +\ +typedef struct cust_prefix##_t { \ + ul_dqfifo_base_t dqf; \ + cust_data_t *buff; \ +} cust_prefix##_t; \ +\ +cust_static_inline unsigned int \ +cust_prefix##_loc2idx(cust_prefix##_t *cdqf, ul_dqfifo_loc_t loc) \ +{ \ + return ul_dqfifo_base_loc2idx(&cdqf->dqf, loc); \ +} \ +\ +cust_static_inline unsigned int \ +cust_prefix##_is_full(cust_prefix##_t *cdqf) \ +{ \ + return ul_dqfifo_base_is_full(&cdqf->dqf); \ +} \ +\ +cust_static_inline unsigned int \ +cust_prefix##_is_empty(cust_prefix##_t *cdqf) \ +{ \ + return ul_dqfifo_base_is_empty(&cdqf->dqf); \ +} \ +\ +cust_static_inline int \ +cust_prefix##_put(cust_prefix##_t *cdqf, const cust_data_t *data) \ +{ \ + ul_dqfifo_loc_t locin; \ + cust_barrier; \ + if(cust_prefix##_is_full(cdqf)) \ + return 0; \ + locin = cdqf->dqf.locin; \ + cdqf->buff[cust_prefix##_loc2idx(cdqf, locin)] = *data; \ + cust_barrier; \ + cdqf->dqf.locin = ++locin; \ + cust_barrier; \ + return 1; \ +} \ +\ +cust_static_inline int \ +cust_prefix##_get(cust_prefix##_t *cdqf, cust_data_t *data) \ +{ \ + ul_dqfifo_loc_t locout; \ + cust_barrier; \ + if(cust_prefix##_is_empty(cdqf)) \ + return 0; \ + locout = cdqf->dqf.locout; \ + *data = cdqf->buff[cust_prefix##_loc2idx(cdqf, locout)]; \ + cust_barrier; \ + cdqf->dqf.locout = ++locout; \ + cust_barrier; \ + return 1; \ +} \ +\ +cust_static_inline ul_dqfifo_loc_t \ +cust_prefix##_skip(cust_prefix##_t *cdqf, ul_dqfifo_loc_t locinc) \ +{ \ + ul_dqfifo_loc_t locout; \ + ul_dqfifo_loc_t locdiff; \ + cust_barrier; \ + locdiff = cdqf->dqf.locin - cdqf->dqf.locout; \ + if(locinc > locdiff) \ + locinc = locdiff; \ + locout = cdqf->dqf.locout + locinc; \ + cdqf->dqf.locout = locout; \ + cust_barrier; \ + return locdiff; \ +} \ +\ +cust_static_inline void \ +cust_prefix##_flush(cust_prefix##_t *cdqf) \ +{ \ + cust_barrier; \ + cdqf->dqf.locout = cdqf->dqf.locin; \ +} \ +\ +cust_static_inline ul_dqfifo_loc_t \ +cust_prefix##_count(cust_prefix##_t *cdqf) \ +{ ul_dqfifo_loc_t loccount; \ + cust_barrier; \ + loccount = cdqf->dqf.locin - cdqf->dqf.locout; \ + cust_barrier; \ + return loccount; \ +} \ +\ +cust_static_inline ul_dqfifo_loc_t \ +cust_prefix##_get_locin(cust_prefix##_t *cdqf) \ +{ \ + ul_dqfifo_loc_t loc; \ + cust_barrier; \ + loc = cdqf->dqf.locin; \ + cust_barrier; \ + return loc; \ +} \ +\ +cust_static_inline ul_dqfifo_loc_t \ +cust_prefix##_get_locout(cust_prefix##_t *cdqf) \ +{ \ + ul_dqfifo_loc_t loc; \ + cust_barrier; \ + loc = cdqf->dqf.locout; \ + cust_barrier; \ + return loc; \ +} \ +\ +cust_static_inline void \ +cust_prefix##_init(cust_prefix##_t *cdqf, cust_data_t *databuff, \ + ul_dqfifo_loc_t locmask) \ +{ \ + cdqf->buff = databuff; \ + cdqf->dqf.locmask = locmask; \ + cdqf->dqf.locout = cdqf->dqf.locin = 0; \ +} + +#define ul_dqfifo_for_last_x(cdqf, limit, loc, data) \ + for((loc) = (cdqf)->dqf.locout; \ + (data) = (cdqf)->buff[ul_dqfifo_base_loc2idx(&(cdqf)->dqf, (loc))], \ + (((loc) != (cdqf)->dqf.locout + (limit)) && ((loc) != (cdqf)->dqf.locin)); (loc)++) + +#define UL_DQFIFO_STATIC_INSTANCE(cust_instance, cust_prefix, slots) \ +\ +typeof(*((cust_prefix##_t*)0)->buff) cust_instance##_databuff[slots]; \ +cust_prefix##_t cust_instance = { \ + .dqf = {.locmask = slots - 1, .locout = 0, .locin = 0}, \ + .buff = cust_instance##_databuff,\ +}; + +#endif /*_UL_DQFIFO_H*/