2 #include "tao/RTScheduling/Current.h"
3 #include "tao/RTScheduling/Distributable_Thread.h"
4 #include "tao/RTCORBA/Priority_Mapping_Manager.h"
5 #include "tao/RTCORBA/RT_Current.h"
6 #include "tao/ORB_Core.h"
7 #include "tao/TSS_Resources.h"
9 #include "ace/OS_NS_errno.h"
10 #include "ace/OS_NS_string.h"
12 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
14 std::atomic
<long> TAO_RTScheduler_Current::guid_counter
;
17 TAO_DTId_Hash::operator () (const IdType
&id
) const
19 return ACE::hash_pjw ((const char *) id
.get_buffer (),
23 TAO_RTScheduler_Current::~TAO_RTScheduler_Current ()
28 TAO_RTScheduler_Current::init (TAO_ORB_Core
* orb
)
32 // Create the RT_Current.
33 RTCORBA::Current_ptr current
;
34 ACE_NEW_THROW_EX (current
,
36 CORBA::NO_MEMORY (CORBA::SystemException::_tao_minor_code (
39 CORBA::COMPLETED_NO
));
40 this->rt_current_
= current
;
44 TAO_RTScheduler_Current::rt_current (RTCORBA::Current_ptr rt_current
)
46 this->rt_current_
= RTCORBA::Current::_duplicate (rt_current
);
50 TAO_RTScheduler_Current::orb ()
56 TAO_RTScheduler_Current::dt_hash ()
58 return &this->dt_hash_
;
62 TAO_RTScheduler_Current::begin_scheduling_segment (
64 CORBA::Policy_ptr sched_param
,
65 CORBA::Policy_ptr implicit_sched_param
)
67 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
71 ACE_NEW_THROW_EX (impl
,
72 TAO_RTScheduler_Current_i (this->orb_
,
75 CORBA::SystemException::_tao_minor_code (
78 CORBA::COMPLETED_NO
));
80 this->implementation (impl
);
83 impl
->begin_scheduling_segment (name
,
85 implicit_sched_param
);
89 TAO_RTScheduler_Current::update_scheduling_segment (const char * name
,
90 CORBA::Policy_ptr sched_param
,
91 CORBA::Policy_ptr implicit_sched_param
)
93 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
96 throw ::CORBA::BAD_INV_ORDER ();
98 impl
->update_scheduling_segment (name
,
100 implicit_sched_param
);
104 TAO_RTScheduler_Current::end_scheduling_segment (const char * name
)
106 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
110 TAOLIB_ERROR ((LM_ERROR
,
111 "Missing scheduling context OR DT cancelled\n"));
112 throw ::CORBA::BAD_INV_ORDER ();
116 impl
->end_scheduling_segment (name
);
119 RTScheduling::DistributableThread_ptr
120 TAO_RTScheduler_Current::lookup(const RTScheduling::Current::IdType
& id
)
122 RTScheduling::DistributableThread_var DT
;
123 int result
= this->dt_hash_
.find (id
,
127 else return RTScheduling::DistributableThread::_nil ();
130 // returns a null reference if
131 // the distributable thread is
132 // not known to the local scheduler
133 RTScheduling::DistributableThread_ptr
134 TAO_RTScheduler_Current::spawn (RTScheduling::ThreadAction_ptr start
,
135 CORBA::VoidData data
,
137 CORBA::Policy_ptr sched_param
,
138 CORBA::Policy_ptr implicit_sched_param
,
139 CORBA::ULong stack_size
,
140 RTCORBA::Priority base_priority
)
142 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
145 throw ::CORBA::BAD_INV_ORDER ();
147 return impl
->spawn (start
,
151 implicit_sched_param
,
156 RTScheduling::Current::IdType
*
157 TAO_RTScheduler_Current::id ()
159 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
162 throw ::CORBA::BAD_INV_ORDER ();
168 TAO_RTScheduler_Current::scheduling_parameter ()
170 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
173 throw ::CORBA::BAD_INV_ORDER ();
175 return impl
->scheduling_parameter ();
179 TAO_RTScheduler_Current::implicit_scheduling_parameter ()
181 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
184 throw ::CORBA::BAD_INV_ORDER ();
186 return impl
->implicit_scheduling_parameter ();
189 RTScheduling::Current::NameList
*
190 TAO_RTScheduler_Current::current_scheduling_segment_names ()
192 TAO_RTScheduler_Current_i
*impl
= this->implementation ();
195 throw ::CORBA::BAD_INV_ORDER ();
197 return impl
->current_scheduling_segment_names ();
201 TAO_RTScheduler_Current::the_priority ()
203 return this->rt_current_
->the_priority ();
207 TAO_RTScheduler_Current::the_priority (RTCORBA::Priority the_priority
)
209 this->rt_current_
->the_priority(the_priority
);
212 TAO_RTScheduler_Current_i
*
213 TAO_RTScheduler_Current::implementation (TAO_RTScheduler_Current_i
* new_current
)
215 TAO_TSS_Resources
*tss
=
216 TAO_TSS_Resources::instance ();
218 TAO_RTScheduler_Current_i
*old
=
219 static_cast<TAO_RTScheduler_Current_i
*> (tss
->rtscheduler_current_impl_
);
220 tss
->rtscheduler_current_impl_
= new_current
;
225 TAO_RTScheduler_Current_i
*
226 TAO_RTScheduler_Current::implementation ()
228 TAO_TSS_Resources
*tss
=
229 TAO_TSS_Resources::instance ();
231 TAO_RTScheduler_Current_i
* impl
=
232 static_cast<TAO_RTScheduler_Current_i
*> (tss
->rtscheduler_current_impl_
);
237 TAO_RTScheduler_Current_i::orb ()
243 TAO_RTScheduler_Current_i::dt_hash ()
245 return this->dt_hash_
;
248 RTScheduling::Scheduler_ptr
249 TAO_RTScheduler_Current_i::scheduler ()
251 return RTScheduling::Scheduler::_duplicate (this->scheduler_
.in ());
254 TAO_RTScheduler_Current_i::TAO_RTScheduler_Current_i (TAO_ORB_Core
* orb
,
255 DT_Hash_Map
* dt_hash
)
257 dt_ (RTScheduling::DistributableThread::_nil ()),
258 previous_current_ (0),
261 CORBA::Object_var scheduler_obj
=
262 this->orb_
->object_ref_table ().resolve_initial_reference (
265 this->scheduler_
= RTScheduling::Scheduler::_narrow (scheduler_obj
.in ());
268 TAO_RTScheduler_Current_i::TAO_RTScheduler_Current_i (
270 DT_Hash_Map
* dt_hash
,
271 RTScheduling::Current::IdType guid
,
273 CORBA::Policy_ptr sched_param
,
274 CORBA::Policy_ptr implicit_sched_param
,
275 RTScheduling::DistributableThread_ptr dt
,
276 TAO_RTScheduler_Current_i
* prev_current
)
279 name_ (CORBA::string_dup (name
)),
280 sched_param_ (CORBA::Policy::_duplicate (sched_param
)),
281 implicit_sched_param_ (CORBA::Policy::_duplicate (implicit_sched_param
)),
282 dt_ (RTScheduling::DistributableThread::_duplicate (dt
)),
283 previous_current_ (prev_current
),
286 CORBA::Object_var scheduler_obj
=
287 orb
->object_ref_table ().resolve_initial_reference (
290 this->scheduler_
= RTScheduling::Scheduler::_narrow (scheduler_obj
.in ());
293 TAO_RTScheduler_Current_i::~TAO_RTScheduler_Current_i ()
298 TAO_RTScheduler_Current_i::begin_scheduling_segment(
300 CORBA::Policy_ptr sched_param
,
301 CORBA::Policy_ptr implicit_sched_param
)
303 // Check if it is a new Scheduling Segmnet
304 if (this->guid_
.length () == 0)
307 size_t temp
= ++TAO_RTScheduler_Current::guid_counter
;
308 this->guid_
.length (sizeof(size_t));
309 ACE_OS::memcpy (this->guid_
.get_buffer (),
314 ACE_OS::memcpy (&guid
,
315 this->guid_
.get_buffer (),
316 this->guid_
.length ());
319 // Inform the scheduler of the new scheduling segment.
320 this->scheduler_
->begin_new_scheduling_segment (this->guid_
,
323 implicit_sched_param
);
325 if (CORBA::is_nil (this->dt_
.in ()))
327 this->dt_
= TAO_DistributableThread_Factory::create_DT ();
330 int result
= this->dt_hash_
->bind (this->guid_
,
333 // Error in binding to the map - cancel thread.
336 this->cancel_thread ();
339 // Remember parameters for the scheduling segment.
340 this->name_
= CORBA::string_dup (name
);
341 this->sched_param_
= CORBA::Policy::_duplicate (sched_param
);
342 this->implicit_sched_param_
= CORBA::Policy::_duplicate (implicit_sched_param
);
344 else //Nested segment
346 // Check current DT state.
347 if (this->dt_
->state () == RTScheduling::DistributableThread::CANCELLED
)
349 this->cancel_thread ();
352 // Inform scheduler of start of nested scheduling segment.
353 this->scheduler_
->begin_nested_scheduling_segment
357 implicit_sched_param
);
359 TAO_TSS_Resources
*tss
=
360 TAO_TSS_Resources::instance ();
362 TAO_RTScheduler_Current_i
* new_current
= 0;
363 ACE_NEW_THROW_EX (new_current
,
364 TAO_RTScheduler_Current_i (this->orb_
,
369 implicit_sched_param
,
373 CORBA::SystemException::_tao_minor_code (
376 CORBA::COMPLETED_NO
));
378 tss
->rtscheduler_current_impl_
= new_current
;
383 TAO_RTScheduler_Current_i::update_scheduling_segment (const char * name
,
384 CORBA::Policy_ptr sched_param
,
385 CORBA::Policy_ptr implicit_sched_param
)
387 // Check if DT has been cancelled
388 if (this->dt_
->state () == RTScheduling::DistributableThread::CANCELLED
)
390 this->cancel_thread ();
393 // Let scheduler know of the updates.
394 this->scheduler_
->update_scheduling_segment (this->guid_
,
397 implicit_sched_param
);
399 // Remember the new values.
400 this->name_
= CORBA::string_dup (name
);
401 this->sched_param_
= CORBA::Policy::_duplicate (sched_param
);
402 this->implicit_sched_param_
= CORBA::Policy::_duplicate (implicit_sched_param
);
406 TAO_RTScheduler_Current_i::end_scheduling_segment (const char * name
)
408 // Check if DT has been cancelled
409 if (this->dt_
->state () == RTScheduling::DistributableThread::CANCELLED
)
411 this->cancel_thread ();
414 if (this->previous_current_
== 0)
416 // Let the scheduler know that the DT is
418 this->scheduler_
->end_scheduling_segment(this->guid_
, name
);
424 this->cleanup_current ();
428 // Inform scheduler of end of nested
429 // scheduling segment.
430 this->scheduler_
->end_nested_scheduling_segment (this->guid_
,
432 this->previous_current_
->sched_param_
.in ());
435 this->cleanup_current ();
439 // returns a null reference if
440 // the distributable thread is
441 // not known to the local scheduler
442 RTScheduling::DistributableThread_ptr
443 TAO_RTScheduler_Current_i::spawn (RTScheduling::ThreadAction_ptr start
,
444 CORBA::VoidData data
,
446 CORBA::Policy_ptr sched_param
,
447 CORBA::Policy_ptr implicit_sched_param
,
448 CORBA::ULong stack_size
,
449 RTCORBA::Priority base_priority
)
451 // Check if DT has been cancelled.
452 if (this->dt_
->state () == RTScheduling::DistributableThread::CANCELLED
)
454 this->cancel_thread ();
457 // Create new task for new DT.
460 // If no scheduling parameter is specified then use the current
461 // implicit scheduling parameter as the scheduling parameter
462 if (sched_param
== 0)
463 sched_param
= this->implicit_sched_param_
.in ();
465 RTScheduling::DistributableThread_var dt
= TAO_DistributableThread_Factory::create_DT ();
466 TAO_RTScheduler_Current_i
*new_current
= 0;
468 ACE_NEW_RETURN (new_current
,
469 TAO_RTScheduler_Current_i (this->orb_
,
473 new_current
->DT (dt
.in ());
475 ACE_NEW_RETURN (dttask
,
476 DTTask (//thread_manager_,
484 implicit_sched_param
),
487 if (dttask
->activate_task (base_priority
,
490 TAOLIB_ERROR((LM_ERROR
,
491 "Unable to activate DistributableThread\n"));
494 return RTScheduling::DistributableThread::_nil ();
501 DTTask::activate_task (RTCORBA::Priority base_priority
,
502 CORBA::ULong stack_size
)
505 long default_flags
= THR_NEW_LWP
| THR_JOINABLE
;
508 this->orb_
->orb_params ()->scope_policy () |
509 this->orb_
->orb_params ()->sched_policy ();
511 CORBA::Object_var object
=
512 this->orb_
->object_ref_table ().resolve_initial_reference (
513 TAO_OBJID_PRIORITYMAPPINGMANAGER
);
515 RTCORBA::PriorityMappingManager_var mapping_manager
=
516 RTCORBA::PriorityMappingManager::_narrow (object
.in ());
518 RTCORBA::PriorityMapping
*pm
=
519 mapping_manager
->mapping ();
521 RTCORBA::NativePriority native_priority
;
522 pm
->to_native (base_priority
,
526 stack
[0] = stack_size
;
527 if (this->activate (flags
,
530 native_priority
,//priority
538 if (ACE_OS::last_error () == EPERM
)
539 TAOLIB_ERROR_RETURN ((LM_ERROR
,
540 ACE_TEXT ("Insufficient privilege to run this test.\n")),
546 DTTask::DTTask (TAO_ORB_Core
*orb
,
548 TAO_RTScheduler_Current_i
* new_current
,
549 RTScheduling::ThreadAction_ptr start
,
550 CORBA::VoidData data
,
552 CORBA::Policy_ptr sched_param
,
553 CORBA::Policy_ptr implicit_sched_param
)
555 // dt_hash_ (dt_hash),
556 current_ (new_current
),
557 start_ (RTScheduling::ThreadAction::_duplicate (start
)),
559 name_ (CORBA::string_dup (name
)),
560 sched_param_ (CORBA::Policy::_duplicate (sched_param
)),
561 implicit_sched_param_ (CORBA::Policy::_duplicate (implicit_sched_param
))
567 delete this->current_
;
575 TAO_TSS_Resources
*tss
=
576 TAO_TSS_Resources::instance ();
578 tss
->rtscheduler_current_impl_
= this->current_
;
580 this->current_
->begin_scheduling_segment (this->name_
.in (),
581 this->sched_param_
.in (),
582 this->implicit_sched_param_
.in ());
584 // Invoke entry point into new DT.
585 this->start_
->_cxx_do (this->data_
);
587 this->current_
->end_scheduling_segment (this->name_
.in ());
589 catch (const ::CORBA::Exception
& ex
)
591 ex
._tao_print_exception ("Caught exception:");
598 RTScheduling::Current::IdType
*
599 TAO_RTScheduler_Current_i::id ()
601 RTScheduling::Current::IdType_var guid
= this->guid_
;
602 return guid
._retn ();
607 TAO_RTScheduler_Current_i::scheduling_parameter ()
609 return CORBA::Policy::_duplicate (this->sched_param_
.in ());
613 TAO_RTScheduler_Current_i::implicit_scheduling_parameter ()
615 return CORBA::Policy::_duplicate (this->implicit_sched_param_
.in ());
618 RTScheduling::Current::NameList
*
619 TAO_RTScheduler_Current_i::current_scheduling_segment_names ()
621 RTScheduling::Current::NameList
* name_list
;
622 ACE_NEW_RETURN (name_list
,
623 RTScheduling::Current::NameList
,
626 TAO_RTScheduler_Current_i
* current
= this;
628 for (int index
= 0; current
!= 0; index
++)
630 name_list
->length (index
+1);
631 (*name_list
) [index
] = current
->name ();
632 current
= current
->previous_current_
;
639 TAO_RTScheduler_Current_i::name ()
641 return this->name_
.in ();
644 #if defined (THREAD_CANCELLED)
645 #undef THREAD_CANCELLED
646 #endif /* THREAD_CANCELLED */
649 TAO_RTScheduler_Current_i::cancel_thread ()
652 ACE_OS::memcpy (&guid
,
653 this->guid_
.get_buffer (),
654 this->guid_
.length ());
656 TAOLIB_DEBUG ((LM_DEBUG
,
657 "Distributable Thread - %d is cancelled\n",
660 // Let the scheduler know that the thread has
662 this->scheduler_
->cancel (this->guid_
);
666 // Remove all related nested currents.
667 this->delete_all_currents ();
670 throw ::CORBA::THREAD_CANCELLED ();
674 TAO_RTScheduler_Current_i::cleanup_DT ()
676 // Remove DT from map.
677 this->dt_hash_
->unbind (this->guid_
);
681 TAO_RTScheduler_Current_i::cleanup_current ()
683 TAO_TSS_Resources
*tss
=
684 TAO_TSS_Resources::instance ();
686 tss
->rtscheduler_current_impl_
= this->previous_current_
;
688 // Delete this current.
693 TAO_RTScheduler_Current_i::delete_all_currents ()
695 TAO_RTScheduler_Current_i
* current
= this;
699 TAO_RTScheduler_Current_i
* prev_current
= current
->previous_current_
;
700 current
->cleanup_current ();
701 current
= prev_current
;
704 TAO_TSS_Resources
*tss
=
705 TAO_TSS_Resources::instance ();
707 tss
->rtscheduler_current_impl_
= tss
->rtscheduler_previous_current_impl_
;
711 TAO_RTScheduler_Current_i::id (RTScheduling::Current::IdType guid
)
717 TAO_RTScheduler_Current_i::name (const char * name
)
719 this->name_
= CORBA::string_dup (name
);
722 RTScheduling::DistributableThread_ptr
723 TAO_RTScheduler_Current_i::DT ()
725 return this->dt_
._retn ();
729 TAO_RTScheduler_Current_i::DT (RTScheduling::DistributableThread_ptr dt
)
731 this->dt_
= RTScheduling::DistributableThread::_duplicate (dt
);
735 TAO_RTScheduler_Current_i::scheduling_parameter (CORBA::Policy_ptr sched_param
)
737 this->sched_param_
= CORBA::Policy::_duplicate (sched_param
);
741 TAO_RTScheduler_Current_i::implicit_scheduling_parameter (CORBA::Policy_ptr implicit_sched_param
)
743 this->implicit_sched_param_
= CORBA::Policy::_duplicate (implicit_sched_param
);
747 // *************************************************************
749 // *************************************************************
750 // Operations for class TAO_RTScheduler_Current_var
751 // *************************************************************
752 TAO_RTScheduler_Current_var::TAO_RTScheduler_Current_var () // default constructor
753 : ptr_ (TAO_RTScheduler_Current::_nil ())
756 ::TAO_RTScheduler_Current_ptr
757 TAO_RTScheduler_Current_var::ptr () const
762 TAO_RTScheduler_Current_var::TAO_RTScheduler_Current_var (const ::TAO_RTScheduler_Current_var
&p
)
764 ptr_ (TAO_RTScheduler_Current::_duplicate (p
.ptr ()))
767 TAO_RTScheduler_Current_var::~TAO_RTScheduler_Current_var () // destructor
769 ::CORBA::release (this->ptr_
);
772 TAO_RTScheduler_Current_var
&
773 TAO_RTScheduler_Current_var::operator= (TAO_RTScheduler_Current_ptr p
)
775 ::CORBA::release (this->ptr_
);
780 TAO_RTScheduler_Current_var
&
781 TAO_RTScheduler_Current_var::operator= (const ::TAO_RTScheduler_Current_var
&p
)
785 ::CORBA::release (this->ptr_
);
786 this->ptr_
= ::TAO_RTScheduler_Current::_duplicate (p
.ptr ());
791 TAO_RTScheduler_Current_var::operator const ::TAO_RTScheduler_Current_ptr
&() const
796 TAO_RTScheduler_Current_var::operator ::TAO_RTScheduler_Current_ptr
&()
801 TAO_RTScheduler_Current_ptr
802 TAO_RTScheduler_Current_var::operator-> () const
807 TAO_RTScheduler_Current_ptr
808 TAO_RTScheduler_Current_var::in () const
813 TAO_RTScheduler_Current_ptr
&
814 TAO_RTScheduler_Current_var::inout ()
819 TAO_RTScheduler_Current_ptr
&
820 TAO_RTScheduler_Current_var::out ()
822 ::CORBA::release (this->ptr_
);
823 this->ptr_
= ::TAO_RTScheduler_Current::_nil ();
827 TAO_RTScheduler_Current_ptr
828 TAO_RTScheduler_Current_var::_retn ()
830 // yield ownership of managed obj reference
831 ::TAO_RTScheduler_Current_ptr val
= this->ptr_
;
832 this->ptr_
= ::TAO_RTScheduler_Current::_nil ();
836 TAO_RTScheduler_Current_ptr
837 TAO_RTScheduler_Current_var::duplicate (TAO_RTScheduler_Current_ptr p
)
839 return ::TAO_RTScheduler_Current::_duplicate (p
);
843 TAO_RTScheduler_Current_var::release (TAO_RTScheduler_Current_ptr p
)
845 ::CORBA::release (p
);
848 TAO_RTScheduler_Current_ptr
849 TAO_RTScheduler_Current_var::nil ()
851 return ::TAO_RTScheduler_Current::_nil ();
854 TAO_RTScheduler_Current_ptr
855 TAO_RTScheduler_Current_var::narrow (CORBA::Object
*p
)
857 return ::TAO_RTScheduler_Current::_narrow (p
);
861 TAO_RTScheduler_Current_var::upcast (void *src
)
863 TAO_RTScheduler_Current
**tmp
=
864 static_cast<TAO_RTScheduler_Current
**> (src
);
868 TAO_RTScheduler_Current_ptr
TAO_RTScheduler_Current::_narrow (
869 CORBA::Object_ptr obj
)
872 TAO_RTScheduler_Current::_duplicate (
873 dynamic_cast<TAO_RTScheduler_Current
*> (obj
));
876 TAO_RTScheduler_Current_ptr
877 TAO_RTScheduler_Current::_duplicate (TAO_RTScheduler_Current_ptr obj
)
879 if (!CORBA::is_nil (obj
))
884 const char* TAO_RTScheduler_Current::_interface_repository_id () const
886 return "IDL:TAO_RTScheduler_Current:1.0";
889 TAO_END_VERSIONED_NAMESPACE_DECL