1 /**************************************************************************/ 2 /* Copyright 2012 Tim Day */ 3 /* */ 4 /* This file is part of Evolvotron */ 5 /* */ 6 /* Evolvotron is free software: you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation, either version 3 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* Evolvotron is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with Evolvotron. If not, see <http://www.gnu.org/licenses/>. */ 18 /**************************************************************************/ 19 20 /*! \file 21 \brief Interface for class MutatableImageComputerFarm. 22 */ 23 24 #ifndef _mutatable_image_computer_farm_h_ 25 #define _mutatable_image_computer_farm_h_ 26 27 #include "common.h" 28 #include "useful.h" 29 30 #include "mutatable_image_computer.h" 31 #include "mutatable_image_computer_task.h" 32 33 class MutatableImageComputer; 34 class MutatableImageDisplay; 35 36 //! Class encapsulating some compute threads and queues of tasks to be done and tasks completed. 37 /*! Priority queues are implemented using multiset becase we want to be able to iterate over all members. 38 */ 39 class MutatableImageComputerFarm 40 { 41 protected: 42 43 //! Comparison class for STL template. 44 class CompareTaskPriorityLoResFirst : public std::binary_function<boost::shared_ptr<const MutatableImageComputerTask>,boost::shared_ptr<const MutatableImageComputerTask>,bool> 45 { 46 public: 47 //! Compare task priorities. operator()48 bool operator()(const boost::shared_ptr<const MutatableImageComputerTask>& t0,const boost::shared_ptr<const MutatableImageComputerTask>& t1) 49 { 50 return (t0->priority() < t1->priority()); 51 } 52 }; 53 54 //! Comparison class for STL template. 55 class CompareTaskPriorityHiResFirst : public std::binary_function<boost::shared_ptr<const MutatableImageComputerTask>,boost::shared_ptr<const MutatableImageComputerTask>,bool> 56 { 57 public: 58 //! Compare task priorities. operator()59 bool operator()(const boost::shared_ptr<const MutatableImageComputerTask>& t0,const boost::shared_ptr<const MutatableImageComputerTask>& t1) 60 { 61 return (t0->priority() > t1->priority()); 62 } 63 }; 64 65 //! Mutex for locking. This is the ONLY thing the compute threads should ever block on. 66 mutable QMutex _mutex; 67 68 //! Wait condition for threads waiting for a new task. 69 QWaitCondition _wait_condition; 70 71 //! The compute threads 72 boost::ptr_vector<MutatableImageComputer> _computers; 73 74 //! Convenience typedef. 75 typedef std::multiset<boost::shared_ptr<MutatableImageComputerTask>,CompareTaskPriorityLoResFirst> TodoQueue; 76 77 //! Queue of tasks to be performed, lowest resolution first 78 TodoQueue _todo; 79 80 //! Conveniencetypedef. 81 typedef std::multiset<boost::shared_ptr<MutatableImageComputerTask>,CompareTaskPriorityHiResFirst> DoneQueue; 82 83 //! Convenience typedef. 84 /*! const because never needs to do anything other than compare pointers 85 */ 86 typedef std::map<const MutatableImageDisplay*,DoneQueue> DoneQueueByDisplay; 87 88 //! Queue of tasks completed awaiting display. 89 /*! We reverse the compute priority so that highest resolution images get displayed first. 90 Lower resolution ones arriving later should be discarded by the displays. 91 This mainly makes a difference for animation where enlarging multiple low resolution 92 images to screen res takes a lot of time. May help low-bandwidth X11 connections 93 by minimising redraws too. 94 We now also sort by display and do round-robin delivery (ithout this one display can run way ahead of the others) 95 */ 96 DoneQueueByDisplay _done; 97 98 //! Points to the next display queue to be returned (could be .end()) 99 DoneQueueByDisplay::iterator _done_position; 100 101 public: 102 103 //! Constructor. 104 MutatableImageComputerFarm(uint n_threads,int niceness); 105 106 //! Destructor cleans up threads. 107 ~MutatableImageComputerFarm(); 108 109 //! Accessor. num_threads()110 uint num_threads() const 111 { 112 return _computers.size(); 113 } 114 115 //! Move aborted tasks from todo queue to done queue. 116 void fasttrack_aborted(); 117 118 //! Enqueue a task for computing. 119 void push_todo(const boost::shared_ptr<MutatableImageComputerTask>&); 120 121 //! Remove a task from the head of the todo queue (returns null if none). 122 const boost::shared_ptr<MutatableImageComputerTask> pop_todo(MutatableImageComputer& requester); 123 124 //! Enqueue a task for display. 125 void push_done(const boost::shared_ptr<MutatableImageComputerTask>&); 126 127 //! Remove a task from the head of the display queue (returns null if none). 128 const boost::shared_ptr<MutatableImageComputerTask> pop_done(); 129 130 //! Flags all tasks in all queues as aborted, and signals the compute threads to abort their current task. 131 void abort_all(); 132 133 //! Flags all tasks for a particular display as aborted (including compute threads) 134 void abort_for(const MutatableImageDisplay* disp); 135 136 //! Number of tasks in queues 137 uint tasks() const; 138 }; 139 140 #endif 141