/home/dko/projects/mobilec/trunk/src/include/ap_queue_template.h

Go to the documentation of this file.
00001 /*[
00002  * Copyright (c) 2007 Integration Engineering Laboratory
00003                       University of California, Davis
00004  *
00005  * Permission to use, copy, and distribute this software and its
00006  * documentation for any purpose with or without fee is hereby granted,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.
00010  *
00011  * Permission to modify the software is granted, but not the right to
00012  * distribute the complete modified source code.  Modifications are to
00013  * be distributed as patches to the released version.  Permission to
00014  * distribute binaries produced by compiling modified sources is granted,
00015  * provided you
00016  *   1. distribute the corresponding source modifications from the
00017  *    released version in the form of a patch file along with the binaries,
00018  *   2. add special version identification to distinguish your version
00019  *    in addition to the base release version number,
00020  *   3. provide your name and address as the primary contact for the
00021  *    support of your modified version, and
00022  *   4. retain our contact information in regard to use of the base
00023  *    software.
00024  * Permission to distribute the released version of the source code along
00025  * with corresponding source modifications in the form of a patch file is
00026  * granted with same provisions 2 through 4 for binary distributions.
00027  *
00028  * This software is provided "as is" without express or implied warranty
00029  * to the extent permitted by applicable law.
00030 ]*/
00031 
00032 #ifndef _AP_QUEUE_TEMPLATE_H_
00033 #define _AP_QUEUE_TEMPLATE_H_
00034 #include "macros.h"
00035 #include "mc_error.h"
00036 /* Fields will be: NAME */
00037 #define AP_QUEUE_DECL_TEMPLATE( name, node_type) \
00038 typedef struct name##_s \
00039 { \
00040   int size; \
00041   list_p list; \
00042   MUTEX_T* lock; \
00043   COND_T* cond; \
00044 } name##_t; \
00045   \
00046 typedef name##_t* name##_p; \
00047   \
00048 name##_p name##_New( void ); \
00049 int name##_Destroy( name##_p name ); \
00050 int name##_Add( name##_p name, struct node_type##_s* node ); \
00051 name##_p name##_Copy(name##_p name); \
00052 struct node_type##_s* name##_Pop( name##_p name ); \
00053 struct node_type##_s* name##_SearchIndex( name##_p name, int index ); \
00054 int name##_RemoveIndex(name##_p name, int index); 
00055 
00056 #define AP_QUEUE_GENERIC_DECL_TEMPLATE(name, func_name, return_type, search_type) \
00057 return_type name##_##func_name(name##_p name, const search_type key);
00058 
00059 #define AP_QUEUE_STD_DEFN_TEMPLATE( name, node_type) \
00060 name##_p name##_New( void ) \
00061 { \
00062   name##_p temp; \
00063   temp = (name##_p)malloc(sizeof(name##_t)); \
00064   temp->size = 0; \
00065   temp->list = ListInitialize(); \
00066   \
00067   temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00068   temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00069   MUTEX_INIT(temp->lock); \
00070   COND_INIT(temp->cond); \
00071   return temp; \
00072 } \
00073   \
00074 int name##_Destroy( name##_p name ) \
00075 { \
00076   struct node_type##_s* node; \
00077   while ((node = name##_Pop(name)) != NULL) { \
00078     node_type##_Destroy(node); \
00079   } \
00080   ListTerminate(name->list); \
00081   MUTEX_DESTROY(name->lock); \
00082   COND_DESTROY(name->cond); \
00083   free(name->lock); \
00084   free(name->cond); \
00085   free(name); \
00086   return 0; \
00087 } \
00088   \
00089 name##_p name##_Copy(name##_p name) \
00090 { \
00091   int i;\
00092   name##_p temp; \
00093   struct node_type##_s* temp_node; \
00094   temp = (name##_p)malloc(sizeof(name##_t)); \
00095   if (temp == NULL) { \
00096     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00097     exit(0); \
00098   } \
00099   temp->size = 0; \
00100   temp->list = ListInitialize(); \
00101   temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00102   if (temp->lock == NULL) { \
00103     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00104     exit(0); \
00105   } \
00106   temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00107   if(temp->cond == NULL) { \
00108     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00109     exit(0); \
00110   } \
00111   MUTEX_INIT(temp->lock); \
00112   COND_INIT(temp->cond); \
00113   for( \
00114       i = 0; \
00115       (temp_node = name##_SearchIndex(name, i)) != NULL; \
00116       i++ \
00117      ) \
00118   { \
00119     name##_Add(temp, node_type##_Copy(temp_node)); \
00120   } \
00121   return temp; \
00122 } \
00123   \
00124 int name##_Add( name##_p name, node_type##_t* node ) \
00125 { \
00126   MUTEX_LOCK(name->lock); \
00127   ListAdd(name->list, node); \
00128   name->size++; \
00129   COND_SIGNAL(name->cond); \
00130   MUTEX_UNLOCK(name->lock); \
00131   return 0; \
00132 } \
00133   \
00134 node_type##_t* name##_Pop( name##_p name ) \
00135 { \
00136   struct node_type##_s* ret; \
00137   MUTEX_LOCK(name->lock); \
00138   if (name->size <= 0) { \
00139     MUTEX_UNLOCK(name->lock); \
00140     return NULL; \
00141   } \
00142   ret = ListPop(name->list); \
00143   name->size--; \
00144   COND_SIGNAL(name->cond); \
00145   MUTEX_UNLOCK(name->lock); \
00146   return ret; \
00147 } \
00148   \
00149 struct node_type##_s* name##_SearchIndex( name##_p name, int index ) \
00150 { \
00151   struct node_type##_s* node; \
00152   MUTEX_LOCK(name->lock); \
00153   node = (node_type##_t*)ListSearch(name->list, index); \
00154   MUTEX_UNLOCK(name->lock); \
00155   return node; \
00156 } \
00157   \
00158 int name##_RemoveIndex( name##_p name, int index ) \
00159 { \
00160   struct node_type##_s* node; \
00161   MUTEX_LOCK(name->lock); \
00162   node = ListDelete(name->list, index); \
00163   node_type##_Destroy(node); \
00164   name->size--; \
00165   MUTEX_UNLOCK(name->lock); \
00166   return 0; \
00167 } 
00168 
00169 #define AP_QUEUE_SEARCH_TEMPLATE( name, func_name, node_type, \
00170     search_type, search_expression ) \
00171 struct node_type##_s* name##_##func_name( name##_p name, const search_type key ) \
00172 { \
00173   listNode_t* parsenode; \
00174   struct node_type##_s* node; \
00175   struct node_type##_s* ret = NULL; \
00176   node = NULL; \
00177   \
00178   MUTEX_LOCK(name->lock); \
00179   if (name->list->listhead == NULL) { \
00180     MUTEX_UNLOCK(name->lock); \
00181     return NULL; \
00182   } \
00183   for( \
00184       parsenode = (listNode_t*)name->list->listhead; \
00185       parsenode != NULL; \
00186       parsenode = (listNode_t*)parsenode->next \
00187      ) \
00188   { \
00189     node = (node_type##_t*)parsenode->node_data; \
00190     if (search_expression){ \
00191       ret = node; \
00192       break; \
00193     } \
00194   } \
00195   MUTEX_UNLOCK(name->lock); \
00196   return ret; \
00197 } 
00198 
00199 #define AP_QUEUE_REMOVE_TEMPLATE( name, func_name, node_type, \
00200     search_type, search_expression) \
00201 int name##_##func_name( name##_p name, const search_type key ) \
00202 { \
00203   int err_code = MC_ERR_NOT_FOUND; \
00204   struct listNode_s* parsenode; \
00205   struct node_type##_s* node; \
00206   node = NULL; \
00207   \
00208   MUTEX_LOCK(name->lock); \
00209   if (name->list->listhead == NULL) { \
00210     MUTEX_UNLOCK(name->lock); \
00211     return MC_ERR_NOT_FOUND; \
00212   } \
00213   for( \
00214       parsenode = (listNode_t*)name->list->listhead; \
00215       parsenode->next != NULL; \
00216       parsenode = (listNode_t*)parsenode->next \
00217      ) \
00218   { \
00219     node = (node_type##_t*)parsenode->node_data; \
00220     if (search_expression) { \
00221       break; \
00222       err_code = MC_SUCCESS; \
00223     } \
00224   } \
00225   MUTEX_UNLOCK(name->lock); \
00226   return err_code; \
00227 }
00228 #endif

Generated on Mon Jun 23 16:01:09 2008 for Mobile-C by  doxygen 1.5.4