File: mutatable_image_computer.h

package info (click to toggle)
evolvotron 0.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,420 kB
  • ctags: 1,367
  • sloc: cpp: 10,462; python: 162; sh: 147; makefile: 9
file content (200 lines) | stat: -rw-r--r-- 6,016 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/**************************************************************************/
/*  Copyright 2012 Tim Day                                                */
/*                                                                        */
/*  This file is part of Evolvotron                                       */
/*                                                                        */
/*  Evolvotron is free software: you can redistribute it and/or modify    */
/*  it under the terms of the GNU General Public License as published by  */
/*  the Free Software Foundation, either version 3 of the License, or     */
/*  (at your option) any later version.                                   */
/*                                                                        */
/*  Evolvotron is distributed in the hope that it will be useful,         */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
/*  GNU General Public License for more details.                          */
/*                                                                        */
/*  You should have received a copy of the GNU General Public License     */
/*  along with Evolvotron.  If not, see <http://www.gnu.org/licenses/>.   */
/**************************************************************************/

/*! \file 
  \brief Interface for class MutatableImageComputer.
*/

#ifndef _mutatable_image_computer_h_
#define _mutatable_image_computer_h_

#include "mutatable_image.h"
#include "random.h"

class MutatableImageDisplay;
class MutatableImageComputerFarm;
class MutatableImageComputerTask;

//! Class to handle computing of MutatableImages in a separate thread.
/*! A compute task starts up and fetches work from it's parent farm.
  The parent farm thread can communicate when necessary using the public methods of the class.
 */
class MutatableImageComputer : public QThread
#ifndef NDEBUG
, public InstanceCounted
#endif
{
 protected:
  //! Pointer to compute farm of which this thread is part.
  MutatableImageComputerFarm*const _farm;

  //! Priority offset applied to compute threads.
  const int _niceness;

  //! The current task.  Can't be a const MutatableImageComputerTask because the task holds the calculated result.
  boost::shared_ptr<MutatableImageComputerTask> _task;

  //! Randomness for sampling jitter
  Random01 _r01;

  //! Class encapsulating mutex-protected flags used for communicating between farm and worker.
  /*! The Mutex is of dubious value (could certainly be eliminated for reads).
   */
  class Communications
    {
    protected:
      //! Mutex protecting access to members (mutable to enable const-ness of accessors).
      mutable QMutex _mutex;
      
      //! Flag to indicate we should put our current task back on the todo queue and take another one.
      /*! volatile because used for inter-thread communication.
       */
      volatile bool _defer;
      
      //! Flag to indicate we should abort the current compute.
      /*! volatile because used for inter-thread communication.
       */
      volatile bool _abort;
      
      //! Flag to indicate the thread should shut down and exit.
      /*! volatile because used for inter-thread communication.
       */
      volatile bool _kill;

    public:
      //! Constructor.
      /*! Mutex is recursive to allow nesting.
       */
      Communications()
	:_mutex()
	,_defer(false)
	,_abort(false)
	,_kill(false)
	{}

      //! Mutex-protected accessor.
      void defer(bool v)
	{
	  QMutexLocker lock(&_mutex);
	  _defer=v;
	}
      //! Mutex-protected accessor.
      bool defer() const
	{
	  QMutexLocker lock(&_mutex);
	  const bool ret=_defer;
	  return ret;
	}
      //! Mutex-protected accessor.
      void abort(bool v)
	{
	  QMutexLocker lock(&_mutex);
	  _abort=v;
	}
      //! Mutex-protected accessor.
      bool abort() const
	{
	  QMutexLocker lock(&_mutex);
	  const bool ret=_abort;
	  return ret;
	}
      //! Mutex-protected accessor.
      void kill(bool v)
	{
	  QMutexLocker lock(&_mutex);
	  _kill=v;
	}
      //! Mutex-protected accessor.
      bool kill() const
	{
	  QMutexLocker lock(&_mutex);
	  const bool ret=_kill;
	  return ret;
	}
      //! Check union of all flags with only one mutex lock.
      bool kill_or_abort_or_defer() const
	{
	  QMutexLocker lock(&_mutex);
	  const bool ret=(_kill || _abort || _defer);
	  return ret;
	}
    };

  //! Instance of communications flags.
  Communications _communications;
  
  //! The actual compute code, launched by invoking start() in the constructor.
  virtual void run();

  //! Accessor.
  Communications& communications()
    {
      return _communications;
    }
  //! Accessor.
  const Communications& communications() const
    {
      return _communications;
    }
  
  //! Accessor.
  const boost::shared_ptr<MutatableImageComputerTask>& task() const
    {
      return _task;
    }

  //! Accessor.
  MutatableImageComputerFarm* farm() const
    {
      return _farm;
    }

 public:

  //! Constructor
  MutatableImageComputer(MutatableImageComputerFarm* frm,int niceness);

  //! Destructor
  ~MutatableImageComputer();

  //! Defer the current task if it's priority is less important than specified.  Returns true if deferrment occurred.
  bool defer_if_less_important_than(uint pri);

  //! This method called by an external threads to shut down the current task
  void abort();

  //! This method called by an external threads to shut down the current task if it's for a particular display
  void abort_for(const MutatableImageDisplay* disp);

  //! This method called by external thread to kill the thread.
  void kill();

  //! Return kill state.
  /*! Needs external visibility for deciding what to do when woken from wait for task.
   */
  bool killed() const;

  //! Indicate whether computation us taking place (only intended for counting outstanding threads).
  bool active() const
    {
      return _task;
    }
};

#endif