This is the mail archive of the sid@sourceware.org mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch][commit] Blockable Component Enhancement


Hi,

I've committed this patch which allows the blockable? attribute of a blocking component to be changed safely by other components using the SID component API. The actual setting of the internal state is delayed until the parent thread has (re)gained control.

Dave
2005-08-02  Dave Brolley  <brolley@redhat.com>

	* sidbusutil.h (bus_arbitrator): Remove passthrough_pin.
	(check_passthrough): Now takes 'upstream' argument. Correct all calls.
	Don't check passthrough_pin here.
	(access_latency): New virtual method of bus_arbitrator.
	* sidblockingutil.h (blocking_component): Initialize still_blockable
	and control_status. Add blockable? using add_attribute_notify.
	(wait_for_child_thread): Assert that control_status != ctl_child_start.
	Return control_status.
	(child_completed): Set blockable to still_blockable.
	(set_blockable): New method of blocking_component.
	(still_blockable): New member of blocking_component.

Index: sid/include/sidblockingutil.h
===================================================================
RCS file: /cvs/src/src/sid/include/sidblockingutil.h,v
retrieving revision 1.1
diff -c -p -r1.1 sidblockingutil.h
*** sid/include/sidblockingutil.h	10 May 2005 15:48:22 -0000	1.1
--- sid/include/sidblockingutil.h	2 Aug 2005 18:19:15 -0000
***************
*** 1,6 ****
  // sidblockingutil.h - Elements used for blockable components.  -*- C++ -*-
  
! // Copyright (C) 2004 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
--- 1,6 ----
  // sidblockingutil.h - Elements used for blockable components.  -*- C++ -*-
  
! // Copyright (C) 2004, 2005 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
*************** namespace sidutil
*** 28,44 ****
        self (child_self),
        child_created (false),
        child_thread_function (f),
!       blockable (false)
        {
  	add_attribute ("name", &name);
! 	add_attribute ("blockable?", & blockable, "setting");
        }
      ~blocking_component () throw()
        {
        }
  
    protected:
!     // Called by the parent thread to ensure that a child thread exists
      //
      void need_child_thread ()
        {
--- 28,77 ----
        self (child_self),
        child_created (false),
        child_thread_function (f),
!       blockable (false),
!       still_blockable (false),
!       control_status (ctl_parent)
        {
  	add_attribute ("name", &name);
! 	add_attribute_notify ("blockable?", & still_blockable, this,
! 			      & blocking_component::set_blockable,
! 			      "setting");
        }
      ~blocking_component () throw()
        {
        }
  
+     // -------------------------------------------------------------------
+     // Child thread management
+     //
+   public:
+     void child_init ()
+       {
+ 	log (10, "%s: child_init\n", name.c_str ());
+ 	assert (child_created);
+ 	// Lock both mutexes
+ 	pthread_mutex_lock (& child_resume_mutex);
+ 	pthread_mutex_lock (& child_stopped_mutex);
+       }
+ 
    protected:
!     void parent_init ()
!       {
! 	log (10, "%s: parent_init\n", name.c_str ());
! 
! 	// Create mutexes for synchronizing the parent and child threads
! 	pthread_mutex_init (& child_resume_mutex, NULL);
! 	pthread_cond_init (& child_resume_condition, NULL);
! 	pthread_mutex_init (& child_stopped_mutex, NULL);
! 	pthread_cond_init (& child_stopped_condition, NULL);
! 
! 	// Lock both mutexes
! 	pthread_mutex_lock (& child_resume_mutex);
! 	pthread_mutex_lock (& child_stopped_mutex);
! 	control_status = ctl_parent;
!       }
! 
!     // Called to ensure that a child thread exists
      //
      void need_child_thread ()
        {
*************** namespace sidutil
*** 81,113 ****
  	return wait_for_child_thread ();
        }
  
-   private:
-     // Called once by the parent thread just before the child thread is
-     // created.
-     void parent_init ()
-       {
- 	log (10, "%s: parent_init\n", name.c_str ());
- 
- 	// Create mutexes for synchronizing the parent and child threads
- 	pthread_mutex_init (& child_resume_mutex, NULL);
- 	pthread_cond_init (& child_resume_condition, NULL);
- 	pthread_mutex_init (& child_stopped_mutex, NULL);
- 	pthread_cond_init (& child_stopped_condition, NULL);
- 
- 	// Lock both mutexes
- 	pthread_mutex_lock (& child_resume_mutex);
- 	pthread_mutex_lock (& child_stopped_mutex);
- 	control_status = ctl_parent;
-       }
- 
-     // Called by the parent to wait for the child thread to give up control
-     //
      int wait_for_child_thread ()
        {
  	log (10, "%s: wait_for_child_thread\n", name.c_str ());
  
  	// Signal the child to resume
! 	assert (control_status == ctl_parent);
  	control_status = ctl_child_start;
  	pthread_cond_signal (& child_resume_condition);
  
--- 114,125 ----
  	return wait_for_child_thread ();
        }
  
      int wait_for_child_thread ()
        {
  	log (10, "%s: wait_for_child_thread\n", name.c_str ());
  
  	// Signal the child to resume
! 	assert (control_status != ctl_child_start);
  	control_status = ctl_child_start;
  	pthread_cond_signal (& child_resume_condition);
  
*************** namespace sidutil
*** 121,144 ****
  	pthread_mutex_lock (& child_resume_mutex);
  
  	// Check the value of control_status
! 	int s = control_status;
! 	assert (s != ctl_child_start);
! 	control_status = ctl_parent;
! 	return s;
        }
  
    public:
-     // Called by the child thread once when it is created.
-     //
-     void child_init ()
-       {
- 	log (10, "%s: child_init\n", name.c_str ());
- 	assert (child_created);
- 	// Lock both mutexes
- 	pthread_mutex_lock (& child_resume_mutex);
- 	pthread_mutex_lock (& child_stopped_mutex);
-       }
- 
      // Called by the child thread to signal normal completion of the child task
      //
      void child_completed ()
--- 133,143 ----
  	pthread_mutex_lock (& child_resume_mutex);
  
  	// Check the value of control_status
! 	assert (control_status != ctl_child_start);
! 	return control_status;
        }
  
    public:
      // Called by the child thread to signal normal completion of the child task
      //
      void child_completed ()
*************** namespace sidutil
*** 146,151 ****
--- 145,151 ----
  	log (10, "%s: child_completed\n", name.c_str ());
  	log (11, "%s: child sending completion signal\n", name.c_str ());
  	control_status = ctl_child_complete;
+ 	blockable = still_blockable;
  	child_wait_for_resume ();
        }
  	    
*************** namespace sidutil
*** 159,165 ****
  	child_wait_for_resume ();
        }
  
!   private:
      // Called by the child thread to wait for a signal from the parent thread
      // to resume
      void child_wait_for_resume ()
--- 159,165 ----
  	child_wait_for_resume ();
        }
  
!   protected:	    
      // Called by the child thread to wait for a signal from the parent thread
      // to resume
      void child_wait_for_resume ()
*************** namespace sidutil
*** 182,190 ****
--- 182,199 ----
  	assert (control_status == ctl_child_start);
        }
  
+     void set_blockable ()
+       {
+ 	// Never change the status of 'blockable' while the child thread is
+ 	// active.
+ 	if (control_status == ctl_parent || control_status == ctl_child_complete)
+ 	  blockable = still_blockable;
+       }
+ 
    protected:
      string name;
      bool blockable;
+     bool still_blockable;
      void *self;
      bool child_created;
      pthread_t child_thread;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]