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