00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include <iostream>
00021
00022 #include <assert_pp.h>
00023 #include <instrumentation.h>
00024
00025 #include "ManagerImpl.hh"
00026
00027 using namespace std;
00028
00029 #define INSTR_manager_change_cpu LRTIME_INSTR
00030 #define INSTR_manager_change_cpu_data "manager_change_cpu", "The wall clock time needed to run ChangeTaskCPU"
00031
00032 #if defined(INSTR_manager_change_cpu_data)
00033 static struct iPoint INSTR_manager_change_cpu_point = {
00034 INSTR_manager_change_cpu_data
00035 };
00036 #endif
00037
00038 ManagerImpl::ManagerImpl(const char *name)
00039 {
00040 static int initialized = 0;
00041
00042 if( !initialized )
00043 {
00044 atexit(iPrintPointsAtExit);
00045 initialized = 1;
00046 }
00047 lnNewList(&this->mi_Tasks);
00048 }
00049
00050 ManagerImpl::~ManagerImpl()
00051 {
00052 }
00053
00054 void ManagerImpl::RepairTaskList(void)
00055 {
00056 struct TaskNode *curr, *next;
00057
00058 curr = (struct TaskNode *)this->mi_Tasks.lh_Head;
00059 while( curr->tn_Link.ln_Succ != NULL )
00060 {
00061 Broker::Task_ptr task = curr->tn_Task.in();
00062
00063 next = (struct TaskNode *)curr->tn_Link.ln_Succ;
00064
00065 try
00066 {
00067 CORBA::String_var name;
00068
00069
00070 name = task->Name();
00071
00072 }
00073 catch(const CORBA::TRANSIENT &e)
00074 {
00075
00076 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00077 {
00078 try
00079 {
00080 this->mi_CurrentPolicy->RemoveTask(task);
00081 }
00082 catch(const CORBA::BAD_PARAM &e)
00083 {
00084
00085 }
00086 catch(const CORBA::SystemException &e)
00087 {
00088 cerr << "Error while repairing: "
00089 << e
00090 << " file: "
00091 << __FILE__
00092 << " line: "
00093 << __LINE__
00094 << endl;
00095 }
00096 }
00097
00098 lnRemove(&curr->tn_Link);
00099 task = Broker::Task::_nil();
00100
00101 delete curr;
00102 curr = NULL;
00103 }
00104
00105 curr = next;
00106 }
00107 }
00108
00109 struct ManagerImpl::TaskNode *ManagerImpl::FindTask(Broker::Task_ptr task)
00110 {
00111 struct TaskNode *curr, *retval = NULL;
00112
00113 curr = (struct TaskNode *)this->mi_Tasks.lh_Head;
00114 while( (curr->tn_Link.ln_Succ != NULL) && (retval == NULL) )
00115 {
00116 if( curr->tn_Task->_is_equivalent(task) )
00117 {
00118 retval = curr;
00119 }
00120 curr = (struct TaskNode *)curr->tn_Link.ln_Succ;
00121 }
00122 return( retval );
00123 }
00124
00125 Broker::Policy_ptr ManagerImpl::CurrentPolicy(void)
00126 throw (CORBA::SystemException)
00127 {
00128 Broker::Policy_var retval;
00129
00130 retval = this->mi_CurrentPolicy;
00131 return( retval._retn() );
00132 }
00133
00134 void ManagerImpl::CurrentPolicy(Broker::Policy_ptr policy)
00135 throw (CORBA::SystemException)
00136 {
00137 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00138 {
00139 struct TaskNode *tn;
00140
00141 tn = (struct TaskNode *)this->mi_Tasks.lh_Head;
00142 while( tn->tn_Link.ln_Succ != NULL )
00143 {
00144 this->mi_CurrentPolicy->RemoveTask(tn->tn_Task.in());
00145 tn = (struct TaskNode *)tn->tn_Link.ln_Succ;
00146 }
00147 }
00148 this->mi_CurrentPolicy = Broker::Policy::_duplicate(policy);
00149 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00150 {
00151 struct TaskNode *tn;
00152
00153 tn = (struct TaskNode *)this->mi_Tasks.lh_Head;
00154 while( tn->tn_Link.ln_Succ != NULL )
00155 {
00156 this->mi_CurrentPolicy->AddTask(tn->tn_Task.in(),
00157 tn->tn_ScheduleParameters);
00158 tn = (struct TaskNode *)tn->tn_Link.ln_Succ;
00159 }
00160 }
00161 }
00162
00163 void ManagerImpl::AddTask(Broker::Task_ptr task,
00164 const Broker::ScheduleParameters &sp)
00165 throw (CORBA::SystemException,
00166 Broker::DuplicateScheduleParameter,
00167 Broker::InvalidScheduleParameter,
00168 Broker::MissingScheduleParameter)
00169 {
00170 if( CORBA::is_nil(task) )
00171 {
00172 throw CORBA::BAD_PARAM();
00173 }
00174
00175
00176 this->RepairTaskList();
00177
00178
00179 if( this->FindTask(task) != NULL )
00180 {
00181 throw CORBA::BAD_PARAM();
00182 }
00183
00184
00185 auto_ptr<struct TaskNode> tn(new TaskNode());
00186
00187
00188 tn->tn_Task = Broker::Task::_duplicate(task);
00189 tn->tn_ScheduleParameters = new Broker::ScheduleParameters(sp);
00190
00191
00192 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00193 {
00194 this->mi_CurrentPolicy->AddTask(task, sp);
00195 }
00196 tn->tn_Task->BeginCPUScheduling(sp);
00197 tn->tn_Task->SetManager(this->_this());
00198
00199
00200 lnAddTail(&this->mi_Tasks, &(tn.release())->tn_Link);
00201 }
00202
00203 void ManagerImpl::RemoveTask(Broker::Task_ptr task)
00204 throw (CORBA::SystemException)
00205 {
00206 struct TaskNode *tn;
00207
00208 if( CORBA::is_nil(task) )
00209 {
00210 throw CORBA::BAD_PARAM();
00211 }
00212
00213
00214 if( (tn = this->FindTask(task)) == NULL )
00215 {
00216 throw CORBA::BAD_PARAM();
00217 }
00218
00219
00220 lnRemove(&tn->tn_Link);
00221
00222
00223 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00224 {
00225 this->mi_CurrentPolicy->RemoveTask(task);
00226 }
00227
00228 delete tn;
00229 }
00230
00231 Broker::TaskList *ManagerImpl::GetTaskList(void)
00232 throw (CORBA::SystemException)
00233 {
00234 Broker::TaskList_var retval;
00235 unsigned int lpc = 0;
00236 struct TaskNode *tn;
00237
00238 retval = new Broker::TaskList();
00239 retval->length(lnCountNodes(&this->mi_Tasks));
00240 tn = (struct TaskNode *)this->mi_Tasks.lh_Head;
00241 while( tn->tn_Link.ln_Succ != NULL )
00242 {
00243 (*retval)[lpc] = Broker::Task::_duplicate(tn->tn_Task.in());
00244 lpc += 1;
00245 tn = (struct TaskNode *)tn->tn_Link.ln_Succ;
00246 }
00247 return( retval._retn() );
00248 }
00249
00250 Broker::CPUReserve ManagerImpl::ChangeTaskCPU(Broker::RealTimeTask_ptr task,
00251 const Broker::CPUReserve &advice)
00252 throw (CORBA::SystemException, Broker::InvalidState)
00253 {
00254 if( CORBA::is_nil(task) )
00255 {
00256 throw CORBA::BAD_PARAM();
00257 }
00258
00259 if( !CORBA::is_nil(this->mi_CurrentPolicy.in()) )
00260 {
00261
00262 return this->mi_CurrentPolicy->ChangeTaskCPU(task, advice);
00263 }
00264 else
00265 {
00266 Broker::CPUReserve retval;
00267
00268 retval = advice;
00269 retval.Compute = 0;
00270 return retval;
00271 }
00272 }
00273
00274 Broker::Task_ptr ManagerImpl::ResolveTask(CORBA::ORB_ptr orb,
00275 Broker::TaskList &tl,
00276 const char *name)
00277 throw (CORBA::SystemException)
00278 {
00279 Broker::Task_var retval;
00280 unsigned int lpc;
00281
00282 require(!CORBA::is_nil(orb));
00283 require(name != NULL);
00284
00285
00286 for( lpc = 0; (lpc < tl.length()) && CORBA::is_nil(retval.in()); lpc++ )
00287 {
00288 try
00289 {
00290 CORBA::String_var task_name;
00291
00292 task_name = tl[lpc]->Name();
00293 if( strcmp(task_name.in(), name) == 0 )
00294 {
00295 retval = Broker::Task::_duplicate(tl[lpc]);
00296 }
00297 }
00298 catch(const CORBA::SystemException &e)
00299 {
00300
00301 }
00302 }
00303 if( CORBA::is_nil(retval.in()) )
00304 {
00305 CORBA::Object_var obj;
00306
00307
00308 try
00309 {
00310 obj = orb->string_to_object(name);
00311 }
00312 catch(const CORBA::SystemException &e)
00313 {
00314 throw CORBA::BAD_PARAM();
00315 }
00316 retval = Broker::Task::_narrow(obj.in());
00317 if( CORBA::is_nil(retval.in()) )
00318 {
00319 throw CORBA::BAD_PARAM();
00320 }
00321 }
00322 return( retval._retn() );
00323 }