/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/ams.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 207 $ : Last Committed Revision
00003  * $Date: 2008-07-11 17:55:19 -0700 (Fri, 11 Jul 2008) $ : 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 }

Generated on Fri Jul 11 17:59:44 2008 for Mobile-C by  doxygen 1.5.4