00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _AP_QUEUE_TEMPLATE_H_
00036 #define _AP_QUEUE_TEMPLATE_H_
00037 #include "macros.h"
00038 #include "mc_error.h"
00039 #include <embedch.h>
00040
00041 struct AP_GENERIC_s {void* none;};
00042 typedef struct AP_GENERIC_s AP_GENERIC_t;
00043 typedef AP_GENERIC_t* AP_GENERIC_p;
00044
00045
00046 #define AP_QUEUE_DECL_TEMPLATE( name, node_type) \
00047 typedef struct name##_s \
00048 { \
00049 int size; \
00050 list_p list; \
00051 MUTEX_T* lock; \
00052 COND_T* cond; \
00053 } name##_t; \
00054 \
00055 typedef name##_t* name##_p; \
00056 \
00057 name##_p name##_New( void ); \
00058 int name##_Destroy( name##_p name ); \
00059 int name##_Add( name##_p name, struct node_type##_s* node ); \
00060 name##_p name##_Copy(name##_p name); \
00061 struct node_type##_s* name##_Pop( name##_p name ); \
00062 struct node_type##_s* name##_WaitPop( name##_p name ); \
00063 struct node_type##_s* name##_SearchIndex( name##_p name, int index ); \
00064 int name##_RemoveIndex(name##_p name, int index);
00065
00066 #define AP_QUEUE_GENERIC_DECL_TEMPLATE(name, func_name, return_type, search_type) \
00067 return_type name##_##func_name(name##_p name, const search_type key);
00068
00069 #define AP_QUEUE_STD_DEFN_TEMPLATE( name, node_type) \
00070 name##_p name##_New( void ) \
00071 { \
00072 name##_p temp; \
00073 temp = (name##_p)malloc(sizeof(name##_t)); \
00074 temp->size = 0; \
00075 temp->list = ListInitialize(); \
00076 \
00077 temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00078 temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00079 MUTEX_INIT(temp->lock); \
00080 COND_INIT(temp->cond); \
00081 return temp; \
00082 } \
00083 \
00084 int name##_Destroy( name##_p name ) \
00085 { \
00086 struct node_type##_s* node; \
00087 while ((node = (node_type##_t*)name##_Pop(name)) != NULL) { \
00088 node_type##_Destroy(node); \
00089 } \
00090 ListTerminate(name->list); \
00091 MUTEX_DESTROY(name->lock); \
00092 COND_DESTROY(name->cond); \
00093 free(name->lock); \
00094 free(name->cond); \
00095 free(name); \
00096 return 0; \
00097 } \
00098 \
00099 name##_p name##_Copy(name##_p name) \
00100 { \
00101 int i;\
00102 name##_p temp; \
00103 struct node_type##_s* temp_node; \
00104 temp = (name##_p)malloc(sizeof(name##_t)); \
00105 if (temp == NULL) { \
00106 fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00107 exit(0); \
00108 } \
00109 temp->size = 0; \
00110 temp->list = ListInitialize(); \
00111 temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00112 if (temp->lock == NULL) { \
00113 fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00114 exit(0); \
00115 } \
00116 temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00117 if(temp->cond == NULL) { \
00118 fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00119 exit(0); \
00120 } \
00121 MUTEX_INIT(temp->lock); \
00122 COND_INIT(temp->cond); \
00123 for( \
00124 i = 0; \
00125 (temp_node = (node_type##_t*)name##_SearchIndex(name, i)) != NULL; \
00126 i++ \
00127 ) \
00128 { \
00129 name##_Add(temp, node_type##_Copy(temp_node)); \
00130 } \
00131 return temp; \
00132 } \
00133 \
00134 int name##_Add( name##_p name, node_type##_t* node ) \
00135 { \
00136 MUTEX_LOCK(name->lock); \
00137 ListAdd(name->list, node); \
00138 name->size++; \
00139 COND_SIGNAL(name->cond); \
00140 MUTEX_UNLOCK(name->lock); \
00141 return 0; \
00142 } \
00143 \
00144 node_type##_t* name##_Pop( name##_p name ) \
00145 { \
00146 struct node_type##_s* ret; \
00147 MUTEX_LOCK(name->lock); \
00148 if (name->size <= 0) { \
00149 MUTEX_UNLOCK(name->lock); \
00150 return NULL; \
00151 } \
00152 ret = (node_type##_t*)ListPop(name->list); \
00153 name->size--; \
00154 COND_SIGNAL(name->cond); \
00155 MUTEX_UNLOCK(name->lock); \
00156 return ret; \
00157 } \
00158 \
00159 node_type##_t* name##_WaitPop( name##_p name ) \
00160 { \
00161 struct node_type##_s* ret; \
00162 MUTEX_LOCK(name->lock); \
00163 while (name->size <= 0) { \
00164 COND_WAIT(name->cond, name->lock); \
00165 } \
00166 ret = (node_type##_t*)ListPop(name->list); \
00167 name->size--; \
00168 COND_SIGNAL(name->cond); \
00169 MUTEX_UNLOCK(name->lock); \
00170 return ret; \
00171 } \
00172 \
00173 struct node_type##_s* name##_SearchIndex( name##_p name, int index ) \
00174 { \
00175 struct node_type##_s* node; \
00176 MUTEX_LOCK(name->lock); \
00177 node = (node_type##_t*)ListSearch(name->list, index); \
00178 MUTEX_UNLOCK(name->lock); \
00179 return node; \
00180 } \
00181 \
00182 int name##_RemoveIndex( name##_p name, int index ) \
00183 { \
00184 struct node_type##_s* node; \
00185 MUTEX_LOCK(name->lock); \
00186 node = (node_type##_t*)ListDelete(name->list, index); \
00187 node_type##_Destroy(node); \
00188 name->size--; \
00189 MUTEX_UNLOCK(name->lock); \
00190 return 0; \
00191 }
00192
00193 #define AP_QUEUE_SEARCH_TEMPLATE( name, func_name, node_type, \
00194 search_type, search_expression ) \
00195 struct node_type##_s* name##_##func_name( name##_p name, const search_type key ) \
00196 { \
00197 listNode_t* parsenode; \
00198 struct node_type##_s* node; \
00199 struct node_type##_s* ret = NULL; \
00200 node = NULL; \
00201 \
00202 MUTEX_LOCK(name->lock); \
00203 if (name->list->listhead == NULL) { \
00204 MUTEX_UNLOCK(name->lock); \
00205 return NULL; \
00206 } \
00207 for( \
00208 parsenode = (listNode_t*)name->list->listhead; \
00209 parsenode != NULL; \
00210 parsenode = (listNode_t*)parsenode->next \
00211 ) \
00212 { \
00213 node = (node_type##_t*)parsenode->node_data; \
00214 if (search_expression){ \
00215 ret = node; \
00216 break; \
00217 } \
00218 } \
00219 MUTEX_UNLOCK(name->lock); \
00220 return ret; \
00221 }
00222
00223 #define AP_QUEUE_REMOVE_TEMPLATE( name, func_name, node_type, \
00224 search_type, search_expression) \
00225 int name##_##func_name( name##_p name, const search_type key ) \
00226 { \
00227 int err_code = MC_ERR_NOT_FOUND; \
00228 struct listNode_s* parsenode; \
00229 struct node_type##_s* node; \
00230 node = NULL; \
00231 \
00232 MUTEX_LOCK(name->lock); \
00233 if (name->list->listhead == NULL) { \
00234 MUTEX_UNLOCK(name->lock); \
00235 return MC_ERR_NOT_FOUND; \
00236 } \
00237 for( \
00238 parsenode = (listNode_t*)name->list->listhead; \
00239 parsenode->next != NULL; \
00240 parsenode = (listNode_t*)parsenode->next \
00241 ) \
00242 { \
00243 node = (node_type##_t*)parsenode->node_data; \
00244 if (search_expression) { \
00245 break; \
00246 err_code = MC_SUCCESS; \
00247 } \
00248 } \
00249 MUTEX_UNLOCK(name->lock); \
00250 return err_code; \
00251 }
00252
00253
00254 struct interpreter_queue_s;
00255 AP_GENERIC_p interpreter_queue_CreateRetrieve( struct interpreter_queue_s *queue, ChOptions_t* interp_options );
00256 #endif