Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/lib/include/diderot/worker-gate.hxx
ViewVC logotype

View of /branches/vis15/src/lib/include/diderot/worker-gate.hxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4797 - (download) (as text) (annotate)
Mon Oct 24 16:59:27 2016 UTC (2 years, 9 months ago) by jhr
File size: 2521 byte(s)
working on parallel target
/*! \file worker-gate.hxx
 *
 * \author John Reppy
 */

/*
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 */

#ifndef _DIDEROT_WORKER_GATE_HXX_
#define _DIDEROT_WORKER_GATE_HXX_

namespace diderot {

  //! this struct implements a two-step barrier synchronization.  First the controller
  //! thead waits until all of the workers are waiting at the "gate", then the controller_wait()
  //! can signal the workers to go (i.e., open the gate).  It is different from a regular
  //! barrier in that the controller is woken once all threads (workers and controllers)
  //! are blocked and can then run code before releasing the workers.
    struct worker_gate {
	uint32_t	_nWorkers;	//!< number of workers in the pool
	uint32_t	_nWaiting;	//!< number of workers waiting
        pthread_mutex_t _lock;          //!< lock to protect this struct
        pthread_cond_t  _waiting;	//!< used by workers to worker_gate that they are waiting
        pthread_cond_t  _go;		//!< used by workers to worker_gate termination

	worker_gate ()
	    : _nWaiting(0), _nWorkers(0)
	{
	    pthread_mutex_init (&this->_lock, nullptr);
	    pthread_cond_init (&this->_waiting, nullptr);
	    pthread_cond_init (&this->_go, nullptr);
	}

	~worker_gate ()
	{
	    pthread_mutex_destroy (&this->_lock);
	    pthread_cond_destroy (&this->_waiting);
	    pthread_cond_destroy (&this->_go);
	}

      // initialize the gate for the given number of workers
	void init (uint32_t nw) { this->_nWorkers = nw; }

      // workers call this function to wait for "go" signal from controller
	void worker_wait ()
	{
	    pthread_mutex_lock (&this->_lock);
		this->_nWaiting++;
		if (this->_nWaiting == this->_nWorkers) {
		    pthread_cond_signal (&this->_waiting);
		}
		pthread_cond_wait (&this->_go, &this->_lock);
	    pthread_mutex_unlock (&this->_lock);
	}

      // the controller calls this function to wait until all the workers are
      // at the gate
	void controller_wait ()
	{
	    pthread_mutex_lock (&this->_lock);
	    	if (this->_nWaiting < this->_nWorkers) {
		    pthread_cond_wait (&this->_waiting, &this->_lock);
		}
		this->_nWaiting = 0;
	    pthread_mutex_unlock (&this->_lock);
	}

      // wait until all workers are waiting and then signal them to go
	void release_workers ()
	{
	    pthread_cond_broadcast (&this->_go);
	}

    }; // struct worker_gate

} // namespace diderot

#endif // !_DIDEROT_WORKER_GATE_HXX_

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0