GNU Radio 3.3.0 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2007,2008 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License along 00018 * with this program; if not, write to the Free Software Foundation, Inc., 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00020 */ 00021 00022 #ifndef INCLUDED_GC_JOB_MANAGER_H 00023 #define INCLUDED_GC_JOB_MANAGER_H 00024 00025 #include <boost/utility.hpp> 00026 #include <boost/shared_ptr.hpp> 00027 #include <vector> 00028 #include <string> 00029 #include <stdexcept> 00030 #include <libspe2.h> 00031 #include "gc_job_desc.h" 00032 00033 class gc_job_manager; 00034 typedef boost::shared_ptr<gc_job_manager> gc_job_manager_sptr; 00035 typedef boost::shared_ptr<spe_program_handle_t> spe_program_handle_sptr; 00036 typedef boost::shared_ptr<gc_job_desc> gc_job_desc_sptr; 00037 00038 /*! 00039 * \brief Return a boost::shared_ptr to an spe_program_handle_t 00040 * 00041 * \param filename is the name of the SPE ELF executable to open. 00042 * 00043 * Calls spe_image_open to open the file. If successful returns a 00044 * boost::shared_ptr that will call spe_image_close when it's time to 00045 * free the object. 00046 * 00047 * Returns the equivalent of the NULL pointer if the file cannot be 00048 * opened, or if it's not an SPE ELF object file. 00049 * 00050 * \sa gc_program_handle_from_address 00051 */ 00052 spe_program_handle_sptr 00053 gc_program_handle_from_filename(const std::string &filename); 00054 00055 /*! 00056 * \brief Return a boost::shared_ptr to an spe_program_handle_t 00057 * 00058 * \param handle is a non-zero pointer to an embedded SPE image. 00059 * 00060 * If successful returns a boost::shared_ptr that does nothing when 00061 * it's time to free the object. 00062 * 00063 * \sa gc_program_handle_from_filename 00064 */ 00065 spe_program_handle_sptr 00066 gc_program_handle_from_address(spe_program_handle_t *handle); 00067 00068 /*! 00069 * \brief map gc_job_status_t into a string 00070 */ 00071 const std::string 00072 gc_job_status_string(gc_job_status_t status); 00073 00074 /* 00075 * \brief Options that configure the job_manager. 00076 * The default values are reasonable. 00077 */ 00078 struct gc_jm_options { 00079 unsigned int max_jobs; // max # of job descriptors in system 00080 unsigned int max_client_threads; // max # of client threads of job manager 00081 unsigned int nspes; // how many SPEs shall we use? 0 -> all of them 00082 bool gang_schedule; // shall we gang schedule? 00083 bool use_affinity; // shall we try for affinity (FIXME not implmented) 00084 bool enable_logging; // shall we log SPE events? 00085 uint32_t log2_nlog_entries; // log2 of number of log entries (default is 12 == 4k) 00086 spe_program_handle_sptr program_handle; // program to load into SPEs 00087 00088 gc_jm_options() : 00089 max_jobs(0), max_client_threads(0), nspes(0), 00090 gang_schedule(false), use_affinity(false), 00091 enable_logging(false), log2_nlog_entries(12) 00092 { 00093 } 00094 00095 gc_jm_options(spe_program_handle_sptr program_handle_, 00096 unsigned int nspes_ = 0) : 00097 max_jobs(0), max_client_threads(0), nspes(nspes_), 00098 gang_schedule(false), use_affinity(false), 00099 enable_logging(false), log2_nlog_entries(12), 00100 program_handle(program_handle_) 00101 { 00102 } 00103 }; 00104 00105 enum gc_wait_mode { 00106 GC_WAIT_ANY, 00107 GC_WAIT_ALL, 00108 }; 00109 00110 /* 00111 * exception classes 00112 */ 00113 class gc_exception : public std::runtime_error 00114 { 00115 public: 00116 gc_exception(const std::string &msg); 00117 }; 00118 00119 class gc_unknown_proc : public gc_exception 00120 { 00121 public: 00122 gc_unknown_proc(const std::string &msg); 00123 }; 00124 00125 class gc_bad_alloc : public gc_exception 00126 { 00127 public: 00128 gc_bad_alloc(const std::string &msg); 00129 }; 00130 00131 class gc_bad_align : public gc_exception 00132 { 00133 public: 00134 gc_bad_align(const std::string &msg); 00135 }; 00136 00137 class gc_bad_submit : public gc_exception 00138 { 00139 public: 00140 gc_bad_submit(const std::string &name, gc_job_status_t status); 00141 }; 00142 00143 /* 00144 * \brief Create an instance of the job manager 00145 */ 00146 gc_job_manager_sptr 00147 gc_make_job_manager(const gc_jm_options *options = 0); 00148 00149 00150 /*! 00151 * \brief Abstract class that manages SPE jobs. 00152 * \ingroup gcell 00153 * 00154 * There is typically a single instance derived from this class. 00155 * It is safe to call its methods from any thread. 00156 */ 00157 class gc_job_manager : boost::noncopyable 00158 { 00159 public: 00160 gc_job_manager(const gc_jm_options *options = 0); 00161 00162 virtual ~gc_job_manager(); 00163 00164 /*! 00165 * Stop accepting new jobs. Wait for existing jobs to complete. 00166 * Return all managed SPE's to the system. 00167 */ 00168 virtual bool shutdown() = 0; 00169 00170 /*! 00171 * \brief Return number of SPE's currently allocated to job manager. 00172 */ 00173 virtual int nspes() const = 0; 00174 00175 /*! 00176 * \brief Return a pointer to a properly aligned job descriptor, 00177 * or throws gc_bad_alloc if there are none available. 00178 */ 00179 virtual gc_job_desc *alloc_job_desc() = 0; 00180 00181 /* 00182 *! Free a job descriptor previously allocated with alloc_job_desc() 00183 * 00184 * \param[in] jd pointer to job descriptor to free. 00185 */ 00186 virtual void free_job_desc(gc_job_desc *jd) = 0; 00187 00188 /*! 00189 * \brief Submit a job for asynchronous processing on an SPE. 00190 * 00191 * \param[in] jd pointer to job description 00192 * 00193 * The caller must not read or write the job description 00194 * or any of the memory associated with any indirect arguments 00195 * until after calling wait_job. 00196 * 00197 * \returns true iff the job was successfully enqueued. 00198 * If submit_job returns false, check jd->status for additional info. 00199 */ 00200 virtual bool submit_job(gc_job_desc *jd) = 0; 00201 00202 /*! 00203 * \brief Wait for job to complete. 00204 * 00205 * A thread may only wait for jobs which it submitted. 00206 * 00207 * \returns true if sucessful, else false. 00208 */ 00209 virtual bool 00210 wait_job(gc_job_desc *jd) = 0; 00211 00212 /*! 00213 * \brief wait for 1 or more jobs to complete. 00214 * 00215 * \param[in] njobs is the length of arrays \p jd and \p done. 00216 * \param[in] jd are the jobs that are to be waited for. 00217 * \param[out] done indicates whether the corresponding job is complete. 00218 * \param[in] mode indicates whether to wait for ALL or ANY of the jobs 00219 * in \p jd to complete. 00220 * 00221 * A thread may only wait for jobs which it submitted. 00222 * 00223 * \returns number of jobs completed, or -1 if error. 00224 * The caller must examine the status field of each job to confirm 00225 * successful completion of the job. 00226 */ 00227 virtual int 00228 wait_jobs(unsigned int njobs, 00229 gc_job_desc *jd[], bool done[], gc_wait_mode mode) = 0; 00230 00231 /*! 00232 * Return the maximum number of bytes of EA arguments that may be 00233 * copied to or from the SPE in a single job. The limit applies 00234 * independently to the "get" and "put" args. 00235 * \sa gc_job_desc_t, gc_job_ea_args_t 00236 */ 00237 virtual int ea_args_maxsize() = 0; 00238 00239 /*! 00240 * Return gc_proc_id_t associated with spu procedure \p proc_name if one 00241 * exists, otherwise throws gc_unknown_proc. 00242 */ 00243 virtual gc_proc_id_t lookup_proc(const std::string &proc_name) = 0; 00244 00245 /*! 00246 * Return a vector of all known spu procedure names. 00247 */ 00248 virtual std::vector<std::string> proc_names() = 0; 00249 00250 virtual void set_debug(int debug); 00251 virtual int debug(); 00252 00253 /* ----- static methods ----- */ 00254 00255 /*! 00256 * \brief Set the singleton gc_job_manager instance. 00257 * \param mgr is the job manager instance. 00258 * 00259 * The singleton is weakly held, thus the caller must maintain 00260 * a reference to the mgr for the duration. (If we held the 00261 * manager strongly, the destructor would never be called, and the 00262 * resources (SPEs) would not be returned.) Bottom line: the 00263 * caller is responsible for life-time management. 00264 */ 00265 static void set_singleton(gc_job_manager_sptr mgr); 00266 00267 /*! 00268 * \brief Retrieve the singleton gc_job_manager instance. 00269 * 00270 * Returns the singleton gc_job_manager instance or raises 00271 * boost::bad_weak_ptr if the singleton is empty. 00272 */ 00273 static gc_job_manager_sptr singleton(); 00274 00275 /*! 00276 * \brief return a boost::shared_ptr to a job descriptor. 00277 */ 00278 static gc_job_desc_sptr make_jd_sptr(gc_job_manager_sptr mgr, gc_job_desc *jd); 00279 00280 /*! 00281 * \brief allocate a job descriptor and return a boost::shared_ptr to it. 00282 */ 00283 static gc_job_desc_sptr alloc_job_desc(gc_job_manager_sptr mgr); 00284 }; 00285 00286 00287 #endif /* INCLUDED_GC_JOB_MANAGER_H */