public inbox for sid@sourceware.org
 help / color / mirror / Atom feed
From: Dave Brolley <brolley@redhat.com>
To: sid@sources.redhat.com
Subject: [patch][commit] Single Mutex for sidutil::blocking_component
Date: Mon, 19 Feb 2007 16:52:00 -0000	[thread overview]
Message-ID: <45D9D5D6.9000605@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 647 bytes --]

Hi,

I've committed the attached patch which simplifies the implementation of 
sidutil::blocking_component. The use of two mutex/condition variable 
pairs for synchronizing the parent and child threads was unnecessary 
and, if you look at the existing code, you will see that they were 
always locked/unlocked/blocked in unison. The implementation now uses a 
single mutex/condition variable pair.

The patch also adds checking that a return from pthread_cond_wait was 
not spontaneous and makes the control_status member volatile for this 
purpose.

Tested extensively using the MeP port which is the only committed port 
using this class.

Dave

[-- Attachment #2: sid.blocking_component.ChangeLOg --]
[-- Type: text/plain, Size: 368 bytes --]

2007-02-19  Dave Brolley  <brolley@redhat.com>

	* sidblockingutil.h (sidutil::blocking_component): Remove
	child_resume_mutex, child_stopped_mutex, chiuld_resume_condition and
	child_stopped_condition. Use a single mutex/condition pair:
	child_sync_mutex and child_sync_condition. Handle spontaneous returns
	from pthread_cond_wait.
	(control_status): Now volatile.


[-- Attachment #3: sid.blocking_component.patch.txt --]
[-- Type: text/plain, Size: 5020 bytes --]

Index: sid/include/sidblockingutil.h
===================================================================
RCS file: /cvs/src/src/sid/include/sidblockingutil.h,v
retrieving revision 1.3
diff -c -p -r1.3 sidblockingutil.h
*** sid/include/sidblockingutil.h	5 Feb 2007 20:28:42 -0000	1.3
--- sid/include/sidblockingutil.h	19 Feb 2007 16:26:33 -0000
*************** namespace sidutil
*** 49,57 ****
        {
  	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:
--- 49,56 ----
        {
  	log (10, "%s: child_init\n", name.c_str ());
  	assert (child_created);
! 	// Lock the syncronization mutex
! 	pthread_mutex_lock (& child_sync_mutex);
        }
  
    protected:
*************** namespace sidutil
*** 59,73 ****
        {
  	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;
        }
  
--- 58,69 ----
        {
  	log (10, "%s: parent_init\n", name.c_str ());
  
! 	// Create a mutex for synchronizing the parent and child threads
! 	pthread_mutex_init (& child_sync_mutex, NULL);
! 	pthread_cond_init (& child_sync_condition, NULL);
! 
! 	// Lock the mutex
! 	pthread_mutex_lock (& child_sync_mutex);
  	control_status = ctl_parent;
        }
  
*************** namespace sidutil
*** 121,139 ****
  	// Signal the child to resume
  	assert (control_status != ctl_child_start);
  	control_status = ctl_child_start;
! 	pthread_cond_signal (& child_resume_condition);
! 
! 	// Unlock the mutex so that the child can gain control
! 	pthread_mutex_unlock (& child_resume_mutex);
  
  	// Wait for the return signal from the child
! 	pthread_cond_wait (& child_stopped_condition, & child_stopped_mutex);
! 
! 	// Reacquire the mutex so that the child can gain control
! 	pthread_mutex_lock (& child_resume_mutex);
  
- 	// Check the value of control_status
- 	assert (control_status != ctl_child_start);
  	return control_status;
        }
  
--- 117,132 ----
  	// Signal the child to resume
  	assert (control_status != ctl_child_start);
  	control_status = ctl_child_start;
! 	log (11, "%s: parent signalling the child thread\n", name.c_str ());
! 	pthread_cond_signal (& child_sync_condition);
  
  	// Wait for the return signal from the child
! 	do {
! 	  log (11, "%s: parent waiting for child thread\n", name.c_str ());
! 	  pthread_cond_wait (& child_sync_condition, & child_sync_mutex);
! 	} while (control_status == ctl_child_start); 
! 	log (11, "%s: parent regains control\n", name.c_str ());
  
  	return control_status;
        }
  
*************** namespace sidutil
*** 168,185 ****
  
  	// Signal the parent that we're stopped
  	log (11, "%s: child signalling the parent thread\n", name.c_str ());
! 	pthread_cond_signal (& child_stopped_condition);
! 
! 	// Unlock the mutex so that the parent can gain control
! 	pthread_mutex_unlock (& child_stopped_mutex);
  
  	// Wait for a signal to resume
! 	log (11, "%s: child waiting for parent thread\n", name.c_str ());
! 	pthread_cond_wait (& child_resume_condition, & child_resume_mutex);
! 
! 	// Reacquire the stopped mutex
! 	pthread_mutex_lock (& child_stopped_mutex);
! 	assert (control_status == ctl_child_start);
        }
  
      void set_blockable ()
--- 161,174 ----
  
  	// Signal the parent that we're stopped
  	log (11, "%s: child signalling the parent thread\n", name.c_str ());
! 	pthread_cond_signal (& child_sync_condition);
  
  	// Wait for a signal to resume
! 	do {
! 	  log (11, "%s: child waiting for parent thread\n", name.c_str ());
! 	  pthread_cond_wait (& child_sync_condition, & child_sync_mutex);
! 	} while (control_status != ctl_child_start);
! 	log (11, "%s: child regains control\n", name.c_str ());
        }
  
      void set_blockable ()
*************** namespace sidutil
*** 198,208 ****
      bool child_created;
      pthread_t child_thread;
      void *(*child_thread_function)(void *);
!     pthread_mutex_t child_resume_mutex;
!     pthread_cond_t child_resume_condition;
!     pthread_mutex_t child_stopped_mutex;
!     pthread_cond_t child_stopped_condition;
!     enum
        {
  	ctl_parent, ctl_child_start, ctl_child_blocked, ctl_child_complete
        } control_status;
--- 187,195 ----
      bool child_created;
      pthread_t child_thread;
      void *(*child_thread_function)(void *);
!     pthread_mutex_t child_sync_mutex;
!     pthread_cond_t child_sync_condition;
!     volatile enum
        {
  	ctl_parent, ctl_child_start, ctl_child_blocked, ctl_child_complete
        } control_status;

                 reply	other threads:[~2007-02-19 16:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45D9D5D6.9000605@redhat.com \
    --to=brolley@redhat.com \
    --cc=sid@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).