00001 /* SVN FILE INFO 00002 * $Revision: 174 $ : Last Committed Revision 00003 * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */ 00004 /*[ 00005 * Copyright (c) 2007 Integration Engineering Laboratory 00006 University of California, Davis 00007 * 00008 * Permission to use, copy, and distribute this software and its 00009 * documentation for any purpose with or without fee is hereby granted, 00010 * provided that the above copyright notice appear in all copies and 00011 * that both that copyright notice and this permission notice appear 00012 * in supporting documentation. 00013 * 00014 * Permission to modify the software is granted, but not the right to 00015 * distribute the complete modified source code. Modifications are to 00016 * be distributed as patches to the released version. Permission to 00017 * distribute binaries produced by compiling modified sources is granted, 00018 * provided you 00019 * 1. distribute the corresponding source modifications from the 00020 * released version in the form of a patch file along with the binaries, 00021 * 2. add special version identification to distinguish your version 00022 * in addition to the base release version number, 00023 * 3. provide your name and address as the primary contact for the 00024 * support of your modified version, and 00025 * 4. retain our contact information in regard to use of the base 00026 * software. 00027 * Permission to distribute the released version of the source code along 00028 * with corresponding source modifications in the form of a patch file is 00029 * granted with same provisions 2 through 4 for binary distributions. 00030 * 00031 * This software is provided "as is" without express or implied warranty 00032 * to the extent permitted by applicable law. 00033 ]*/ 00034 00035 #include "include/ams.h" 00036 #include "include/agent.h" 00037 #include "include/data_structures.h" 00038 #include "include/mc_platform.h" 00039 00040 int 00041 ams_Destroy(ams_p ams) 00042 { 00043 MUTEX_DESTROY(ams->runflag_lock); 00044 free(ams->runflag_lock); 00045 COND_DESTROY(ams->runflag_cond); 00046 free(ams->runflag_cond); 00047 free(ams); 00048 return MC_SUCCESS; 00049 } 00050 00051 ams_p 00052 ams_Initialize(mc_platform_p mc_platform) 00053 { 00054 ams_p ams; 00055 ams = (ams_p)malloc(sizeof(ams_t)); 00056 CHECK_NULL(ams, exit(0);); 00057 ams->mc_platform = mc_platform; 00058 00059 ams->runflag_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); 00060 CHECK_NULL(ams->runflag_lock, exit(0);); 00061 MUTEX_INIT(ams->runflag_lock); 00062 00063 ams->runflag_cond = (COND_T*)malloc(sizeof(COND_T)); 00064 CHECK_NULL(ams->runflag_cond, exit(0);); 00065 COND_INIT(ams->runflag_cond); 00066 00067 ams->run = 0; 00068 00069 ams->waiting = 0; 00070 ams->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); 00071 MUTEX_INIT(ams->waiting_lock); 00072 ams->waiting_cond = (COND_T*)malloc(sizeof(COND_T)); 00073 COND_INIT(ams->waiting_cond); 00074 00075 return ams; 00076 } 00077 00078 void 00079 ams_Print(ams_p ams) 00080 { 00081 int i; 00082 MCAgent_t agent; 00083 agent_queue_p alist; 00084 00085 alist = ams->mc_platform->agent_queue; 00086 00087 MUTEX_LOCK(alist->lock); 00088 00089 if(alist->size == 0) 00090 { 00091 MUTEX_UNLOCK(alist->lock); 00092 return; 00093 } 00094 00095 /* find all agents and print their relvent information to the screen */ 00096 printf("%d total agents on board.\n", alist->size); 00097 for(i=0; i<alist->size; i++) 00098 { 00099 agent = (MCAgent_t)ListSearch(alist->list, i); 00100 printf("Agent id: %lu, Connect id: %lu, status: %u\n", 00101 agent->id, 00102 agent->connect_id, 00103 agent->agent_status); 00104 } 00105 00106 MUTEX_UNLOCK(alist->lock); 00107 return; 00108 } 00109 00110 extern int 00111 ams_ManageAgentList(ams_p ams) 00112 { 00113 /*variables */ 00114 MCAgent_t current_agent; 00115 int index; 00116 agent_queue_p alist; 00117 mc_platform_p global; 00118 message_p message; 00119 00120 alist = ams->mc_platform->agent_queue; 00121 global = ams->mc_platform; 00122 00123 /* looks through the agent list and performs action on agent 00124 depending upon the status that the agent displays */ 00125 MUTEX_LOCK(alist->lock); 00126 for(index=0; index<alist->size; index++) 00127 { 00128 if((current_agent = ListSearch(alist->list, index))) 00129 { 00130 MUTEX_UNLOCK(alist->lock); 00131 MUTEX_LOCK(current_agent->lock); 00132 current_agent->orphan = 0; 00133 switch(current_agent->agent_status) 00134 { 00135 case MC_WAIT_CH : 00136 MUTEX_UNLOCK(current_agent->lock); 00137 agent_RunChScript(current_agent, global); 00138 break; 00139 case MC_AGENT_ACTIVE : 00140 MUTEX_UNLOCK(current_agent->lock); 00141 /* nothing is done if the agent in question is ACTIVE */ 00142 break; 00143 case MC_WAIT_MESSGSEND : 00144 current_agent->agent_status = MC_WAIT_FINISHED; 00145 MUTEX_UNLOCK(current_agent->lock); 00146 MUTEX_LOCK(ams->runflag_lock); 00147 ams->run = 1; 00148 MUTEX_UNLOCK(ams->runflag_lock); 00149 MUTEX_UNLOCK(current_agent->lock); 00150 message = message_New(); 00151 if ( 00152 message_InitializeFromAgent 00153 ( 00154 ams->mc_platform, 00155 message, 00156 current_agent 00157 ) 00158 ) 00159 { 00160 message_Destroy(message); 00161 message = NULL; 00162 } else { 00163 message_queue_Add( 00164 ams->mc_platform->message_queue, 00165 message 00166 ); 00167 } 00168 break; 00169 case MC_AGENT_NEUTRAL : 00170 MUTEX_UNLOCK(current_agent->lock); 00171 break; 00172 case MC_WAIT_FINISHED : 00173 MUTEX_UNLOCK(current_agent->lock); 00174 agent_queue_RemoveIndex(alist, index); 00175 index=0; 00176 break; 00177 default : 00178 printf("ERROR IN AGENT FORMAT"); 00179 printf("Agent Format %d not recognized.", 00180 current_agent->agent_status); 00181 /* Flush the invalid agent. */ 00182 current_agent->agent_status = MC_WAIT_FINISHED; 00183 MUTEX_UNLOCK(current_agent->lock); 00184 } 00185 } else { 00186 MUTEX_UNLOCK( alist->lock ); 00187 } 00188 MUTEX_LOCK( alist->lock ); 00189 } 00190 MUTEX_UNLOCK( alist->lock ); 00191 return 0 ; 00192 } 00193 00194 void 00195 ams_Start(mc_platform_p mc_platform) 00196 { 00197 ams_p ams = mc_platform->ams; 00198 #ifndef _WIN32 00199 pthread_attr_t attr; 00200 pthread_attr_init(&attr); 00201 if(mc_platform->stack_size[MC_THREAD_AMS] != -1) { 00202 pthread_attr_setstacksize 00203 ( 00204 &attr, 00205 mc_platform->stack_size[MC_THREAD_AMS] 00206 ); 00207 } 00208 #else 00209 int stack_size; 00210 if (mc_platform->stack_size[MC_THREAD_AMS] < 1) { 00211 /* In windows, 0 is default, not min */ 00212 stack_size = mc_platform->stack_size[MC_THREAD_AMS]+1; 00213 } else { 00214 stack_size = mc_platform->stack_size[MC_THREAD_AMS]; 00215 } 00216 #endif 00217 THREAD_CREATE 00218 ( 00219 &ams->thread, 00220 ams_Thread, 00221 mc_platform 00222 ); 00223 } 00224 #ifndef _WIN32 00225 void* 00226 ams_Thread(void* arg) 00227 #else 00228 DWORD WINAPI 00229 ams_Thread( LPVOID arg ) 00230 #endif 00231 { 00232 mc_platform_p mc_platform = (mc_platform_p)arg; 00233 ams_p ams = mc_platform->ams; 00234 00235 while(1) { 00236 MUTEX_LOCK(ams->runflag_lock); 00237 MUTEX_LOCK(mc_platform->quit_lock); 00238 while(ams->run == 0 && !mc_platform->quit) { 00239 MUTEX_UNLOCK(mc_platform->quit_lock); 00240 /* Set waiting flag */ 00241 MUTEX_LOCK(ams->waiting_lock); 00242 ams->waiting = 1; 00243 COND_BROADCAST(ams->waiting_cond); 00244 MUTEX_UNLOCK(ams->waiting_lock); 00245 /* Wait for activity */ 00246 COND_WAIT 00247 ( 00248 ams->runflag_cond, 00249 ams->runflag_lock 00250 ); 00251 MUTEX_LOCK(mc_platform->quit_lock); 00252 } 00253 /* Set waiting flag */ 00254 MUTEX_LOCK(ams->waiting_lock); 00255 ams->waiting = 0; 00256 COND_BROADCAST(ams->waiting_cond); 00257 MUTEX_UNLOCK(ams->waiting_lock); 00258 if (ams->run == 0 && mc_platform->quit) { 00259 MUTEX_UNLOCK(mc_platform->quit_lock); 00260 MUTEX_UNLOCK(ams->runflag_lock); 00261 return 0; 00262 } 00263 ams->run = 0; 00264 MUTEX_UNLOCK(mc_platform->quit_lock); 00265 MUTEX_UNLOCK(ams->runflag_lock); 00266 ams_ManageAgentList(ams); 00267 } 00268 return NULL; 00269 }