3 * Copyright 2007,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef INCLUDED_GC_JOB_MANAGER_H
23 #define INCLUDED_GC_JOB_MANAGER_H
25 #include <boost/utility.hpp>
26 #include <boost/shared_ptr.hpp>
31 #include "gc_job_desc.h"
34 typedef boost::shared_ptr<gc_job_manager> gc_job_manager_sptr;
35 typedef boost::shared_ptr<spe_program_handle_t> spe_program_handle_sptr;
36 typedef boost::shared_ptr<gc_job_desc> gc_job_desc_sptr;
39 * \brief Return a boost::shared_ptr to an spe_program_handle_t
41 * \param filename is the name of the SPE ELF executable to open.
43 * Calls spe_image_open to open the file. If successful returns a
44 * boost::shared_ptr that will call spe_image_close when it's time to
47 * Returns the equivalent of the NULL pointer if the file cannot be
48 * opened, or if it's not an SPE ELF object file.
50 * \sa gc_program_handle_from_address
52 spe_program_handle_sptr
53 gc_program_handle_from_filename(const std::string &filename);
56 * \brief Return a boost::shared_ptr to an spe_program_handle_t
58 * \param handle is a non-zero pointer to an embedded SPE image.
60 * If successful returns a boost::shared_ptr that does nothing when
61 * it's time to free the object.
63 * \sa gc_program_handle_from_filename
65 spe_program_handle_sptr
66 gc_program_handle_from_address(spe_program_handle_t *handle);
69 * \brief map gc_job_status_t into a string
72 gc_job_status_string(gc_job_status_t status);
75 * \brief Options that configure the job_manager.
76 * The default values are reasonable.
78 struct gc_jm_options {
79 unsigned int max_jobs; // max # of job descriptors in system
80 unsigned int max_client_threads; // max # of client threads of job manager
81 unsigned int nspes; // how many SPEs shall we use? 0 -> all of them
82 bool gang_schedule; // shall we gang schedule?
83 bool use_affinity; // shall we try for affinity (FIXME not implmented)
84 bool enable_logging; // shall we log SPE events?
85 uint32_t log2_nlog_entries; // log2 of number of log entries (default is 12 == 4k)
86 spe_program_handle_sptr program_handle; // program to load into SPEs
89 max_jobs(0), max_client_threads(0), nspes(0),
90 gang_schedule(false), use_affinity(false),
91 enable_logging(false), log2_nlog_entries(12)
95 gc_jm_options(spe_program_handle_sptr program_handle_,
96 unsigned int nspes_ = 0) :
97 max_jobs(0), max_client_threads(0), nspes(nspes_),
98 gang_schedule(false), use_affinity(false),
99 enable_logging(false), log2_nlog_entries(12),
100 program_handle(program_handle_)
113 class gc_exception : public std::runtime_error
116 gc_exception(const std::string &msg);
119 class gc_unknown_proc : public gc_exception
122 gc_unknown_proc(const std::string &msg);
125 class gc_bad_alloc : public gc_exception
128 gc_bad_alloc(const std::string &msg);
131 class gc_bad_align : public gc_exception
134 gc_bad_align(const std::string &msg);
137 class gc_bad_submit : public gc_exception
140 gc_bad_submit(const std::string &name, gc_job_status_t status);
144 * \brief Create an instance of the job manager
147 gc_make_job_manager(const gc_jm_options *options = 0);
151 * \brief Abstract class that manages SPE jobs.
153 * There is typically a single instance derived from this class.
154 * It is safe to call its methods from any thread.
156 class gc_job_manager : boost::noncopyable
159 gc_job_manager(const gc_jm_options *options = 0);
161 virtual ~gc_job_manager();
164 * Stop accepting new jobs. Wait for existing jobs to complete.
165 * Return all managed SPE's to the system.
167 virtual bool shutdown() = 0;
170 * \brief Return number of SPE's currently allocated to job manager.
172 virtual int nspes() const = 0;
175 * \brief Return a pointer to a properly aligned job descriptor,
176 * or throws gc_bad_alloc if there are none available.
178 virtual gc_job_desc *alloc_job_desc() = 0;
181 *! Free a job descriptor previously allocated with alloc_job_desc()
183 * \param[in] jd pointer to job descriptor to free.
185 virtual void free_job_desc(gc_job_desc *jd) = 0;
188 * \brief Submit a job for asynchronous processing on an SPE.
190 * \param[in] jd pointer to job description
192 * The caller must not read or write the job description
193 * or any of the memory associated with any indirect arguments
194 * until after calling wait_job.
196 * \returns true iff the job was successfully enqueued.
197 * If submit_job returns false, check jd->status for additional info.
199 virtual bool submit_job(gc_job_desc *jd) = 0;
202 * \brief Wait for job to complete.
204 * A thread may only wait for jobs which it submitted.
206 * \returns true if sucessful, else false.
209 wait_job(gc_job_desc *jd) = 0;
212 * \brief wait for 1 or more jobs to complete.
214 * \param[input] njobs is the length of arrays \p jd and \p done.
215 * \param[input] jd are the jobs that are to be waited for.
216 * \param[output] done indicates whether the corresponding job is complete.
217 * \param[input] mode indicates whether to wait for ALL or ANY of the jobs
218 * in \p jd to complete.
220 * A thread may only wait for jobs which it submitted.
222 * \returns number of jobs completed, or -1 if error.
223 * The caller must examine the status field of each job to confirm
224 * successful completion of the job.
227 wait_jobs(unsigned int njobs,
228 gc_job_desc *jd[], bool done[], gc_wait_mode mode) = 0;
231 * Return the maximum number of bytes of EA arguments that may be
232 * copied to or from the SPE in a single job. The limit applies
233 * independently to the "get" and "put" args.
234 * \sa gc_job_desc_t, gc_job_ea_args_t
236 virtual int ea_args_maxsize() = 0;
239 * Return gc_proc_id_t associated with spu procedure \p proc_name if one
240 * exists, otherwise throws gc_unknown_proc.
242 virtual gc_proc_id_t lookup_proc(const std::string &proc_name) = 0;
245 * Return a vector of all known spu procedure names.
247 virtual std::vector<std::string> proc_names() = 0;
249 virtual void set_debug(int debug);
252 /* ----- static methods ----- */
255 * \brief Set the singleton gc_job_manager instance.
256 * \param mgr is the job manager instance.
258 * The singleton is weakly held, thus the caller must maintain
259 * a reference to the mgr for the duration. (If we held the
260 * manager strongly, the destructor would never be called, and the
261 * resources (SPEs) would not be returned.) Bottom line: the
262 * caller is responsible for life-time management.
264 static void set_singleton(gc_job_manager_sptr mgr);
267 * \brief Retrieve the singleton gc_job_manager instance.
269 * Returns the singleton gc_job_manager instance or raises
270 * boost::bad_weak_ptr if the singleton is empty.
272 static gc_job_manager_sptr singleton();
275 * \brief return a boost::shared_ptr to a job descriptor.
277 static gc_job_desc_sptr make_jd_sptr(gc_job_manager_sptr mgr, gc_job_desc *jd);
280 * \brief allocate a job descriptor and return a boost::shared_ptr to it.
282 static gc_job_desc_sptr alloc_job_desc(gc_job_manager_sptr mgr);
286 #endif /* INCLUDED_GC_JOB_MANAGER_H */