Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * aqt_vision_threads.cpp - FireVision Base Vision Camera Data 00004 * 00005 * Created: Mon Sep 24 16:16:25 2007 00006 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 #include <apps/base/aqt_vision_threads.h> 00024 00025 #include <core/threading/barrier.h> 00026 #include <utils/time/clock.h> 00027 #include <aspect/vision.h> 00028 00029 #include <algorithm> 00030 00031 using namespace fawkes; 00032 00033 /** @class FvAqtVisionThreads <apps/base/aqt_vision_threads.h> 00034 * Aquisition-dependant threads. 00035 * This class is used for managing the vision threads that depend on a 00036 * given aquisition thread. Used internally in base vision. 00037 * @author Tim Niemueller 00038 */ 00039 00040 00041 /** Constructor. 00042 * @param clock Clock for timeout handling, system time is used only. 00043 */ 00044 FvAqtVisionThreads::FvAqtVisionThreads(Clock *clock) 00045 00046 { 00047 this->clock = clock; 00048 00049 _empty_time = new Time(); 00050 clock->get_systime(_empty_time); 00051 00052 running_threads_cyclic = new ThreadList(); 00053 running_threads_cont = new ThreadList(); 00054 waiting_threads = new ThreadList(); 00055 00056 cyclic_barrier = new Barrier(1); 00057 } 00058 00059 00060 /** Destructor. */ 00061 FvAqtVisionThreads::~FvAqtVisionThreads() 00062 { 00063 delete _empty_time; 00064 delete cyclic_barrier; 00065 00066 delete running_threads_cyclic; 00067 delete running_threads_cont; 00068 delete waiting_threads; 00069 00070 } 00071 00072 00073 /** Add a thread in waiting state. 00074 * The thread is marked as dependant but it is otherwise ignored. 00075 * @param thread thread to add 00076 * for access to the YUV422_PLANAR image. 00077 */ 00078 void 00079 FvAqtVisionThreads::add_waiting_thread(Thread *thread) 00080 { 00081 waiting_threads->push_back_locked(thread); 00082 } 00083 00084 00085 /** Mark the thread as running. 00086 * @param thread thread to mark as running 00087 */ 00088 void 00089 FvAqtVisionThreads::set_thread_running(Thread *thread) 00090 { 00091 VisionAspect *vision_thread = dynamic_cast<VisionAspect *>(thread); 00092 if ( find(waiting_threads->begin(), waiting_threads->end(), thread) != waiting_threads->end()) { 00093 if ( vision_thread->vision_thread_mode() == VisionAspect::CYCLIC ) { 00094 running_threads_cyclic->push_back_locked(thread); 00095 delete cyclic_barrier; 00096 cyclic_barrier = new Barrier( running_threads_cyclic->size() + 1 ); 00097 } else { 00098 running_threads_cont->push_back_locked(thread); 00099 } 00100 waiting_threads->remove_locked(thread); 00101 } 00102 } 00103 00104 00105 /** Remove a thread. 00106 * The thread is removed from all internal structures. 00107 * @param thread thread to remove 00108 */ 00109 void 00110 FvAqtVisionThreads::remove_thread(Thread *thread) 00111 { 00112 waiting_threads->remove_locked(thread); 00113 if ( find(running_threads_cyclic->begin(), running_threads_cyclic->end(), thread) != 00114 running_threads_cyclic->end()) { 00115 00116 running_threads_cyclic->remove_locked(thread); 00117 00118 delete cyclic_barrier; 00119 cyclic_barrier = new Barrier( running_threads_cyclic->size() + 1 ); 00120 } 00121 running_threads_cont->remove_locked(thread); 00122 if ( empty() ) { 00123 clock->get_systime(_empty_time); 00124 } 00125 } 00126 00127 00128 /** Remove waiting thread. 00129 * @param thread thread to remove from waiting structures. 00130 */ 00131 void 00132 FvAqtVisionThreads::remove_waiting_thread(Thread *thread) 00133 { 00134 waiting_threads->remove_locked(thread); 00135 if ( empty() ) { 00136 clock->get_systime(_empty_time); 00137 } 00138 } 00139 00140 00141 /** Check if there is at least one cyclic thread. 00142 * @return true if there is at least one cyclic thread, false otherwise. 00143 */ 00144 bool 00145 FvAqtVisionThreads::has_cyclic_thread() 00146 { 00147 return ( ! running_threads_cyclic->empty() ); 00148 } 00149 00150 00151 /** Check if the given waiting thread is registered. 00152 * @param t thread to check for 00153 * @return true if the given thread is marked as waiting, false otherwise 00154 */ 00155 bool 00156 FvAqtVisionThreads::has_waiting_thread(Thread *t) 00157 { 00158 return (find(waiting_threads->begin(), waiting_threads->end(), t) != waiting_threads->end()); 00159 } 00160 00161 00162 /** Check if there is no thread at all. 00163 * @return true if there is no thread in any of the internal running or waiting 00164 * lists, false otherwise 00165 */ 00166 bool 00167 FvAqtVisionThreads::empty() 00168 { 00169 return ( waiting_threads->empty() && 00170 running_threads_cyclic->empty() && 00171 running_threads_cont->empty() ); 00172 } 00173 00174 00175 /** Get the empty time. 00176 * @return the time in seconds since the last thread has been removed. 00177 */ 00178 float 00179 FvAqtVisionThreads::empty_time() 00180 { 00181 return clock->elapsed(_empty_time); 00182 } 00183 00184 00185 /** Wakeup and wait for all cyclic threads. */ 00186 void 00187 FvAqtVisionThreads::wakeup_and_wait_cyclic_threads() 00188 { 00189 if ( has_cyclic_thread() ) { 00190 running_threads_cyclic->wakeup(cyclic_barrier); 00191 cyclic_barrier->wait(); 00192 } 00193 } 00194 00195 00196 /** Set prepfin hold fo cyclic threads. 00197 * Sets prepfin hold for cyclice threads and rolls back if it cannot 00198 * be set for any of the threads. 00199 * @param hold prepfin hold value 00200 * @exception Exception thrown if setting fails 00201 * @see Thread::set_prepfin_hold() 00202 * @see ThreadList::set_prepfin_hold() 00203 */ 00204 void 00205 FvAqtVisionThreads::set_prepfin_hold(bool hold) 00206 { 00207 try { 00208 running_threads_cyclic->set_prepfin_hold(hold); 00209 } catch (Exception &e) { 00210 running_threads_cyclic->set_prepfin_hold(false); 00211 throw; 00212 } 00213 }