/home/dko/projects/mobilec/trunk/src/ams.c

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 #include "include/ams.h"
00033 #include "include/agent.h"
00034 #include "include/data_structures.h"
00035 #include "include/mc_platform.h"
00036 
00037   int
00038 ams_Destroy(ams_p ams)
00039 {
00040   MUTEX_DESTROY(ams->runflag_lock);
00041   free(ams->runflag_lock);
00042   COND_DESTROY(ams->runflag_cond);
00043   free(ams->runflag_cond);
00044   free(ams);
00045   return MC_SUCCESS;
00046 }
00047 
00048   ams_p 
00049 ams_Initialize(mc_platform_p mc_platform)
00050 {
00051   ams_p ams;
00052   ams = (ams_p)malloc(sizeof(ams_t));
00053   CHECK_NULL(ams, exit(0););
00054   ams->mc_platform = mc_platform;
00055 
00056   ams->runflag_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00057   CHECK_NULL(ams->runflag_lock, exit(0););
00058   MUTEX_INIT(ams->runflag_lock);
00059 
00060   ams->runflag_cond = (COND_T*)malloc(sizeof(COND_T));
00061   CHECK_NULL(ams->runflag_cond, exit(0););
00062   COND_INIT(ams->runflag_cond);
00063 
00064   ams->run = 0;
00065 
00066   ams->waiting = 0;
00067   ams->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00068   MUTEX_INIT(ams->waiting_lock);
00069   ams->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00070   COND_INIT(ams->waiting_cond);
00071 
00072   return ams;
00073 }
00074 
00075   void 
00076 ams_Print(ams_p ams)
00077 {
00078   int i;
00079   MCAgent_t agent;
00080   agent_queue_p alist;
00081 
00082   alist = ams->mc_platform->agent_queue;
00083 
00084   MUTEX_LOCK(alist->lock);
00085 
00086   if(alist->size == 0) 
00087   {
00088     MUTEX_UNLOCK(alist->lock);
00089     return;
00090   }
00091 
00092   /* find all agents and print their relvent information to the screen  */
00093   printf("%d total agents on board.\n", alist->size);
00094   for(i=0; i<alist->size; i++)
00095   {
00096     agent = (MCAgent_t)ListSearch(alist->list, i);
00097     printf("Agent id: %lu, Connect id: %lu, status: %u\n",
00098         agent->id,
00099         agent->connect_id,
00100         agent->agent_status);
00101   }
00102 
00103   MUTEX_UNLOCK(alist->lock);
00104   return;
00105 }
00106 
00107   extern int 
00108 ams_ManageAgentList(ams_p ams)
00109 {
00110   /*variables */
00111   MCAgent_t current_agent;
00112   int index;
00113   agent_queue_p alist;
00114   mc_platform_p global;
00115   message_p message;
00116 
00117   alist = ams->mc_platform->agent_queue;
00118   global = ams->mc_platform;
00119 
00120   /* looks through the agent list and performs action on agent 
00121      depending upon the status that the agent displays */
00122   MUTEX_LOCK(alist->lock);
00123   for(index=0; index<alist->size; index++)
00124   {
00125     if((current_agent = ListSearch(alist->list, index)))
00126     {
00127       MUTEX_UNLOCK(alist->lock);
00128       MUTEX_LOCK(current_agent->lock);
00129       current_agent->orphan = 0;
00130       switch(current_agent->agent_status)
00131       {
00132         case MC_WAIT_CH :
00133           MUTEX_UNLOCK(current_agent->lock);
00134           agent_RunChScript(current_agent, global);
00135           break;
00136         case MC_AGENT_ACTIVE :
00137           MUTEX_UNLOCK(current_agent->lock);
00138           /* nothing is done if the agent in question is ACTIVE */
00139           break;
00140         case MC_WAIT_MESSGSEND :
00141           current_agent->agent_status = MC_WAIT_FINISHED;
00142           MUTEX_UNLOCK(current_agent->lock);
00143           MUTEX_LOCK(ams->runflag_lock);
00144           ams->run = 1;
00145           MUTEX_UNLOCK(ams->runflag_lock);
00146           MUTEX_UNLOCK(current_agent->lock);
00147           message = message_New();
00148           if (
00149               message_InitializeFromAgent
00150               (
00151                ams->mc_platform,
00152                message,
00153                current_agent
00154               )
00155              )
00156           {
00157             message_Destroy(message);
00158             message = NULL;
00159           } else {
00160             message_queue_Add(
00161                 ams->mc_platform->message_queue,
00162                 message
00163                 );
00164           }
00165           break;
00166         case MC_AGENT_NEUTRAL :
00167           MUTEX_UNLOCK(current_agent->lock);
00168           break;
00169         case MC_WAIT_FINISHED :
00170           MUTEX_UNLOCK(current_agent->lock);
00171           agent_queue_RemoveIndex(alist, index);
00172           index=0;
00173           break;
00174         default : 
00175           printf("ERROR IN AGENT FORMAT"); 
00176           printf("Agent Format %d not recognized.",
00177               current_agent->agent_status);
00178           /* Flush the invalid agent. */
00179           current_agent->agent_status = MC_WAIT_FINISHED;
00180           MUTEX_UNLOCK(current_agent->lock);
00181       }
00182     } else {
00183       MUTEX_UNLOCK( alist->lock );
00184     }
00185     MUTEX_LOCK( alist->lock );
00186   }
00187   MUTEX_UNLOCK( alist->lock );
00188   return 0 ;
00189 }
00190 
00191   void
00192 ams_Start(mc_platform_p mc_platform)
00193 {
00194   ams_p ams = mc_platform->ams;
00195 #ifndef _WIN32
00196   pthread_attr_t attr;
00197   pthread_attr_init(&attr);
00198   if(mc_platform->stack_size[MC_THREAD_AMS] != -1) {
00199     pthread_attr_setstacksize
00200       (
00201        &attr,
00202        mc_platform->stack_size[MC_THREAD_AMS]
00203       );
00204   }
00205 #else
00206   int stack_size;
00207   if (mc_platform->stack_size[MC_THREAD_AMS] < 1) {
00208     /* In windows, 0 is default, not min */
00209     stack_size = mc_platform->stack_size[MC_THREAD_AMS]+1;
00210   } else {
00211     stack_size = mc_platform->stack_size[MC_THREAD_AMS];
00212   }
00213 #endif
00214   THREAD_CREATE
00215     (
00216      &ams->thread,
00217      ams_Thread,
00218      mc_platform
00219     );
00220 }
00221 #ifndef _WIN32
00222   void*
00223 ams_Thread(void* arg)
00224 #else
00225   DWORD WINAPI
00226 ams_Thread( LPVOID arg )
00227 #endif
00228 {
00229   mc_platform_p mc_platform = (mc_platform_p)arg;
00230   ams_p ams = mc_platform->ams;
00231 
00232   while(1) {
00233     MUTEX_LOCK(ams->runflag_lock);
00234     MUTEX_LOCK(mc_platform->quit_lock);
00235     while(ams->run == 0 && !mc_platform->quit) {
00236       MUTEX_UNLOCK(mc_platform->quit_lock);
00237       /* Set waiting flag */
00238       MUTEX_LOCK(ams->waiting_lock);
00239       ams->waiting = 1;
00240       COND_BROADCAST(ams->waiting_cond);
00241       MUTEX_UNLOCK(ams->waiting_lock);
00242       /* Wait for activity */
00243       COND_WAIT
00244         (
00245          ams->runflag_cond,
00246          ams->runflag_lock
00247         );
00248       MUTEX_LOCK(mc_platform->quit_lock);
00249     }
00250     /* Set waiting flag */
00251     MUTEX_LOCK(ams->waiting_lock);
00252     ams->waiting = 0;
00253     COND_BROADCAST(ams->waiting_cond);
00254     MUTEX_UNLOCK(ams->waiting_lock);
00255     if (ams->run == 0 && mc_platform->quit) {
00256       MUTEX_UNLOCK(mc_platform->quit_lock);
00257       MUTEX_UNLOCK(ams->runflag_lock);
00258       return 0;
00259     }
00260     ams->run = 0;
00261     MUTEX_UNLOCK(mc_platform->quit_lock);
00262     MUTEX_UNLOCK(ams->runflag_lock);
00263     ams_ManageAgentList(ams);
00264   }
00265   return NULL;
00266 }

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4