TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

tsp_ringbuf.h

Go to the documentation of this file.
00001 
00039 #ifndef __TSP_RINGBUF_H
00040 #define __TSP_RINGBUF_H
00041 
00042 #include <stdlib.h>
00043 
00044 #include "tsp_prjcfg.h"
00045 
00046 #ifdef __cplusplus
00047 extern "C" {
00048 #endif
00049 
00050 /*
00051 --
00052 -- ring buffer type
00053 --
00054 */
00055 
00056 #ifdef __GNUC__
00057 #define RINGBUF_DYNAMIC_SZ      0
00058 #else
00059 #define RINGBUF_DYNAMIC_SZ
00060 #endif
00061 
00062 /* 
00063  * On definit une taille qui soit un multiple
00064  * de 4 car certaines CPU alignent les structures
00065  * sur des multiples de 2 octets (MVME 162) et d'autre 
00066  * sur des multiples de 4 octets (MVME 26xx)
00067  */
00068 #define RINGBUF_SZ(sz)          ((sz) + 1 + (4-(((sz) + 1) % 4)))
00069 
00070 
00071 /* For number x, get the nearest superior or equal number, multiple of base */
00072 #define RINGBUF_MULTSUP(x, base)     (( (base) - ( (x) % (base) )) % (base) + (x) )
00073 
00074 #define RINGBUF_DECLARE_TYPE(TypeName, ItemType, sz) \
00075         typedef struct \
00076         { \
00077                 int             size; \
00078                 int             put; \
00079                 int             get; \
00080                 int             missed; \
00081                 ItemType        buf[sz]; \
00082         } TypeName
00083 
00084 /*
00085 --
00086 -- static implementation
00087 --
00088 */
00089 
00090 #define RINGBUF_DEFINE(TypeName, name, sz) \
00091         TypeName        (name) = { sz, 0, 0, 0, 0 }
00092 
00093 #define RINGBUF_PUT(name, item) \
00094         { \
00095                 int     put; \
00096                 \
00097                 put = ((name).put + 1) % (name).size; \
00098                 \
00099                 if (put != (name).get) \
00100                 { \
00101                         (name).buf[(name).put] = (item); \
00102                         (name).put = put; \
00103                 } \
00104                 else \
00105                 { \
00106                         ++(name).missed; \
00107                 } \
00108         }
00109 
00110 #define RINGBUF_PUTBYADDR(name) \
00111         ( \
00112                 ((((name).put + 1) % (name).size) != (name).get) ? \
00113                         &(name).buf[(name).put] \
00114                 : \
00115                         ( \
00116                         ++(name).missed, \
00117                         (void*)NULL \
00118                         ) \
00119         )
00120 
00121 #define RINGBUF_PUTBYADDR_WITH_SIZE(name, sizePlusOne, indexPut) \
00122         ( \
00123                 ( ( ((indexPut)=(name).put) + 1) % sizePlusOne) != (name).get) ? \
00124                         &(name).buf[(indexPut)] \
00125                 : \
00126                         ( \
00127                         ++(name).missed, \
00128                         (void*)NULL \
00129                         ) \
00130         )
00131 
00132 #define RINGBUF_PUTBYADDR_COMMIT(name) \
00133                 (name).put = ((name).put + 1) % (name).size
00134 
00135 #define RINGBUF_PUTBYADDR_COMMIT_WITH_SIZE(name, indexPut, sizePlusOne) \
00136                 (name).put = ((indexPut) + 1) % (sizePlusOne) 
00137 
00138 #define RINGBUF_GET(name, item) \
00139         ( \
00140                 ((name).get != (name).put) ? \
00141                         ( \
00142                         (item) = (name).buf[(name).get], \
00143                         (name).get = ((name).get + 1) % (name).size, \
00144                         TRUE \
00145                         ) \
00146                 : \
00147                         FALSE \
00148         )
00149 
00150 #define RINGBUF_GETBYADDR(name) \
00151         ( \
00152                 ((name).get != (name).put) ? \
00153                         &(name).buf[(name).get] \
00154                 : \
00155                         (void*)NULL \
00156         )
00157 
00158 #define RINGBUF_GETBYADDR_COMMIT(name) \
00159                 (name).get = ((name).get + 1) % (name).size
00160 
00161 #define RINGBUF_RESTART_GET(name) \
00162         { \
00163                 (name).get = ((name).get + 1) % (name).size); \
00164         }
00165 
00166 /* It is safe because we get until the put or until the end of buffer 
00167    then make a loop (i=firstItem; i<firstItem+nbItems; i++)
00168    and call RINGBUF_GETBYADDR_BURST_NEXT */
00169 #define RINGBUF_GETBYADDR_BURST(name, firstItem, nbItems, sizePlusOne) \
00170         { \
00171                 int lastItem =   (name).put;\
00172                 firstItem = (name).get; \
00173                 sizePlusOne = (name).size; \
00174                 if (firstItem<=lastItem)\
00175                         nbItems = lastItem-firstItem; \
00176                 else\
00177                         nbItems = (sizePlusOne-firstItem)+lastItem;\
00178         }
00179 
00180 #define RINGBUF_GETBYADDR_BURST_NEXT(name, indexItem, sizePlusOne) \
00181              &(name).buf[ (indexItem) % (sizePlusOne)] 
00182           
00183 #define RINGBUF_GETBYADDR_COMMIT_BURST(name, firstItem, nbItems, sizePlusOne)\
00184           (name).get = ( (firstItem) + (nbItems) )  % (sizePlusOne)
00185 
00186 /* This reset is not safe for the producer */
00187 #define RINGBUF_RESET_CONSUMER(name) \
00188         { \
00189                 (name).get   = (name).put ; \
00190                 (name).missed = 0; \
00191         }
00192 
00193 /* This reset is not safe for the consumer */
00194 #define RINGBUF_RESET_PRODUCER(name) \
00195         { \
00196                 (name).put   = (name).get \
00197                 (name).missed = 0; \
00198         }
00199 
00200 #define RINGBUF_SIZE(name)              ((name).size - 1)
00201 #define RINGBUF_MISSED(name)            ((name).missed)
00202 #define RINGBUF_ISEMPTY(name)           ((name).get == (name).put)
00203 
00204 #define RINGBUF_ITEMS(name) \
00205         ( \
00206                 ((name).put >= (name).get) ? \
00207                         (name).put - (name).get \
00208                 : \
00209                         (name).size - (name).get + (name).put \
00210         )
00211 
00212 /*
00213 --
00214 -- dynamic implementation
00215 --
00216 */
00217 
00218 
00219 /* 'pad' is there for alignement purpose */
00220 #define RINGBUF_DECLARE_TYPE_DYNAMIC(TypeName, ItemType) \
00221         typedef struct \
00222         { \
00223                 int             size; \
00224                 int             put; \
00225                 int             get; \
00226                 int             missed; \
00227                 int             mul_offset; \
00228                 ItemType*       buf; \
00229         } TypeName
00230 
00231 
00232 
00233 #define RINGBUF_PTR_INIT(TypeName, name, ItemType, nbSpareBytes, sz) \
00234         { \
00235           int mul_offset =  RINGBUF_MULTSUP((sizeof(ItemType) + nbSpareBytes),sizeof(ItemType)) / sizeof(ItemType);\
00236           name = (TypeName*)malloc(sizeof(TypeName) + (sizeof(ItemType) * mul_offset  * sz)); \
00237           (name)->size   = sz; \
00238           (name)->put   = 0; \
00239           (name)->get   = 0; \
00240           (name)->missed = 0; \
00241           (name)->mul_offset = mul_offset; \
00242           (name)->buf = (ItemType*)((name)+1); \
00243         }
00244 
00245 #define RINGBUF_PTR_DESTROY(name)  \
00246         { \
00247                 free((name)); \
00248                 (name) = NULL; \
00249         }
00250 
00251                 
00252 #define RINGBUF_PTR_PUT(name, item) \
00253         { \
00254                 int     put; \
00255                 \
00256                 put = ((name)->put + 1) % (name)->size; \
00257                 \
00258                 if (put != (name)->get) \
00259                 { \
00260                         (name)->buf[(name)->put * (name)->mul_offset] = (item); \
00261                         (name)->put = put; \
00262                 } \
00263                 else \
00264                 { \
00265                         ++(name)->missed; \
00266                 } \
00267         }
00268 
00269 #define RINGBUF_PTR_PUTBYADDR(name) \
00270         ( \
00271                 ((((name)->put + 1) % (name)->size) != (name)->get) ? \
00272                         &(name)->buf[(name)->put * (name)->mul_offset] \
00273                 : \
00274                         ( \
00275                         ++(name)->missed, \
00276                         (void*)NULL \
00277                         ) \
00278         )
00279 
00280 
00281 #define RINGBUF_PTR_PUTBYADDR_COMMIT(name) \
00282                 (name)->put = ((name)->put + 1) % (name)->size 
00283 
00284 #define RINGBUF_PTR_GET(name,item) \
00285         ( \
00286                 ((name)->get != (name)->put) ? \
00287                         ( \
00288                         (item) = (name)->buf[(name)->get * (name)->mul_offset], \
00289                         (name)->get = ((name)->get + 1) % (name)->size, \
00290                         TRUE \
00291                         ) \
00292                 : \
00293                         FALSE \
00294         )
00295 
00296 #define RINGBUF_PTR_NOCHECK_GET(name,item) \
00297         { \
00298                 (item) = (name)->buf[(name)->get * (name)->mul_offset]; \
00299                 (name)->get = ((name)->get + 1) % (name)->size; \
00300         }
00301 
00302 #define RINGBUF_PTR_GETBYADDR(name) \
00303         ( \
00304                 ((name)->get != (name)->put) ? \
00305                         &(name)->buf[(name)->get * (name)->mul_offset] \
00306                 : \
00307                         (void*)NULL \
00308         )
00309 
00310 #define RINGBUF_PTR_GETBYADDR_COMMIT(name) \
00311                 (name)->get = ((name)->get + 1) % (name)->size
00312 
00313 #define RINGBUF_PTR_RESTART_GET(name) \
00314         { \
00315                 (name)->get = ((name)->get + 1) % (name)->size); \
00316         }
00317 
00318 
00319 /* This reset is not safe for the producer */
00320 #define RINGBUF_PTR_RESET_CONSUMER(name) \
00321         { \
00322                 (name)->get   = (name)->put; \
00323                 (name)->missed = 0; \
00324         }
00325 
00326 /* This reset is not safe for the consumer */
00327 #define RINGBUF_PTR_RESET_PRODUCER(name) \
00328         { \
00329                 (name)->put   = (name)->get; \
00330                 (name)->missed = 0; \
00331         }
00332 
00333 
00334 #define RINGBUF_PTR_SIZE(name)          ((name)->size - 1)
00335 #define RINGBUF_PTR_MISSED(name)        ((name)->missed)
00336 #define RINGBUF_PTR_ISEMPTY(name)       ((name)->get == (name)->put)
00337 
00338 #define RINGBUF_PTR_ITEMS(name) \
00339         ( \
00340                 ((name)->put > (name)->get) ? \
00341                         (name)->put - (name)->get \
00342                 : \
00343                         (name)->size - (name)->get + (name)->put \
00344         )
00345  
00346 #define RINGBUF_PTR_ITEMS_LEFT(name) \
00347         ( \
00348                 ((name)->put >= (name)->get) ? \
00349                         (name)->size - (name)->put + (name)->get \
00350                 : \
00351                         (name)->get - (name)->put \
00352         )
00353 
00354 
00355 #ifdef __cplusplus
00356 }
00357 #endif
00358 
00359 #endif /* _RINGBUF_H */
00360 
Framework Home Page.

Beware !! TSP wave is coming...