00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include <signal.h>
00025 #include <time_util.h>
00026
00027 #include <iostream>
00028
00029 #include <BrokerC.h>
00030 #include <BasicTaskKernelImpl.h>
00031
00032 #include "RTServerImpl.hh"
00033 #include "RTServerWrapper.hh"
00034
00035 #include "RKTask.hh"
00036 #include "MaxDecayTaskAdvocate.hh"
00037
00038
00039
00040
00041 static struct {
00042
00043
00044
00045 CORBA::ORB_var orb;
00046
00047
00048
00049 RTServerImpl *rtsi;
00050
00051
00052
00053 Broker::Manager_var manager;
00054
00055
00056
00057 Broker::RealTimeTask_var rtt;
00058 } rts_data;
00059
00060
00061
00062
00063
00064
00065 static void sigexit(int sig)
00066 {
00067 if( !CORBA::is_nil(rts_data.manager.in()) &&
00068 !CORBA::is_nil(rts_data.rtt.in()) )
00069 {
00070 rts_data.manager->RemoveTask(rts_data.rtt.in());
00071 }
00072
00073 if( !CORBA::is_nil(rts_data.orb.in()) )
00074 {
00075 rts_data.orb->shutdown();
00076 }
00077
00078 if( rts_data.rtsi != NULL )
00079 {
00080 delete rts_data.rtsi;
00081 }
00082
00083 exit(EXIT_SUCCESS);
00084 }
00085
00086 int main(int argc, char *argv[])
00087 {
00088 int retval = EXIT_FAILURE;
00089
00090 #if defined(HAVE_ACE)
00091
00092 ACE_Log_Msg::instance()->priority_mask(0, ACE_Log_Msg::PROCESS);
00093 #endif
00094
00095 {
00096 struct sigaction sa;
00097 sigset_t sigmask;
00098
00099 sigemptyset(&sigmask);
00100 sigaddset(&sigmask, SIGINT);
00101 sigaddset(&sigmask, SIGTERM);
00102 sigaddset(&sigmask, SIGALRM);
00103 sa.sa_mask = sigmask;
00104 sa.sa_flags = 0;
00105 sa.sa_handler = sigexit;
00106 if( (sigaction(SIGINT, &sa, NULL) == -1) ||
00107 (sigaction(SIGTERM, &sa, NULL) == -1) )
00108 {
00109 ensure(0);
00110 }
00111 }
00112
00113 try
00114 {
00115
00116 rts_data.orb = CORBA::ORB_init(argc, argv);
00117
00118 CORBA::Object_var obj = rts_data.orb->
00119 resolve_initial_references("RootPOA");
00120
00121 PortableServer::POA_var root_poa =
00122 PortableServer::POA::_narrow(obj.in());
00123 PortableServer::POAManager_var mgr = root_poa->the_POAManager();
00124 mgr->activate();
00125
00126 quo::QuoKernel_var qk;
00127
00128 try
00129 {
00130
00131 obj = rts_data.orb->string_to_object("file://quoKernel.ior");
00132 qk = quo::QuoKernel::_narrow(obj.in());
00133 if( CORBA::is_nil(qk.in()) || qk->_non_existent() )
00134 {
00135 qk = quo::QuoKernel::_nil();
00136 }
00137 }
00138 catch(const CORBA::SystemException &e)
00139 {
00140 qk = quo::QuoKernel::_nil();
00141 }
00142 if( CORBA::is_nil(qk.in()) )
00143 {
00144 Qosket::Basic::BasicTaskKernelImpl *btki;
00145
00146
00147 btki = new Qosket::Basic::BasicTaskKernelImpl(rts_data.orb);
00148 qk = btki->_this();
00149 }
00150
00151
00152 const char *manager_ior = "file://manager.ior";
00153 const char *obj_ior = "rtserver.ior";
00154 const char *period = "1s";
00155 CORBA::ULong period_ul = 1000000;
00156 struct {
00157 CORBA::ULong data[128];
00158 CORBA::ULong length;
00159 } compute = { { 0 }, 0 };
00160 const char *task_ior = NULL;
00161 const char *task_name = NULL;
00162 unsigned long run_time = 0;
00163 int lpc, ch, g2g = 1;
00164
00165
00166 while( ((ch = getopt(argc, argv, "hVm:t:n:P:f:o:")) != -1) && g2g )
00167 {
00168 switch( ch )
00169 {
00170 case 'm':
00171 manager_ior = optarg;
00172 if( strlen(manager_ior) == 0 )
00173 {
00174 cerr << argv[0] << ": Manager IOR is empty" << endl;
00175 throw CORBA::BAD_PARAM();
00176 }
00177 break;
00178 case 't':
00179 if( task_name != NULL )
00180 {
00181 cerr << argv[0]
00182 << ": The -n and -t options are mutually exclusive"
00183 << endl;
00184 throw CORBA::BAD_PARAM();
00185 }
00186 task_ior = optarg;
00187 if( strlen(task_ior) == 0 )
00188 {
00189 cerr << argv[0] << ": Task IOR is empty" << endl;
00190 throw CORBA::BAD_PARAM();
00191 }
00192 break;
00193 case 'n':
00194 if( task_ior != NULL )
00195 {
00196 cerr << argv[0]
00197 << ": The -n and -t options are mutually exclusive"
00198 << endl;
00199 throw CORBA::BAD_PARAM();
00200 }
00201 task_name = optarg;
00202 if( strlen(task_name) == 0 )
00203 {
00204 cerr << "Task name is empty" << endl;
00205 }
00206 break;
00207 case 'P':
00208 {
00209 unsigned long long period_ull;
00210
00211 period = optarg;
00212 if( string_to_microsec(&period_ull, period) )
00213 {
00214 period_ul = period_ull;
00215 }
00216 else
00217 {
00218 cerr << "Period value not a time: "
00219 << period
00220 << endl;
00221 throw CORBA::BAD_PARAM();
00222 }
00223 }
00224 break;
00225 case 'f':
00226 {
00227 unsigned long long run_time_ull;
00228
00229 if( string_to_microsec(&run_time_ull, optarg) )
00230 {
00231 run_time = run_time_ull;
00232 }
00233 else
00234 {
00235 cerr << argv[0]
00236 << ": Run for value not a time: "
00237 << period
00238 << endl;
00239 throw CORBA::BAD_PARAM();
00240 }
00241 }
00242 break;
00243 case 'o':
00244 if( strlen(optarg) == 0 )
00245 {
00246 cerr << argv[0]
00247 << ": IOR output file name is empty"
00248 << endl;
00249 throw CORBA::BAD_PARAM();
00250 }
00251 obj_ior = optarg;
00252 break;
00253 case 'V':
00254 cout << PACKAGE_VERSION << endl;
00255 exit(0);
00256 break;
00257 case 'h':
00258 case '?':
00259 default:
00260 g2g = 0;
00261 break;
00262 }
00263 }
00264
00265
00266 for( lpc = optind; lpc < argc; lpc++ )
00267 {
00268 unsigned long long compute_ull;
00269
00270 if( compute.length >= 128 )
00271 {
00272 cerr << "Too many compute values." << endl;
00273 throw CORBA::BAD_PARAM();
00274 }
00275 else if( string_to_microsec(&compute_ull, argv[lpc]) )
00276 {
00277 compute.data[compute.length] = compute_ull;
00278 compute.length += 1;
00279 }
00280 else
00281 {
00282 cerr << "Compute value is not a time: "
00283 << argv[lpc]
00284 << endl;
00285 throw CORBA::BAD_PARAM();
00286 }
00287 }
00288
00289 if( (task_ior == NULL) && (task_name == NULL) )
00290 {
00291 cerr << "No task name or IOR specified" << endl;
00292 g2g = 0;
00293 }
00294 if( g2g )
00295 {
00296
00297 if( run_time > 0 )
00298 {
00299 struct itimerval itv;
00300
00301 signal(SIGALRM, sigexit);
00302 itv.it_interval.tv_sec = 0;
00303 itv.it_interval.tv_usec = 0;
00304 itv.it_value.tv_sec = run_time / 1000000;
00305 itv.it_value.tv_usec = run_time % 1000000;
00306 if( setitimer(ITIMER_REAL, &itv, NULL) < 0 )
00307 {
00308 perror("setitimer");
00309 }
00310 }
00311
00312
00313 if( compute.length == 0 )
00314 {
00315 for( lpc = 0; lpc < 15; lpc++, compute.length++ )
00316 {
00317 compute.data[lpc] = period_ul / 4;
00318 }
00319 for( ; lpc < 20; lpc++, compute.length++ )
00320 {
00321 compute.data[lpc] = period_ul / 2;
00322 }
00323 }
00324
00325
00326 obj = rts_data.orb->string_to_object(manager_ior);
00327 rts_data.manager = Broker::Manager::_narrow(obj.in());
00328 if( CORBA::is_nil(rts_data.manager.in()) )
00329 {
00330 cerr << "Invalid manager IOR: "
00331 << manager_ior
00332 << endl;
00333 throw CORBA::BAD_PARAM();
00334 }
00335
00336
00337 if( task_ior != NULL )
00338 {
00339 obj = rts_data.orb->string_to_object(task_ior);
00340 rts_data.rtt = Broker::RealTimeTask::_narrow(obj.in());
00341 if( CORBA::is_nil(rts_data.rtt.in()) )
00342 {
00343 cerr << "Invalid task factory IOR: "
00344 << task_ior
00345 << endl;
00346 throw CORBA::BAD_PARAM();
00347 }
00348 }
00349 else if( task_name != NULL )
00350 {
00351
00352 try
00353 {
00354 Broker::RealTimeTask_var rtt;
00355 MaxDecayTaskAdvocate *mdta;
00356 Broker::TaskParameters tp;
00357 CORBA::Any value;
00358 RKTask *rkt;
00359
00360 tp.length(1);
00361 tp[0].name = "name";
00362 tp[0].value <<= task_name;
00363 rkt = new RKTask(tp);
00364 rtt = rkt->_this();
00365 mdta = new MaxDecayTaskAdvocate();
00366 value <<= rtt;
00367 mdta->SetDelegateAttribute("remote-object", value);
00368 rts_data.rtt = mdta->_this();
00369 }
00370 catch(const Broker::DuplicateTaskParameter &e)
00371 {
00372 ensure(0);
00373 }
00374 catch(const Broker::InvalidTaskParameter &e)
00375 {
00376 ensure(0);
00377 }
00378 catch(const Broker::MissingTaskParameter &e)
00379 {
00380 ensure(0);
00381 }
00382 }
00383 else
00384 {
00385 ensure(0);
00386 }
00387
00388
00389 try
00390 {
00391 Broker::ScheduleParameters sp;
00392
00393 sp.length(2);
00394 sp[0].name = "period";
00395 sp[0].value <<= period;
00396 sp[1].name = "pid";
00397 sp[1].value <<= (CORBA::Long)getpid();
00398 rts_data.manager->AddTask(rts_data.rtt.in(), sp);
00399 }
00400 catch(const Broker::DuplicateScheduleParameter &e)
00401 {
00402 cerr << e << endl;
00403 cerr << e.name << endl;
00404 throw CORBA::BAD_PARAM();
00405 }
00406 catch(const Broker::InvalidScheduleParameter &e)
00407 {
00408 cerr << e << endl;
00409 cerr << e.message << endl;
00410 throw CORBA::BAD_PARAM();
00411 }
00412 catch(const Broker::MissingScheduleParameter &e)
00413 {
00414 cerr << e << endl;
00415 cerr << e.name << endl;
00416 throw CORBA::BAD_PARAM();
00417 }
00418
00419
00420 rts_data.rtsi = new RTServerImpl(period_ul,
00421 &compute.data[0],
00422 compute.length);
00423 RTServer_var real_rts;
00424
00425 real_rts = rts_data.rtsi->_this();
00426
00427
00428 RTServerWrapper *rtsw = new RTServerWrapper(rts_data.rtt.in(),
00429 period_ul,
00430 period_ul);
00431 RTServer_var rts;
00432
00433 rts = rtsw->_this();
00434
00435 rtsw->initSysconds(qk);
00436 rtsw->initCallbacks(rts_data.orb);
00437 rtsw->linkContract(qk);
00438 rtsw->linkRemoteObject(real_rts.in());
00439
00440
00441 if( obj_ior != NULL )
00442 {
00443 ofstream ostr(obj_ior);
00444 ostr << rts_data.orb->object_to_string(rts.in()) << endl;
00445 ostr.close();
00446 }
00447
00448 cout << "RT server ready, waiting for connection from rt_client..."
00449 << endl;
00450
00451 rts_data.orb->run();
00452
00453 if( !CORBA::is_nil(rts_data.rtt.in()) )
00454 {
00455 rts_data.manager->RemoveTask(rts_data.rtt.in());
00456 }
00457
00458 rts_data.orb->shutdown();
00459
00460 retval = EXIT_SUCCESS;
00461 }
00462 else
00463 {
00464
00465 cerr << "CORBA Server that exerts synthetic CPU load." << endl
00466 << "Usage: "
00467 << argv[0]
00468 << " [options] [<compute-time1> <compute-time2> ...]\n"
00469
00470 << endl
00471
00472 << " -m <ior>\tThe Broker::Manager IOR."
00473 << " (Default: " << manager_ior << ")" << endl
00474
00475 << " -n <name>\tThe name of the task to create." << endl
00476
00477 << " -t <ior>\tThe Broker::RealTimeTask IOR." << endl
00478
00479 << " -o <file>\tThe file name for the object's IOR."
00480 << " (Default: " << obj_ior << ")" << endl
00481
00482 << " -P <time>\tThe task's period."
00483 << " (Default: " << period << ")" << endl
00484
00485 << " -f <time>\tThe amount of time to run for."
00486 << " (Default: forever)" << endl
00487
00488 << endl
00489
00490 << "Package: " << PACKAGE_STRING << endl
00491 << "Contact: " << PACKAGE_BUGREPORT << endl;
00492 }
00493 }
00494 catch(const CORBA::SystemException &e)
00495 {
00496 cerr << "Caught Exception: " << e << endl;
00497 }
00498 catch(...)
00499 {
00500 cerr << "Caught an unhandled exception" << endl;
00501 }
00502 return( retval );
00503 }