[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash/cygnal/ACT ACT.hpp Cygnal_Instances.cpp S...
From: |
Eric Hughes |
Subject: |
[Gnash-commit] gnash/cygnal/ACT ACT.hpp Cygnal_Instances.cpp S... |
Date: |
Tue, 19 Jun 2007 18:52:26 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Eric Hughes <eh9> 07/06/19 18:52:26
Modified files:
cygnal/ACT : ACT.hpp Cygnal_Instances.cpp Scheduler.cpp
Scheduler.hpp Scheduling_Queue.cpp
Scheduling_Queue.hpp
cygnal/ACT/test_support: Listening_Actions.cpp
Listening_Actions.hpp
cygnal/ACT/unit_tests: Test_Scheduler.cpp
Test_Scheduling_Queue.cpp
Added files:
cygnal/ACT : Change_Log.txt
Log message:
Scheduler to stable status.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/ACT.hpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Cygnal_Instances.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduler.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduler.hpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduling_Queue.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduling_Queue.hpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Change_Log.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Listening_Actions.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Listening_Actions.hpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/unit_tests/Test_Scheduler.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/unit_tests/Test_Scheduling_Queue.cpp?cvsroot=gnash&r1=1.1&r2=1.2
Patches:
Index: ACT.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/ACT.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- ACT.hpp 13 Jun 2007 19:29:10 -0000 1.1
+++ ACT.hpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -32,34 +32,7 @@
namespace ACT {
- //-------------------------
- /** \class wakeup_listener
- * \brief The 'A' in ACT means 'asynchronous', so in general there
must be a way of notifying
- * a scheduler that an inactive ACT, one that has a
pending sub-action, is ready to proceed.
- * This class is the interface between a scheduler and such an ACT.
- *
- * The archetype of a notification is that from an asynchronous
system I/O call.
- * These notifications arrive various by event, queue item,
callback, signal, and others.
- * Notification is a mechanism crying out for implementation
hiding by means of an abstraction.
- * This type provides a standard way to do so.
- *
- * The implementation pattern is an ACT call a wakeup_listener and
that a scheduler
- * provide the function so called.
- * The scheduler should encapsulate its own notification receiver,
however structured,
- * into a function object of this class, say, by binding a
member function adapter.
- *
- * Such a function object should be parameter of the ACT
constructor, if required.
- *
- * An alternate design would have to pass a wakeup_listener with
each call.
- * This would be useful if a single ACT were variously handled by
different scheduler objects.
- * This may, perhaps, be an opportunity for greater efficiency.
- * It's not clear as of this writing that such an interface is
necessary.
- */
- class wakeup_listener
- {
- public:
- virtual void operator()() =0 ;
- } ;
+ class wakeup_listener ;
//-------------------------
/** \enum act_state
Index: Cygnal_Instances.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Cygnal_Instances.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Cygnal_Instances.cpp 13 Jun 2007 19:29:11 -0000 1.1
+++ Cygnal_Instances.cpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -32,6 +32,6 @@
namespace ACT {
// Explicit template instantiation.
- template Scheduling_Queue< Basic_Scheduled_Item > ;
+ template Basic_Scheduler::queue_type ;
} // end namespace ACT
Index: Scheduler.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduler.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Scheduler.cpp 13 Jun 2007 19:29:11 -0000 1.1
+++ Scheduler.cpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -28,39 +28,61 @@
// Basic_Scheduled_Item
//--------------------------------------------------
Basic_Scheduled_Item::
- Basic_Scheduled_Item( act x, unsigned int n, Basic_Priority p )
+ Basic_Scheduled_Item( act x, unsigned int n, Action_Category
action_type )
: the_action( x ),
sequence_number( n ),
- priority_category( p )
- {}
+ action_type( action_type )
+ {
+ switch ( action_type ) {
+ case Task :
+ priority_category = Initial ;
+ break ;
+ case Service :
+ priority_category = Background ;
+ break ;
+ default :
+ priority_category = Background ;
+ break ;
+ }
+ }
//-------------------------
bool
Basic_Scheduled_Item::
operator<( const Basic_Scheduled_Item & x ) const
{
- return priority_category < x.priority_category
- || sequence_number > x.sequence_number ;
+ return priority_category > x.priority_category
+ || ( priority_category ==
x.priority_category
+ && sequence_number >
x.sequence_number
+ ) ;
}
//--------------------------------------------------
- // Basic_Scheduler
+ // wakeup_listener_allocated
//--------------------------------------------------
- // Class member initialization
- Basic_Scheduler Basic_Scheduler::the_instance ;
+ wakeup_listener_allocated::
+ wakeup_listener_allocated( size_t x, scheduler_pointer y )
+ : the_wakeup_listener( new wakeup_listener( x, y ) ) {}
- //-------------------------
- // Class factory function member
- Basic_Scheduler &
- Basic_Scheduler::obtain_scheduler()
+ //--------------------------------------------------
+ // wakeup_listener
+ //--------------------------------------------------
+ void
+ wakeup_listener::
+ operator()()
{
- return the_instance ;
+ queue_type & the_queue = the_scheduler -> queue() ;
+ the_queue.item( permutation_index ).priority_category =
Ordinary ;
+ the_queue.reorder( permutation_index ) ;
}
- //-------------------------
+ //--------------------------------------------------
+ // Basic_Scheduler
+ //--------------------------------------------------
Basic_Scheduler::
Basic_Scheduler()
- : operating( true )
+ : operating( true ),
+ next_sequence_number( 1 )
{}
//-------------------------
@@ -97,14 +119,14 @@
Basic_Scheduler::
add_task( act x )
{
- item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++
next_sequence_number ) ) ;
- item -> listener = Basic_Wakeup_Listener( item, & the_queue ) ;
+ item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++
next_sequence_number ), this ) ;
}
void
Basic_Scheduler::
- add_service( act )
+ add_service( act x )
{
+ item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++
next_sequence_number, Service ), this ) ;
}
void
@@ -130,11 +152,15 @@
}
// Assert the_queue is not empty
- Scheduling_Queue< Basic_Scheduled_Item >::reference item =
the_queue.top() ;
- act_state result = item.the_action( & item.listener.get() ) ;
//.get() because .listener is optional<>
+ queue_type::pointer item = the_queue.top_ptr() ;
+ act_state result = item -> the_action(
the_queue.auxiliary_top() -> get() ) ;
if ( result == Working ) {
- item.priority_category = Waiting ;
- the_queue.reorder( the_queue.top_ptr() ) ;
+ if ( item -> action_type == Task ) {
+ // Assert action is not a service
+ item -> priority_category = Waiting ;
+ the_queue.reorder( item ) ;
+ }
+ // Note service actions do not re-prioritize right now
} else {
the_queue.pop() ;
// Perhaps we might want to log items gone bad here.
@@ -150,16 +176,4 @@
return the_queue.top().priority_category <= Ordinary ;
}
- //--------------------------------------------------
- // Basic_Wakeup_Listener
- //--------------------------------------------------
- void
- Basic_Wakeup_Listener::
- operator()()
- {
- the_item -> priority_category = Ordinary ;
- the_scheduler -> reorder( the_item ) ;
- }
-
-
} // end namespace ACT
Index: Scheduler.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduler.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Scheduler.hpp 13 Jun 2007 19:29:11 -0000 1.1
+++ Scheduler.hpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -32,27 +32,81 @@
namespace ACT {
- //using boost::posix_time::ptime ;
-
//-------------------------
- /* Forward declarations for Basic_Wakeup_Listener
+ /* Forward declarations for wakeup_listener
*/
struct Basic_Scheduled_Item ;
+ class Basic_Scheduler ;
+ class wakeup_listener_allocated ;
//-------------------------
- class Basic_Wakeup_Listener
- : public wakeup_listener
+ /** \class wakeup_listener_allocated
+ * \brief A managed-storage wrapper for wakeup listener as it's
used with the Scheduling_Queue
+ *
+ * \par Plans
+ * This class uses the ordinary heap for allocation on an
item-by-item basis.
+ * Since we know that we must have one object of this class
allocated for each task,
+ * we can optimize this memory use by allocating in bulk
and providing a custom allocator.
+ * On the other hand, since these objects are allocated only
during the growth phase,
+ * this allocation strategy has no performance penalty in
the steady state,
+ * except to the extent that excess memory usage causes
unnecessary swapping.
+ */
+ class wakeup_listener_allocated
{
public:
///
- typedef Scheduling_Queue< Basic_Scheduled_Item >::pointer
item_pointer ;
+ typedef Basic_Scheduler * scheduler_pointer ;
+ // typedef wakeup_listener::scheduler_pointer scheduler_pointer
;
+
+ ///
+ typedef scheduler_pointer constructor_parameter ;
+ private:
+ /// The wrapped pointer
+ ///
+ /// I'm using a shared_ptr here because this class must have a
copy constructor for std::vector resizing.
+ /// An auto_ptr won't work with the default copy constructor.
+ boost::shared_ptr< wakeup_listener > the_wakeup_listener ;
+
+ public:
+ /// Ordinary constructor used after item is within a scheduling
queue and its storage location is known.
+ wakeup_listener_allocated( size_t x, scheduler_pointer y ) ;
+
+ ///
+ wakeup_listener * get() const { return
the_wakeup_listener.get() ; }
+
+ ///
+ inline void reconstruct( scheduler_pointer ) {} ;
+ } ;
+
+ //-------------------------
+ /** \class wakeup_listener
+ * \brief The 'A' in ACT means 'asynchronous', so in general there
must be a way of notifying
+ * a scheduler that an inactive ACT, one that has a
pending sub-action, is ready to proceed.
+ * This class is the interface between a scheduler and such an ACT.
+ *
+ * The archetype of a notification is that from an asynchronous
system I/O call.
+ * These notifications arrive various by event, queue item,
callback, signal, and others.
+ * Notification is a mechanism crying out for implementation
hiding by means of an abstraction.
+ * This type provides a standard way to do so.
+ *
+ * The implementation pattern is an ACT call a wakeup_listener and
that a scheduler
+ * provide the function so called.
+ * The scheduler should encapsulate its own notification receiver,
however structured,
+ * into a function object of this class, say, by binding a
member function adapter.
+ */
+ class wakeup_listener
+ {
+ public:
///
- typedef Scheduling_Queue< Basic_Scheduled_Item > *
scheduler_pointer ;
+ typedef Basic_Scheduler * scheduler_pointer ;
private:
+ ///
+ typedef Scheduling_Queue< Basic_Scheduled_Item,
wakeup_listener_allocated > queue_type ;
+
/// A pointer to the item to reschedule.
- item_pointer the_item ;
+ size_t permutation_index ;
/// We use the scheduler to reorder an item after we change its
priority.
scheduler_pointer the_scheduler ;
@@ -61,9 +115,12 @@
/// The listener body.
void operator()() ;
+ /// Accessor for the scheduler
+ inline scheduler_pointer scheduler() const { return
the_scheduler ; }
+
/// Ordinary constructor used after item is within a scheduling
queue and its storage location is known.
- Basic_Wakeup_Listener( item_pointer x, scheduler_pointer y )
- : the_item( x ), the_scheduler( y ) {}
+ wakeup_listener( size_t x, scheduler_pointer y )
+ : permutation_index( x ), the_scheduler( y ) {}
} ;
//-------------------------
@@ -113,6 +170,9 @@
struct Basic_Scheduled_Item
{
///
+ Action_Category action_type ;
+
+ ///
Basic_Priority priority_category ;
///
@@ -122,10 +182,7 @@
act the_action ;
///
- Basic_Scheduled_Item( act, unsigned int, Basic_Priority =
Initial ) ;
-
- ///
- boost::optional< Basic_Wakeup_Listener > listener ;
+ Basic_Scheduled_Item( act x, unsigned int n, Action_Category
action_type = Task ) ;
/// Comparison operator for the priority queue
bool operator<( const Basic_Scheduled_Item & ) const ;
@@ -135,7 +192,13 @@
class Basic_Scheduler
{
///
- typedef Scheduling_Queue< Basic_Scheduled_Item >::pointer
item_pointer ;
+ friend wakeup_listener ;
+
+ /// The type of our internal queue.
+ typedef Scheduling_Queue< Basic_Scheduled_Item,
wakeup_listener_allocated > queue_type ;
+
+ ///
+ typedef queue_type::pointer item_pointer ;
/// Activate the next action once.
void activate_one_item() ;
@@ -144,18 +207,18 @@
bool operating ;
/// The live activation queue.
- Scheduling_Queue< Basic_Scheduled_Item > the_queue ;
+ queue_type the_queue ;
+
+ /// Getter method for wakeup_listener
+ inline queue_type & queue() { return the_queue ; }
/// Increasing sequence numbers upon scheduling implements a
kind of LRU activation policy.
unsigned int next_sequence_number ;
+ public:
/// Default constructor is private to enforce singleton
Basic_Scheduler() ;
- ///
- static Basic_Scheduler the_instance ;
-
- public:
/// Add an ordinary task into the scheduling queue.
void add_task( act ) ;
@@ -179,9 +242,6 @@
///
void reset() ;
-
- /// Factory method for singleton pattern
- static Basic_Scheduler & obtain_scheduler() ;
} ;
} // end namespace ACT
Index: Scheduling_Queue.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduling_Queue.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Scheduling_Queue.cpp 13 Jun 2007 19:29:11 -0000 1.1
+++ Scheduling_Queue.cpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -28,22 +28,17 @@
namespace ACT {
//-------------------------
- template< class T >
- Scheduling_Queue< T >::
+ template< class T, class Aux >
+ Scheduling_Queue< T, Aux >::
Scheduling_Queue()
: n_queue_items( 0 )
{}
//-------------------------
- /*
-The problem here is that the free list isn't ordered as it should be.
-Or else the problem here is that something.
-Blargh.
- */
- template< class T >
- typename Scheduling_Queue< T >::pointer
- Scheduling_Queue< T >::
- push( const_reference item )
+ template< class T, class Aux >
+ typename Scheduling_Queue< T, Aux >::pointer
+ Scheduling_Queue< T, Aux >::
+ push( const_reference item, const typename Aux::constructor_parameter
auxiliary )
{
size_t permutation_index ;
// The new queue-index in both cases is n_queue_items, which is
incremented afterwards.
@@ -52,25 +47,26 @@
// In this case the permutation index is the mutual
size of the queue and the permutation.
permutation_index = n_queue_items ;
the_queue.push_back( Scheduled_Item< T >( item,
permutation_index ) ) ; // operator[] would throw here
- permutation.push_back( n_queue_items ) ;
// ditto
+ permutation.push_back( Auxiliary_Item< Aux >(
n_queue_items, permutation_index, auxiliary ) ) ; // ditto
} else {
// Assert n_queue_items < the_queue.size()
// Assert the_queue has at least one deleted element
// In this case the permutation index to use it that of
the first deleted element
permutation_index = the_queue[ n_queue_items
].permutation_index ;
the_queue[ n_queue_items ] = Scheduled_Item< T >( item,
permutation_index ) ; // note that the Scheduled_Item is the same as above
- permutation[ permutation_index ] = n_queue_items ;
+ // The reconstruct() call is ordinarily a no-op, since
a wakeup_listener can be reused.
+ // This call is present to support a possible aspect in
the Auxiliary.
+ permutation[ permutation_index
].the_auxiliary.reconstruct( auxiliary ) ;
}
++ n_queue_items ;
-
size_t n = up_heap( n_queue_items - 1 ) ;
- return pointer( n, this ) ;
+ return pointer( permutation_index, this ) ;
}
//-------------------------
- template< class T >
+ template< class T, class Aux >
void
- Scheduling_Queue< T >::
+ Scheduling_Queue< T, Aux >::
pop()
{
-- n_queue_items ;
@@ -79,21 +75,33 @@
}
//-------------------------
- template< class T >
+ template< class T, class Aux >
void
- Scheduling_Queue< T >::
+ Scheduling_Queue< T, Aux >::
reorder( pointer p )
{
- size_t z = permutation[ p.index ] ;
+ size_t z = permutation[ p.index ].priority_queue_index ;
size_t x = down_heap( z ) ;
if ( z != x ) return ;
(void) up_heap( z ) ;
}
//-------------------------
- template< class T >
+ template< class T, class Aux >
+ void
+ Scheduling_Queue< T, Aux >::
+ reorder( size_t permutation_index )
+ {
+ size_t z( permutation[ permutation_index ].priority_queue_index
) ;
+ size_t x( down_heap( z ) ) ;
+ if ( z != x ) return ;
+ (void) up_heap( z ) ;
+ }
+
+ //-------------------------
+ template< class T, class Aux >
void
- Scheduling_Queue< T >::
+ Scheduling_Queue< T, Aux >::
swap( size_t x, size_t y )
{
// Swap the items
@@ -102,17 +110,17 @@
the_queue[ y ] = tmp ;
// Update the permutation
- permutation[ the_queue[ x ].permutation_index ] = x ;
- permutation[ the_queue[ y ].permutation_index ] = y ;
+ permutation[ the_queue[ x ].permutation_index
].priority_queue_index = x ;
+ permutation[ the_queue[ y ].permutation_index
].priority_queue_index = y ;
}
//-------------------------
/** \par Implementation
* This algorithm treat the_queue as an implicit binary heap.
*/
- template< class T >
+ template< class T, class Aux >
size_t
- Scheduling_Queue< T >::
+ Scheduling_Queue< T, Aux >::
up_heap( size_t item )
{
// Guards:
@@ -135,9 +143,9 @@
/** \par Implementation
* This algorithm treat the_queue as an implicit binary heap.
*/
- template< class T >
+ template< class T, class Aux >
size_t
- Scheduling_Queue< T >::
+ Scheduling_Queue< T, Aux >::
down_heap( size_t item )
{
//
Index: Scheduling_Queue.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduling_Queue.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Scheduling_Queue.hpp 13 Jun 2007 19:29:11 -0000 1.1
+++ Scheduling_Queue.hpp 19 Jun 2007 18:52:25 -0000 1.2
@@ -74,19 +74,42 @@
}
} ;
+
+ //-------------------------
+ /** \class Scheduled_Item
+ * \brief The full data that goes into the scheduling queue.
+ * It includes the underlying item plus extra housekeeping
information.
+ */
+ template< class Aux >
+ struct Auxiliary_Item
+ {
+ /// Index into the priority queue.
+ size_t priority_queue_index ;
+
+ /// The auxiliary item held at fixed location.
+ /// Designed for wakeup_listener.
+ Aux the_auxiliary ;
+
+ /// Ordinary constructor
+ Auxiliary_Item( size_t x, size_t permutation_index, typename
Aux::constructor_parameter z )
+ : priority_queue_index( x ),
+ the_auxiliary( permutation_index, z )
+ {} ;
+ } ;
+
//-------------------------
/** \class Scheduled_Item_Pointer
*/
- template< class T >
+ template< class T, class Aux >
class Scheduled_Item_Pointer
{
- template< class T > friend class Scheduling_Queue ;
+ template< class T, class Aux > friend class Scheduling_Queue ;
size_t index ;
- Scheduling_Queue< T > * the_scheduling_queue ;
+ Scheduling_Queue< T, Aux > * the_scheduling_queue ;
- Scheduled_Item_Pointer( size_t x, Scheduling_Queue< T > * y )
+ Scheduled_Item_Pointer( size_t x, Scheduling_Queue< T, Aux > *
y )
: index( x ), the_scheduling_queue( y ) {}
public:
inline T & operator*() {
@@ -110,8 +133,8 @@
* These extra permutation indices constitute a "free list" of
available permutation slots for the creation of pointers.
*
* \invariant
- * - (bijective permutation) permutation[ the_queue[ x
].permutation_index ] == x
- * - (bijective permutation) the_queue[ permutation[ y ]
].permutation_index == y
+ * - (bijective permutation) permutation[ the_queue[ x
].permutation_index ].priority_queue_index == x
+ * - (bijective permutation) the_queue[ permutation[ y
].priority_queue_index ].permutation_index == y
* - n_queue_items <= the_queue.size
* - permutation.size() == the_queue.size()
*
@@ -121,10 +144,12 @@
* It might be more efficient later to put them in the same
container
* and provide adapters to simulate separate arrays.
*/
- template< class T >
+ template< class T, class Aux >
class Scheduling_Queue
{
- template< class T > friend class Scheduled_Item_Pointer ;
+ // friends
+ template< class T, class Aux > friend class
Scheduled_Item_Pointer ;
+ friend class wakeup_listener ;
/// The main queue for scheduled items.
std::vector< Scheduled_Item< T > > the_queue ;
@@ -134,7 +159,7 @@
size_t n_queue_items ;
/// The heap functions maintain a permutation that provide a
constant pointer into the item queue.
- std::vector< size_t > permutation ;
+ std::vector< Auxiliary_Item< Aux > > permutation ;
/// Swap two elements within the queue.
/// Adjust the permutation accordingly.
@@ -155,12 +180,12 @@
/// Item accessor for implementation of indirection in
Scheduled_Item_Pointer
T & item( size_t x ) {
- return the_queue[ permutation[ x ]
].the_underlying_item ;
+ return the_queue[ permutation[ x ].priority_queue_index
].the_underlying_item ;
}
/// Item accessor for implementation of indirection in
Scheduled_Item_Pointer
T * item_ptr( size_t x ) {
- return & the_queue[ permutation[ x ]
].the_underlying_item ;
+ return & the_queue[ permutation[ x
].priority_queue_index ].the_underlying_item ;
}
public:
@@ -168,7 +193,7 @@
typedef T value_type ;
/// We have a pointer type rather than an iterator type, since
we cannot increment through the queue.
- typedef Scheduled_Item_Pointer< T > pointer ;
+ typedef Scheduled_Item_Pointer< T, Aux > pointer ;
/// A reference to a member of the queue
typedef value_type & reference ;
@@ -183,7 +208,7 @@
///
/// Note that the signature of this function differs from that
of std::priority_queue, which returns void.
/// We require a reference to be able to asynchronously wake up
an action.
- pointer push( const_reference ) ;
+ pointer push( const_reference, const typename
Aux::constructor_parameter auxiliary ) ;
/// Constant access to the top-priority item in the queue.
reference top() { return the_queue[ 0 ].the_underlying_item ; }
@@ -194,11 +219,20 @@
/// Remove the top item from the queue
void pop() ;
+ /// Reorder the position of the indexed item. Use this after
its priority changes.
+ void reorder( size_t ) ;
+
/// Reorder the position of the pointed-to item. Use this
after its priority changes.
void reorder( pointer ) ;
/// Return is true if queue has no items of any kind in it,
waiting or not.
bool empty() { return n_queue_items == 0 ; }
+
+ ///
+ inline Aux & auxiliary( size_t x ) { return permutation[ x
].the_auxiliary ; }
+
+ ///
+ inline Aux * auxiliary_top() { return & permutation[ the_queue[
0 ].permutation_index ].the_auxiliary ; }
} ;
} // end namespace ACT
Index: test_support/Listening_Actions.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Listening_Actions.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test_support/Listening_Actions.cpp 13 Jun 2007 19:29:12 -0000 1.1
+++ test_support/Listening_Actions.cpp 19 Jun 2007 18:52:26 -0000 1.2
@@ -28,6 +28,8 @@
//--------------------------------------------------
// N_to_completion_Monitor
//--------------------------------------------------
+ std::vector< wakeup_listener::scheduler_pointer >
N_to_completion_Monitor::schedulers ;
+
N_to_completion_Monitor::
N_to_completion_Monitor()
: listeners( 0 )
@@ -35,7 +37,7 @@
void
N_to_completion_Monitor::
- add( N_to_completion *, wakeup_listener * w )
+ add_wakeup_item( N_to_completion *, wakeup_listener * w )
{
// Assert this instance is registered in the scheduler and will
eventually run.
// Note: as of this writing, there's no way for an object to
register itself with the scheduler.
@@ -51,6 +53,11 @@
N_to_completion_Monitor::
run()
{
+ if ( listeners.empty() ) {
+ // This monitor is no longer necessary, since there's
nothing to wake up.
+ // Therefore we return complete and let the scheduler
remove this instance.
+ return Completed ;
+ }
while ( ! listeners.empty() ) {
( * listeners.back() )() ;
listeners.pop_back() ;
@@ -99,12 +106,13 @@
N_to_completion::
register_for_wakeup( wakeup_listener * w )
{
+ if ( w == 0 ) return ;
if ( the_monitor.get() == 0 ) {
the_monitor = shared_ptr< monitor_type >( new
monitor_type() ) ;
- Basic_Scheduler::obtain_scheduler().add_service( act(
the_monitor ) ) ;
+ w -> scheduler() -> add_service( act( the_monitor ) ) ;
}
// Assert monitor exists
- the_monitor -> add( this, w ) ;
+ the_monitor -> add_wakeup_item( this, w ) ;
}
//-------------------------
Index: test_support/Listening_Actions.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Listening_Actions.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test_support/Listening_Actions.hpp 13 Jun 2007 19:29:12 -0000 1.1
+++ test_support/Listening_Actions.hpp 19 Jun 2007 18:52:26 -0000 1.2
@@ -24,7 +24,7 @@
#ifndef __Listening_Actions_hpp__
#define __Listening_Actions_hpp__
-#include "ACT/ACT.hpp"
+#include "ACT/Scheduler.hpp"
#include "Action_Tracing.hpp"
#include <boost/optional.hpp>
#include <vector>
@@ -40,6 +40,9 @@
class N_to_completion_Monitor
: public simple_act
{
+ /// A vector of schedulers
+ static std::vector< wakeup_listener::scheduler_pointer >
schedulers ;
+
std::vector< wakeup_listener * > listeners ;
act_state run() ;
@@ -51,7 +54,7 @@
/// Query whether there are any actions registered for wakeup.
inline bool empty() { return listeners.empty() ; }
- void add( N_to_completion *, wakeup_listener * ) ;
+ void add_wakeup_item( N_to_completion *, wakeup_listener * ) ;
} ;
//-------------------------
Index: unit_tests/Test_Scheduler.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/unit_tests/Test_Scheduler.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- unit_tests/Test_Scheduler.cpp 13 Jun 2007 19:29:12 -0000 1.1
+++ unit_tests/Test_Scheduler.cpp 19 Jun 2007 18:52:26 -0000 1.2
@@ -31,8 +31,7 @@
BOOST_AUTO_UNIT_TEST( null )
{
- Basic_Scheduler & b = Basic_Scheduler::obtain_scheduler() ;
- BOOST_REQUIRE( b.empty() ) ;
+ Basic_Scheduler b ;
execution_trace tr ;
b.add_task( act( new no_action( new simple_tracker( tr, "N" ) ) ) ) ;
@@ -44,12 +43,12 @@
std::string expected( "ABC" ) ;
BOOST_CHECK_MESSAGE( tr.result() == expected,
"Found result " << tr.result() << ". Expected result " <<
expected << "." ) ;
+ BOOST_CHECK( b.empty() ) ;
}
BOOST_AUTO_UNIT_TEST( act_n_interleaved )
{
- Basic_Scheduler & b = Basic_Scheduler::obtain_scheduler() ;
- b.reset() ;
+ Basic_Scheduler b ;
BOOST_REQUIRE( b.empty() ) ;
execution_trace tr ;
@@ -61,6 +60,7 @@
std::string expected( "ABCABCBCCC" ) ;
BOOST_CHECK_MESSAGE( tr.result() == expected,
"Found result " << tr.result() << ". Expected result " <<
expected << "." ) ;
+ BOOST_CHECK( b.empty() ) ;
}
//--------------------------------------------------
@@ -68,7 +68,7 @@
BOOST_AUTO_UNIT_TEST( pause_action )
{
- Basic_Scheduler & b = Basic_Scheduler::obtain_scheduler() ;
+ Basic_Scheduler b ;
BOOST_REQUIRE( b.empty() ) ;
Pause_Service x( & b ) ;
Index: unit_tests/Test_Scheduling_Queue.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/unit_tests/Test_Scheduling_Queue.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- unit_tests/Test_Scheduling_Queue.cpp 13 Jun 2007 19:29:12 -0000
1.1
+++ unit_tests/Test_Scheduling_Queue.cpp 19 Jun 2007 18:52:26 -0000
1.2
@@ -29,12 +29,12 @@
// Include this implementation file in order to instantiate template
#include "ACT/Scheduling_Queue.cpp"
-namespace ACT {
- /** A test item to put into a scheduling queue.
+
+/** A test item to put into a scheduling queue.
*/
- class test_item {
+class test_item {
size_t it ;
- public:
+public:
explicit test_item( size_t x )
: it( x ) {}
@@ -42,27 +42,28 @@
inline bool operator==( unsigned int x ) const { return it == x
; }
size_t get() { return it ; }
void set( size_t n ) { it = n ; }
- } ;
+} ;
- // Explicit instantiation
- template Scheduling_Queue< test_item > ;
-}
+// Explicit instantiation
+template ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated > ;
+
+typedef ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated >
queue_type ;
+typedef queue_type::pointer pointer ;
using namespace ACT ;
-typedef Scheduling_Queue< test_item >::pointer pointer ;
//--------------------------------------------------
BOOST_AUTO_UNIT_TEST( simple_queue_exercise )
{
- Scheduling_Queue< test_item > q ;
+ queue_type q ;
test_item a( 1 ) ;
test_item b( 2 ) ;
test_item c( 3 ) ;
- q.push( a ) ;
- q.push( b ) ;
- q.push( c ) ;
+ q.push( a, 0 ) ;
+ q.push( b, 0 ) ;
+ q.push( c, 0 ) ;
pointer x( q.top_ptr() ) ;
test_item it = * x ;
@@ -80,12 +81,12 @@
void
add_then_test_order( permutation_iterator::const_iterator begin,
permutation_iterator::const_iterator end )
{
- Scheduling_Queue< test_item > q ;
+ queue_type q ;
size_t permutation_size = end - begin ;
size_t j ;
for ( j = 0 ; j < permutation_size ; ++ j ) {
- q.push( test_item( * begin ++ ) ) ;
+ q.push( test_item( * begin ++ ), 0 ) ;
}
for ( j = 0 ; j < permutation_size ; ++ j ) {
pointer p( q.top_ptr() ) ;
@@ -114,15 +115,15 @@
//--------------------------------------------------
BOOST_AUTO_UNIT_TEST( another_simple_queue_exercise )
{
- Scheduling_Queue< test_item > q ;
+ queue_type q ;
test_item a( 4 ) ;
test_item b( 5 ) ;
test_item c( 6 ) ;
- q.push( a ) ;
- q.push( b ) ;
- q.push( c ) ;
+ q.push( a, 0 ) ;
+ q.push( b, 0 ) ;
+ q.push( c, 0 ) ;
pointer x( q.top_ptr() ) ;
test_item it = * x ;
@@ -172,7 +173,7 @@
void
add_then_reorder( const iterator begin, iterator middle, iterator end )
{
- Scheduling_Queue< test_item > q ;
+ queue_type q ;
size_t n = middle - begin ;
size_t n2 = end - middle ;
@@ -183,7 +184,7 @@
/* Add elements to the queue from middle to end
*/
for ( j = 0 ; j < n2 ; ++ j ) {
- q.push( test_item( * i ++ ) ) ;
+ q.push( test_item( * i ++ ), 0 ) ;
}
i = begin ;
for ( j = 0 ; j < n ; ++ j ) {
@@ -231,14 +232,14 @@
void
add_then_wakeup( const iterator begin, const iterator middle, const iterator
end )
{
- Scheduling_Queue< test_item > q ;
+ queue_type q ;
const size_t number_of_elements = middle - begin ;
size_t j ;
iterator i( begin ) ;
std::vector< pointer > pp ;
while ( i != middle ) {
- pp.push_back( q.push( test_item( * i ++ ) ) ) ;
+ pp.push_back( q.push( test_item( * i ++ ), 0 ) ) ;
}
BOOST_REQUIRE( i - begin == number_of_elements ) ;
Index: Change_Log.txt
===================================================================
RCS file: Change_Log.txt
diff -N Change_Log.txt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Change_Log.txt 19 Jun 2007 18:52:25 -0000 1.1
@@ -0,0 +1,32 @@
+2007-06-19 Eric Hughes <address@hidden>
+ Added a completion check for the test listening action.
+ All unit tests now fully pass.
+
+2007-06-19 Eric Hughes <address@hidden>
+ Added wakeup_listener_allocated to be the auxiliary object in the
scheduling queue.
+ Changed constructor for old auxiliary items into a call to reconstruct
on the old object.
+ Eliminated identifier Basic_Wakeup_Listener.
+
+2007-06-18 Eric Hughes <address@hidden>
+ Removed singleton construction for Scheduler.
+
+2007-06-17 Eric Hughes <address@hidden>
+ Changed activate_one_item to use a queue pointer rather than a
reference. A reference points to a single location in the priority queue
(which reorders itself), whereas a pointer points to the same entry as it moves
around.
+ Changed index version of reorder to use a permutation_index.
+
+2007-06-17 Eric Hughes <address@hidden>
+ Changed wakeup_listener to store a permutation_index rather than a
pointer. This eliminates an essential duplication, having stored both the
scheduler and its queue addresses both.
+ Expanded permutation vector to incorporate an auxiliary object, used to
hold wakeup_listener.
+ Changed interface to push to take this auxiliary object.
+ Added a reorder( size_t ) call that directly takes the
permutation_index in wakeup_listener.
+
+2007-06-17 Eric Hughes <address@hidden>
+ Found defect with wakeup_listener allocated with queue_item, so
pointers to such aren't stable.
+ Added another class parameter to Scheduling_Queue etc. in preparation
for storing wakeup_listener stably.
+
+2007-06-16 Eric Hughes <address@hidden>
+ Added guard for wakeup to require a listener present.
+ Moved wakeup_listener from ACT.hpp to Scheduler.hpp
+ Added scheduler accessor to wakeup_listener. Will allow removal of
singleton.
+ Added action type to scheduled item. Fixed comparison function.
+ Implemented add_service.
\ No newline at end of file
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash/cygnal/ACT ACT.hpp Cygnal_Instances.cpp S...,
Eric Hughes <=