]> rtime.felk.cvut.cz Git - ulut.git/commitdiff
Data queue FIFO included in uLUt missing file added.
authorppisa <ppisa>
Sun, 17 May 2009 09:35:52 +0000 (09:35 +0000)
committerppisa <ppisa>
Sun, 17 May 2009 09:35:52 +0000 (09:35 +0000)
ulut/ul_dqfifo.h [new file with mode: 0644]

diff --git a/ulut/ul_dqfifo.h b/ulut/ul_dqfifo.h
new file mode 100644 (file)
index 0000000..bcc92c4
--- /dev/null
@@ -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*/