/home/users/khuck/src/hpx-lsu/hpx/runtime/threads/thread_helpers.hpp

Line% of fetchesSource
1  
//  Copyright (c) 2007-2015 Hartmut Kaiser
2  
//  Copyright (c)      2011 Bryce Lelbach
3  
//  Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon
4  
//
5  
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
8  
#ifndef HPX_RUNTIME_THREADS_THREAD_HELPERS_HPP
9  
#define HPX_RUNTIME_THREADS_THREAD_HELPERS_HPP
10  
11  
#include <hpx/config.hpp>
12  
#include <hpx/exception_fwd.hpp>
13  
#include <hpx/runtime/naming_fwd.hpp>
14  
#include <hpx/runtime/threads/policies/scheduler_mode.hpp>
15  
#include <hpx/runtime/threads/thread_data_fwd.hpp>
16  
#include <hpx/runtime/threads/thread_enums.hpp>
17  
#include <hpx/util_fwd.hpp>
18  
#include <hpx/util/unique_function.hpp>
19  
#include <hpx/util/steady_clock.hpp>
20  
#include <hpx/util/thread_description.hpp>
21  
22  
#include <chrono>
23  
#include <cstddef>
24  
#include <cstdint>
25  
26  
///////////////////////////////////////////////////////////////////////////////
27  
namespace hpx { namespace threads
28  
{
29  
    /// \cond NOINTERNAL
30  
    class thread_init_data;
31  
32  
    namespace executors
33  
    {
34  
        struct HPX_EXPORT current_executor;
35  
    }
36  
    /// \endcond
37  
38  
    ///////////////////////////////////////////////////////////////////////////
39  
    /// \brief  Set the thread state of the \a thread referenced by the
40  
    ///         thread_id \a id.
41  
    ///
42  
    /// \param id         [in] The thread id of the thread the state should
43  
    ///                   be modified for.
44  
    /// \param state      [in] The new state to be set for the thread
45  
    ///                   referenced by the \a id parameter.
46  
    /// \param state_ex   [in] The new extended state to be set for the
47  
    ///                   thread referenced by the \a id parameter.
48  
    /// \param priority
49  
    /// \param ec         [in,out] this represents the error status on exit,
50  
    ///                   if this is pre-initialized to \a hpx#throws
51  
    ///                   the function will throw on error instead.
52  
    ///
53  
    /// \note             If the thread referenced by the parameter \a id
54  
    ///                   is in \a thread_state#active state this function
55  
    ///                   schedules a new thread which will set the state of
56  
    ///                   the thread as soon as its not active anymore. The
57  
    ///                   function returns \a thread_state#active in this case.
58  
    ///
59  
    /// \returns          This function returns the previous state of the
60  
    ///                   thread referenced by the \a id parameter. It will
61  
    ///                   return one of the values as defined by the
62  
    ///                   \a thread_state enumeration. If the
63  
    ///                   thread is not known to the thread-manager the
64  
    ///                   return value will be \a thread_state#unknown.
65  
    ///
66  
    /// \note             As long as \a ec is not pre-initialized to
67  
    ///                   \a hpx#throws this function doesn't
68  
    ///                   throw but returns the result code using the
69  
    ///                   parameter \a ec. Otherwise it throws an instance
70  
    ///                   of hpx#exception.
71  
    HPX_API_EXPORT thread_state set_thread_state(thread_id_type const& id,
72  
        thread_state_enum state = pending,
73  
        thread_state_ex_enum stateex = wait_signaled,
74  
        thread_priority priority = thread_priority_normal,
75  
        hpx::error_code& ec = throws);
76  
77  
    ///////////////////////////////////////////////////////////////////////
78  
    /// \brief  Set the thread state of the \a thread referenced by the
79  
    ///         thread_id \a id.
80  
    ///
81  
    /// Set a timer to set the state of the given \a thread to the given
82  
    /// new value after it expired (at the given time)
83  
    ///
84  
    /// \param id         [in] The thread id of the thread the state should
85  
    ///                   be modified for.
86  
    /// \param at_time
87  
    /// \param state      [in] The new state to be set for the thread
88  
    ///                   referenced by the \a id parameter.
89  
    /// \param state_ex   [in] The new extended state to be set for the
90  
    ///                   thread referenced by the \a id parameter.
91  
    /// \param priority
92  
    /// \param ec         [in,out] this represents the error status on exit,
93  
    ///                   if this is pre-initialized to \a hpx#throws
94  
    ///                   the function will throw on error instead.
95  
    ///
96  
    /// \returns
97  
    ///
98  
    /// \note             As long as \a ec is not pre-initialized to
99  
    ///                   \a hpx#throws this function doesn't
100  
    ///                   throw but returns the result code using the
101  
    ///                   parameter \a ec. Otherwise it throws an instance
102  
    ///                   of hpx#exception.
103  
    HPX_API_EXPORT thread_id_type set_thread_state(thread_id_type const& id,
104  
        util::steady_time_point const& abs_time,
105  
        thread_state_enum state = pending,
106  
        thread_state_ex_enum stateex = wait_timeout,
107  
        thread_priority priority = thread_priority_normal,
108  
        error_code& ec = throws);
109  
110  
    ///////////////////////////////////////////////////////////////////////////
111  
    /// \brief  Set the thread state of the \a thread referenced by the
112  
    ///         thread_id \a id.
113  
    ///
114  
    /// Set a timer to set the state of the given \a thread to the given
115  
    /// new value after it expired (after the given duration)
116  
    ///
117  
    /// \param id         [in] The thread id of the thread the state should
118  
    ///                   be modified for.
119  
    /// \param after_duration
120  
    /// \param state      [in] The new state to be set for the thread
121  
    ///                   referenced by the \a id parameter.
122  
    /// \param state_ex   [in] The new extended state to be set for the
123  
    ///                   thread referenced by the \a id parameter.
124  
    /// \param priority
125  
    /// \param ec         [in,out] this represents the error status on exit,
126  
    ///                   if this is pre-initialized to \a hpx#throws
127  
    ///                   the function will throw on error instead.
128  
    ///
129  
    /// \returns
130  
    ///
131  
    /// \note             As long as \a ec is not pre-initialized to
132  
    ///                   \a hpx#throws this function doesn't
133  
    ///                   throw but returns the result code using the
134  
    ///                   parameter \a ec. Otherwise it throws an instance
135  
    ///                   of hpx#exception.
136  
    inline thread_id_type set_thread_state(thread_id_type const& id,
137  
        util::steady_duration const& rel_time,
138  
        thread_state_enum state = pending,
139  
        thread_state_ex_enum stateex = wait_timeout,
140  
        thread_priority priority = thread_priority_normal,
141  
        error_code& ec = throws)
142  
    {
143  
        return set_thread_state(id, rel_time.from_now(), state, stateex,
144  
            priority, ec);
145  
    }
146  
147  
    ///////////////////////////////////////////////////////////////////////////
148  
    /// The function get_thread_description is part of the thread related API
149  
    /// allows to query the description of one of the threads known to the
150  
    /// thread-manager.
151  
    ///
152  
    /// \param id         [in] The thread id of the thread being queried.
153  
    /// \param ec         [in,out] this represents the error status on exit,
154  
    ///                   if this is pre-initialized to \a hpx#throws
155  
    ///                   the function will throw on error instead.
156  
    ///
157  
    /// \returns          This function returns the description of the
158  
    ///                   thread referenced by the \a id parameter. If the
159  
    ///                   thread is not known to the thread-manager the return
160  
    ///                   value will be the string "<unknown>".
161  
    ///
162  
    /// \note             As long as \a ec is not pre-initialized to
163  
    ///                   \a hpx#throws this function doesn't
164  
    ///                   throw but returns the result code using the
165  
    ///                   parameter \a ec. Otherwise it throws an instance
166  
    ///                   of hpx#exception.
167  
    HPX_API_EXPORT util::thread_description get_thread_description(
168  
        thread_id_type const& id, error_code& ec = throws);
169  
    HPX_API_EXPORT util::thread_description set_thread_description(
170  
        thread_id_type const& id,
171  
        util::thread_description const& desc = util::thread_description(),
172  
        error_code& ec = throws);
173  
174  
    HPX_API_EXPORT util::thread_description get_thread_lco_description(
175  
        thread_id_type const& id, error_code& ec = throws);
176  
    HPX_API_EXPORT util::thread_description set_thread_lco_description(
177  
        thread_id_type const& id,
178  
        util::thread_description const& desc = util::thread_description(),
179  
        error_code& ec = throws);
180  
181  
    ///////////////////////////////////////////////////////////////////////////
182  
    /// The function get_thread_backtrace is part of the thread related API
183  
    /// allows to query the currently stored thread back trace (which is
184  
    /// captured during thread suspension).
185  
    ///
186  
    /// \param id         [in] The thread id of the thread being queried.
187  
    /// \param ec         [in,out] this represents the error status on exit,
188  
    ///                   if this is pre-initialized to \a hpx#throws
189  
    ///                   the function will throw on error instead.
190  
    ///
191  
    /// \returns          This function returns the currently captured stack
192  
    ///                   back trace of the thread referenced by the \a id
193  
    ///                   parameter. If the thread is not known to the
194  
    ///                   thread-manager the return value will be the zero.
195  
    ///
196  
    /// \note             As long as \a ec is not pre-initialized to
197  
    ///                   \a hpx#throws this function doesn't
198  
    ///                   throw but returns the result code using the
199  
    ///                   parameter \a ec. Otherwise it throws an instance
200  
    ///                   of hpx#exception.
201  
#ifdef HPX_HAVE_THREAD_FULLBACKTRACE_ON_SUSPENSION
202  
    HPX_API_EXPORT char const* get_thread_backtrace(
203  
        thread_id_type const& id, error_code& ec = throws);
204  
    HPX_API_EXPORT char const* set_thread_backtrace(
205  
        thread_id_type const& id, char const* bt = nullptr,
206  
        error_code& ec = throws);
207  
#else
208  
#if !defined(DOXYGEN)
209  
    HPX_API_EXPORT util::backtrace const* get_thread_backtrace(
210  
        thread_id_type const& id, error_code& ec = throws);
211  
    HPX_API_EXPORT util::backtrace const* set_thread_backtrace(
212  
        thread_id_type const& id, util::backtrace const* bt = nullptr,
213  
        error_code& ec = throws);
214  
#endif
215  
#endif
216  
217  
    ///////////////////////////////////////////////////////////////////////////
218  
    /// The function get_thread_state is part of the thread related API. It
219  
    /// queries the state of one of the threads known to the thread-manager.
220  
    ///
221  
    /// \param id         [in] The thread id of the thread the state should
222  
    ///                   be modified for.
223  
    /// \param ec         [in,out] this represents the error status on exit,
224  
    ///                   if this is pre-initialized to \a hpx#throws
225  
    ///                   the function will throw on error instead.
226  
    ///
227  
    /// \returns          This function returns the thread state of the
228  
    ///                   thread referenced by the \a id parameter. If the
229  
    ///                   thread is not known to the thread-manager the return
230  
    ///                   value will be \a terminated.
231  
    ///
232  
    /// \note             As long as \a ec is not pre-initialized to
233  
    ///                   \a hpx#throws this function doesn't
234  
    ///                   throw but returns the result code using the
235  
    ///                   parameter \a ec. Otherwise it throws an instance
236  
    ///                   of hpx#exception.
237  
    HPX_API_EXPORT thread_state get_thread_state(thread_id_type const& id,
238  
        error_code& ec = throws);
239  
240  
    ///////////////////////////////////////////////////////////////////////////
241  
    /// The function get_thread_phase is part of the thread related API.
242  
    /// It queries the phase of one of the threads known to the thread-manager.
243  
    ///
244  
    /// \param id         [in] The thread id of the thread the phase should
245  
    ///                   be modified for.
246  
    /// \param ec         [in,out] this represents the error status on exit,
247  
    ///                   if this is pre-initialized to \a hpx#throws
248  
    ///                   the function will throw on error instead.
249  
    ///
250  
    /// \returns          This function returns the thread phase of the
251  
    ///                   thread referenced by the \a id parameter. If the
252  
    ///                   thread is not known to the thread-manager the return
253  
    ///                   value will be ~0.
254  
    ///
255  
    /// \note             As long as \a ec is not pre-initialized to
256  
    ///                   \a hpx#throws this function doesn't
257  
    ///                   throw but returns the result code using the
258  
    ///                   parameter \a ec. Otherwise it throws an instance
259  
    ///                   of hpx#exception.
260  
    HPX_API_EXPORT std::size_t get_thread_phase(thread_id_type const& id,
261  
        error_code& ec = throws);
262  
263  
    ///////////////////////////////////////////////////////////////////////////
264  
    // Return the number of the NUMA node the current thread is running on
265  
    HPX_API_EXPORT std::size_t get_numa_node_number();
266  
267  
    ///////////////////////////////////////////////////////////////////////////
268  
    /// Returns whether the given thread can be interrupted at this point.
269  
    ///
270  
    /// \param id         [in] The thread id of the thread which should be
271  
    ///                   queried.
272  
    /// \param ec         [in,out] this represents the error status on exit,
273  
    ///                   if this is pre-initialized to \a hpx#throws
274  
    ///                   the function will throw on error instead.
275  
    ///
276  
    /// \returns          This function returns \a true if the given thread
277  
    ///                   can be interrupted at this point in time. It will
278  
    ///                   return \a false otherwise.
279  
    ///
280  
    /// \note             As long as \a ec is not pre-initialized to
281  
    ///                   \a hpx#throws this function doesn't
282  
    ///                   throw but returns the result code using the
283  
    ///                   parameter \a ec. Otherwise it throws an instance
284  
    ///                   of hpx#exception.
285  
    HPX_API_EXPORT bool get_thread_interruption_enabled(thread_id_type const& id,
286  
        error_code& ec = throws);
287  
288  
    /// Set whether the given thread can be interrupted at this point.
289  
    ///
290  
    /// \param id         [in] The thread id of the thread which should
291  
    ///                   receive the new value.
292  
    /// \param enable     [in] This value will determine the new interruption
293  
    ///                   enabled status for the given thread.
294  
    /// \param ec         [in,out] this represents the error status on exit,
295  
    ///                   if this is pre-initialized to \a hpx#throws
296  
    ///                   the function will throw on error instead.
297  
    ///
298  
    /// \returns          This function returns the previous value of
299  
    ///                   whether the given thread could have been interrupted.
300  
    ///
301  
    /// \note             As long as \a ec is not pre-initialized to
302  
    ///                   \a hpx#throws this function doesn't
303  
    ///                   throw but returns the result code using the
304  
    ///                   parameter \a ec. Otherwise it throws an instance
305  
    ///                   of hpx#exception.
306  
    HPX_API_EXPORT bool set_thread_interruption_enabled(thread_id_type const& id,
307  
        bool enable, error_code& ec = throws);
308  
309  
    /// Returns whether the given thread has been flagged for interruption.
310  
    ///
311  
    /// \param id         [in] The thread id of the thread which should be
312  
    ///                   queried.
313  
    /// \param ec         [in,out] this represents the error status on exit,
314  
    ///                   if this is pre-initialized to \a hpx#throws
315  
    ///                   the function will throw on error instead.
316  
    ///
317  
    /// \returns          This function returns \a true if the given thread
318  
    ///                   was flagged for interruption. It will return
319  
    ///                   \a false otherwise.
320  
    ///
321  
    /// \note             As long as \a ec is not pre-initialized to
322  
    ///                   \a hpx#throws this function doesn't
323  
    ///                   throw but returns the result code using the
324  
    ///                   parameter \a ec. Otherwise it throws an instance
325  
    ///                   of hpx#exception.
326  
    HPX_API_EXPORT bool get_thread_interruption_requested(thread_id_type const& id,
327  
        error_code& ec = throws);
328  
329  
    /// Flag the given thread for interruption.
330  
    ///
331  
    /// \param id         [in] The thread id of the thread which should be
332  
    ///                   interrupted.
333  
    /// \param flag       [in] The flag encodes whether the thread should be
334  
    ///                   interrupted (if it is \a true), or 'uninterrupted'
335  
    ///                   (if it is \a false).
336  
    /// \param ec         [in,out] this represents the error status on exit,
337  
    ///                   if this is pre-initialized to \a hpx#throws
338  
    ///                   the function will throw on error instead.
339  
    ///
340  
    /// \note             As long as \a ec is not pre-initialized to
341  
    ///                   \a hpx#throws this function doesn't
342  
    ///                   throw but returns the result code using the
343  
    ///                   parameter \a ec. Otherwise it throws an instance
344  
    ///                   of hpx#exception.
345  
    HPX_API_EXPORT void interrupt_thread(thread_id_type const& id, bool flag,
346  
        error_code& ec = throws);
347  
348  
    inline void interrupt_thread(thread_id_type const& id, error_code& ec = throws)
349  
    {
350  
        interrupt_thread(id, true, ec);
351  
    }
352  
353  
    ///////////////////////////////////////////////////////////////////////////
354  
    /// Interrupt the current thread at this point if it was canceled. This
355  
    /// will throw a thread_interrupted exception, which will cancel the thread.
356  
    ///
357  
    /// \param id         [in] The thread id of the thread which should be
358  
    ///                   interrupted.
359  
    /// \param ec         [in,out] this represents the error status on exit,
360  
    ///                   if this is pre-initialized to \a hpx#throws
361  
    ///                   the function will throw on error instead.
362  
    ///
363  
    /// \note             As long as \a ec is not pre-initialized to
364  
    ///                   \a hpx#throws this function doesn't
365  
    ///                   throw but returns the result code using the
366  
    ///                   parameter \a ec. Otherwise it throws an instance
367  
    ///                   of hpx#exception.
368  
    HPX_API_EXPORT void interruption_point(thread_id_type const& id,
369  
        error_code& ec = throws);
370  
371  
    ///////////////////////////////////////////////////////////////////////////
372  
    /// Return priority of the given thread
373  
    ///
374  
    /// \param id         [in] The thread id of the thread whose priority
375  
    ///                   is queried.
376  
    /// \param ec         [in,out] this represents the error status on exit,
377  
    ///                   if this is pre-initialized to \a hpx#throws
378  
    ///                   the function will throw on error instead.
379  
    ///
380  
    /// \note             As long as \a ec is not pre-initialized to
381  
    ///                   \a hpx#throws this function doesn't
382  
    ///                   throw but returns the result code using the
383  
    ///                   parameter \a ec. Otherwise it throws an instance
384  
    ///                   of hpx#exception.
385  
    HPX_API_EXPORT threads::thread_priority get_thread_priority(
386  
        thread_id_type const& id, error_code& ec = throws);
387  
388  
    ///////////////////////////////////////////////////////////////////////////
389  
    /// Return stack size of the given thread
390  
    ///
391  
    /// \param id         [in] The thread id of the thread whose priority
392  
    ///                   is queried.
393  
    /// \param ec         [in,out] this represents the error status on exit,
394  
    ///                   if this is pre-initialized to \a hpx#throws
395  
    ///                   the function will throw on error instead.
396  
    ///
397  
    /// \note             As long as \a ec is not pre-initialized to
398  
    ///                   \a hpx#throws this function doesn't
399  
    ///                   throw but returns the result code using the
400  
    ///                   parameter \a ec. Otherwise it throws an instance
401  
    ///                   of hpx#exception.
402  
    HPX_API_EXPORT std::ptrdiff_t get_stack_size(
403  
        thread_id_type const& id, error_code& ec = throws);
404  
405  
    ///////////////////////////////////////////////////////////////////////////
406  
    /// \cond NOINTERNAL
407  
    HPX_API_EXPORT void run_thread_exit_callbacks(thread_id_type const& id,
408  
        error_code& ec = throws);
409  
410  
    HPX_API_EXPORT bool add_thread_exit_callback(thread_id_type const& id,
411  
        util::function_nonser<void()> const& f, error_code& ec = throws);
412  
413  
    HPX_API_EXPORT void free_thread_exit_callbacks(thread_id_type const& id,
414  
        error_code& ec = throws);
415  
416  
    ///////////////////////////////////////////////////////////////////////////
417  
    HPX_API_EXPORT std::size_t get_thread_data(thread_id_type const& id,
418  
        error_code& ec = throws);
419  
420  
    HPX_API_EXPORT std::size_t set_thread_data(thread_id_type const& id,
421  
        std::size_t data, error_code& ec = throws);
422  
423  
    HPX_API_EXPORT std::size_t& get_continuation_recursion_count();
424  
    HPX_API_EXPORT void reset_continuation_recursion_count();
425  
    /// \endcond
426  
427  
    /// Returns a reference to the executor which was used to create
428  
    /// the given thread.
429  
    ///
430  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
431  
    ///         to an appropriate value when an error occurs. Otherwise, this
432  
    ///         function will throw an \a hpx#exception with an error code of
433  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
434  
    ///         If called outside of a HPX-thread, this function will throw
435  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
436  
    ///         If this function is called while the thread-manager is not
437  
    ///         running, it will throw an \a hpx#exception with an error code of
438  
    ///         \a hpx#invalid_status.
439  
    ///
440  
    HPX_API_EXPORT threads::executors::current_executor
441  
        get_executor(thread_id_type const& id, error_code& ec = throws);
442  
443  
    /// \cond NOINTERNAL
444  
    /// Reset internal (round robin) thread distribution scheme
445  
    HPX_API_EXPORT void reset_thread_distribution();
446  
447  
    /// Set the new scheduler mode
448  
    HPX_API_EXPORT void set_scheduler_mode(threads::policies::scheduler_mode);
449  
    /// \endcond
450  
}}
451  
452  
namespace hpx { namespace this_thread
453  
{
454  
    ///////////////////////////////////////////////////////////////////////////
455  
    /// The function \a suspend will return control to the thread manager
456  
    /// (suspends the current thread). It sets the new state of this thread
457  
    /// to the thread state passed as the parameter.
458  
    ///
459  
    /// \note Must be called from within a HPX-thread.
460  
    ///
461  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
462  
    ///         to an appropriate value when an error occurs. Otherwise, this
463  
    ///         function will throw an \a hpx#exception with an error code of
464  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
465  
    ///         If called outside of a HPX-thread, this function will throw
466  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
467  
    ///         If this function is called while the thread-manager is not
468  
    ///         running, it will throw an \a hpx#exception with an error code of
469  
    ///         \a hpx#invalid_status.
470  
    ///
471  
    HPX_API_EXPORT threads::thread_state_ex_enum suspend(
472  
        threads::thread_state_enum state, threads::thread_id_type const& id,
473  
        util::thread_description const& description =
474  
            util::thread_description("this_thread::suspend"),
475  
        error_code& ec = throws);
476  
477  
    /// The function \a suspend will return control to the thread manager
478  
    /// (suspends the current thread). It sets the new state of this thread
479  
    /// to the thread state passed as the parameter.
480  
    ///
481  
    /// \note Must be called from within a HPX-thread.
482  
    ///
483  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
484  
    ///         to an appropriate value when an error occurs. Otherwise, this
485  
    ///         function will throw an \a hpx#exception with an error code of
486  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
487  
    ///         If called outside of a HPX-thread, this function will throw
488  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
489  
    ///         If this function is called while the thread-manager is not
490  
    ///         running, it will throw an \a hpx#exception with an error code of
491  
    ///         \a hpx#invalid_status.
492  
    ///
493  
    inline threads::thread_state_ex_enum suspend(
494  
        threads::thread_state_enum state = threads::pending,
495  
        util::thread_description const& description =
496  
            util::thread_description("this_thread::suspend"),
497  
        error_code& ec = throws)
498  
    {
499  
        return suspend(state, nullptr, description, ec);
500  
    }
501  
502  
    /// The function \a suspend will return control to the thread manager
503  
    /// (suspends the current thread). It sets the new state of this thread
504  
    /// to \a suspended and schedules a wakeup for this threads at the given
505  
    /// time.
506  
    ///
507  
    /// \note Must be called from within a HPX-thread.
508  
    ///
509  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
510  
    ///         to an appropriate value when an error occurs. Otherwise, this
511  
    ///         function will throw an \a hpx#exception with an error code of
512  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
513  
    ///         If called outside of a HPX-thread, this function will throw
514  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
515  
    ///         If this function is called while the thread-manager is not
516  
    ///         running, it will throw an \a hpx#exception with an error code of
517  
    ///         \a hpx#invalid_status.
518  
    ///
519  
    HPX_API_EXPORT threads::thread_state_ex_enum suspend(
520  
        util::steady_time_point const& abs_time,
521  
        threads::thread_id_type const& id,
522  
        util::thread_description const& description =
523  
            util::thread_description("this_thread::suspend"),
524  
        error_code& ec = throws);
525  
526  
    /// The function \a suspend will return control to the thread manager
527  
    /// (suspends the current thread). It sets the new state of this thread
528  
    /// to \a suspended and schedules a wakeup for this threads at the given
529  
    /// time.
530  
    ///
531  
    /// \note Must be called from within a HPX-thread.
532  
    ///
533  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
534  
    ///         to an appropriate value when an error occurs. Otherwise, this
535  
    ///         function will throw an \a hpx#exception with an error code of
536  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
537  
    ///         If called outside of a HPX-thread, this function will throw
538  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
539  
    ///         If this function is called while the thread-manager is not
540  
    ///         running, it will throw an \a hpx#exception with an error code of
541  
    ///         \a hpx#invalid_status.
542  
    ///
543  
    inline threads::thread_state_ex_enum suspend(
544  
        util::steady_time_point const& abs_time,
545  
        util::thread_description const& description =
546  
            util::thread_description("this_thread::suspend"),
547  
        error_code& ec = throws)
548  
    {
549  
        return suspend(abs_time, nullptr, description, ec);
550  
    }
551  
552  
    /// The function \a suspend will return control to the thread manager
553  
    /// (suspends the current thread). It sets the new state of this thread
554  
    /// to \a suspended and schedules a wakeup for this threads after the given
555  
    /// duration.
556  
    ///
557  
    /// \note Must be called from within a HPX-thread.
558  
    ///
559  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
560  
    ///         to an appropriate value when an error occurs. Otherwise, this
561  
    ///         function will throw an \a hpx#exception with an error code of
562  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
563  
    ///         If called outside of a HPX-thread, this function will throw
564  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
565  
    ///         If this function is called while the thread-manager is not
566  
    ///         running, it will throw an \a hpx#exception with an error code of
567  
    ///         \a hpx#invalid_status.
568  
    ///
569  
    inline threads::thread_state_ex_enum suspend(
570  
        util::steady_duration const& rel_time,
571  
        util::thread_description const& description =
572  
            util::thread_description("this_thread::suspend"),
573  
        error_code& ec = throws)
574  
    {
575  
        return suspend(rel_time.from_now(), nullptr, description, ec);
576  
    }
577  
578  
    /// The function \a suspend will return control to the thread manager
579  
    /// (suspends the current thread). It sets the new state of this thread
580  
    /// to \a suspended and schedules a wakeup for this threads after the given
581  
    /// duration.
582  
    ///
583  
    /// \note Must be called from within a HPX-thread.
584  
    ///
585  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
586  
    ///         to an appropriate value when an error occurs. Otherwise, this
587  
    ///         function will throw an \a hpx#exception with an error code of
588  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
589  
    ///         If called outside of a HPX-thread, this function will throw
590  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
591  
    ///         If this function is called while the thread-manager is not
592  
    ///         running, it will throw an \a hpx#exception with an error code of
593  
    ///         \a hpx#invalid_status.
594  
    ///
595  
    inline threads::thread_state_ex_enum suspend(
596  
        util::steady_duration const& rel_time,
597  
        threads::thread_id_type const& id,
598  
        util::thread_description const& description =
599  
            util::thread_description("this_thread::suspend"),
600  
        error_code& ec = throws)
601  
    {
602  
        return suspend(rel_time.from_now(), id, description, ec);
603  
    }
604  
605  
    /// The function \a suspend will return control to the thread manager
606  
    /// (suspends the current thread). It sets the new state of this thread
607  
    /// to \a suspended and schedules a wakeup for this threads after the given
608  
    /// time (specified in milliseconds).
609  
    ///
610  
    /// \note Must be called from within a HPX-thread.
611  
    ///
612  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
613  
    ///         to an appropriate value when an error occurs. Otherwise, this
614  
    ///         function will throw an \a hpx#exception with an error code of
615  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
616  
    ///         If called outside of a HPX-thread, this function will throw
617  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
618  
    ///         If this function is called while the thread-manager is not
619  
    ///         running, it will throw an \a hpx#exception with an error code of
620  
    ///         \a hpx#invalid_status.
621  
    ///
622  
    inline threads::thread_state_ex_enum suspend(std::uint64_t ms,
623  
        util::thread_description const& description =
624  
            util::thread_description("this_thread::suspend"),
625  
        error_code& ec = throws)
626  
    {
627  
        return suspend(std::chrono::milliseconds(ms), nullptr, description, ec);
628  
    }
629  
630  
    /// Returns a reference to the executor which was used to create the current
631  
    /// thread.
632  
    ///
633  
    /// \throws If <code>&ec != &throws</code>, never throws, but will set \a ec
634  
    ///         to an appropriate value when an error occurs. Otherwise, this
635  
    ///         function will throw an \a hpx#exception with an error code of
636  
    ///         \a hpx#yield_aborted if it is signaled with \a wait_aborted.
637  
    ///         If called outside of a HPX-thread, this function will throw
638  
    ///         an \a hpx#exception with an error code of \a hpx::null_thread_id.
639  
    ///         If this function is called while the thread-manager is not
640  
    ///         running, it will throw an \a hpx#exception with an error code of
641  
    ///         \a hpx#invalid_status.
642  
    ///
643  
    HPX_EXPORT threads::executors::current_executor
644  
        get_executor(error_code& ec = throws);
645  
646  
    /// \cond NOINTERNAL
647  
    // returns the remaining available stack space
648  
    HPX_EXPORT std::ptrdiff_t get_available_stack_space();
649  
650  
    // returns whether the remaining stack-space is at least as large as
651  
    // requested
652  
    HPX_EXPORT bool has_sufficient_stack_space(
653  
        std::size_t space_needed = 8 * HPX_THREADS_STACK_OVERHEAD);
654  
    /// \endcond
655  
}}
656  
657  
/// \cond NOINTERNAL
658  
659  
///////////////////////////////////////////////////////////////////////////////
660  
// FIXME: the API function below belong into the namespace hpx::threads
661  
namespace hpx { namespace applier
662  
{
663  
    ///////////////////////////////////////////////////////////////////////////
664  
    /// \brief Create a new \a thread using the given function as the work to
665  
    ///        be executed.
666  
    ///
667  
    /// \param func       [in] The function to be executed as the thread-function.
668  
    ///                   This function has to expose the minimal low level
669  
    ///                   HPX-thread interface, i.e. it takes one argument (a
670  
    ///                   \a threads#thread_state_ex_enum) and returns a
671  
    ///                   \a threads#thread_state_enum.
672  
    /// \param description [in] A optional string describing the newly created
673  
    ///                   thread. This is useful for debugging and logging
674  
    ///                   purposes as this string will be inserted in the logs.
675  
    /// \param initial_state [in] The thread state the newly created thread
676  
    ///                   should have. If this is not given it defaults to
677  
    ///                   \a threads#pending, which means that the new thread
678  
    ///                   will be scheduled to run as soon as it is created.
679  
    /// \param run_now    [in] If this is set to `true` the thread object will
680  
    ///                   be actually immediately created. Otherwise the
681  
    ///                   thread-manager creates a work-item description, which
682  
    ///                   will result in creating a thread object later (if
683  
    ///                   no work is available any more). The default is to
684  
    ///                   immediately create the thread object.
685  
    /// \param priority   [in] This is the priority the newly created HPX-thread
686  
    ///                   should be executed with. The default is \a
687  
    ///                   threads#thread_priority_normal. This parameter is not
688  
    ///                   guaranteed to be taken into account as it depends on
689  
    ///                   the used scheduling policy whether priorities are
690  
    ///                   supported in the first place.
691  
    /// \param os_thread  [in] The number of the shepherd thread the newly
692  
    ///                   created HPX-thread should run on. If this is given it
693  
    ///                   will be no more than a hint in any case, mainly
694  
    ///                   because even if the HPX-thread gets scheduled on the
695  
    ///                   queue of the requested shepherd thread, it still can
696  
    ///                   be stolen by another shepherd thread. If this is not
697  
    ///                   given, the system will select a shepherd thread.
698  
    /// \param ec         [in,out] This represents the error status on exit,
699  
    ///                   if this is pre-initialized to \a hpx#throws
700  
    ///                   the function will throw on error instead.
701  
    ///
702  
    /// \returns This function will return the internal id of the newly created
703  
    ///          HPX-thread or threads#invalid_thread_id (if run_now is set to
704  
    ///          `false`).
705  
    ///
706  
    /// \note The value returned by the thread function will be interpreted by
707  
    ///       the thread manager as the new thread state the executed HPX-thread
708  
    ///       needs to be switched to. Normally, HPX-threads will either return
709  
    ///       \a threads#terminated (if the thread should be destroyed) or
710  
    ///       \a threads#suspended (if the thread needs to be suspended because
711  
    ///       it is waiting for an external event to happen). The external
712  
    ///       event will set the state of the thread back to pending, which
713  
    ///       will re-schedule the HPX-thread.
714  
    ///
715  
    /// \throws invalid_status if the runtime system has not been started yet.
716  
    ///
717  
    ///
718  
    /// \note             As long as \a ec is not pre-initialized to
719  
    ///                   \a hpx#throws this function doesn't
720  
    ///                   throw but returns the result code using the
721  
    ///                   parameter \a ec. Otherwise it throws an instance
722  
    ///                   of hpx#exception.
723  
    HPX_API_EXPORT threads::thread_id_type register_thread_plain(
724  
        threads::thread_function_type && func,
725  
        util::thread_description const& description = util::thread_description(),
726  
        threads::thread_state_enum initial_state = threads::pending,
727  
        bool run_now = true,
728  
        threads::thread_priority priority = threads::thread_priority_normal,
729  
        std::size_t os_thread = std::size_t(-1),
730  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
731  
        error_code& ec = throws);
732  
733  
    ///////////////////////////////////////////////////////////////////////////
734  
    /// \brief Create a new \a thread using the given function as the work to
735  
    ///        be executed.
736  
    ///
737  
    /// \param func       [in] The function to be executed as the thread-function.
738  
    ///                   This function has to expose the minimal low level
739  
    ///                   HPX-thread interface, i.e. it takes one argument (a
740  
    ///                   \a threads#thread_state_ex_enum). The thread will be
741  
    ///                   terminated after the function returns.
742  
    ///
743  
    /// \note All other arguments are equivalent to those of the function
744  
    ///       \a threads#register_thread_plain
745  
    ///
746  
    HPX_API_EXPORT threads::thread_id_type register_thread(
747  
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> && func,
748  
        util::thread_description const& description = util::thread_description(),
749  
        threads::thread_state_enum initial_state = threads::pending,
750  
        bool run_now = true,
751  
        threads::thread_priority priority = threads::thread_priority_normal,
752  
        std::size_t os_thread = std::size_t(-1),
753  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
754  
        error_code& ec = throws);
755  
756  
    ///////////////////////////////////////////////////////////////////////////
757  
    /// \brief Create a new \a thread using the given function as the work to
758  
    ///        be executed.
759  
    ///
760  
    /// \param func       [in] The function to be executed as the thread-function.
761  
    ///                   This function has to expose the minimal low level
762  
    ///                   HPX-thread interface, i.e. it takes no arguments. The
763  
    ///                   thread will be terminated after the function returns.
764  
    ///
765  
    /// \note All other arguments are equivalent to those of the function
766  
    ///       \a threads#register_thread_plain
767  
    ///
768  
    HPX_API_EXPORT threads::thread_id_type register_thread_nullary(
769  
        util::unique_function_nonser<void()> && func,
770  
        util::thread_description const& description = util::thread_description(),
771  
        threads::thread_state_enum initial_state = threads::pending,
772  
        bool run_now = true,
773  
        threads::thread_priority priority = threads::thread_priority_normal,
774  
        std::size_t os_thread = std::size_t(-1),
775  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
776  
        error_code& ec = throws);
777  
778  
    ///////////////////////////////////////////////////////////////////////////
779  
    /// \brief Create a new \a thread using the given data.
780  
    ///
781  
    /// \note This function is completely equivalent to the first overload
782  
    ///       of threads#register_thread_plain above, except that part of the
783  
    ///       parameters are passed as members of the threads#thread_init_data
784  
    ///       object.
785  
    ///
786  
    HPX_API_EXPORT threads::thread_id_type register_thread_plain(
787  
        threads::thread_init_data& data,
788  
        threads::thread_state_enum initial_state = threads::pending,
789  
        bool run_now = true, error_code& ec = throws);
790  
791  
    ///////////////////////////////////////////////////////////////////////////
792  
    /// \brief Create a new work item using the given function as the
793  
    ///        work to be executed. This work item will be used to create a
794  
    ///        \a threads#thread instance whenever the shepherd thread runs out
795  
    ///        of work only. The created work descriptions will be queued
796  
    ///        separately, causing them to be converted into actual thread
797  
    ///        objects on a first-come-first-served basis.
798  
    ///
799  
    /// \param func       [in] The function to be executed as the thread-function.
800  
    ///                   This function has to expose the minimal low level
801  
    ///                   HPX-thread interface, i.e. it takes one argument (a
802  
    ///                   \a threads#thread_state_ex_enum) and returns a
803  
    ///                   \a threads#thread_state_enum.
804  
    /// \param description [in] A optional string describing the newly created
805  
    ///                   thread. This is useful for debugging and logging
806  
    ///                   purposes as this string will be inserted in the logs.
807  
    /// \param initial_state [in] The thread state the newly created thread
808  
    ///                   should have. If this is not given it defaults to
809  
    ///                   \a threads#pending, which means that the new thread
810  
    ///                   will be scheduled to run as soon as it is created.
811  
    /// \param priority   [in] This is the priority the newly created HPX-thread
812  
    ///                   should be executed with. The default is \a
813  
    ///                   threads#thread_priority_normal. This parameter is not
814  
    ///                   guaranteed to be taken into account as it depends on
815  
    ///                   the used scheduling policy whether priorities are
816  
    ///                   supported in the first place.
817  
    /// \param os_thread  [in] The number of the shepherd thread the newly
818  
    ///                   created HPX-thread should run on. If this is given it
819  
    ///                   will be no more than a hint in any case, mainly
820  
    ///                   because even if the HPX-thread gets scheduled on the
821  
    ///                   queue of the requested shepherd thread, it still can
822  
    ///                   be stolen by another shepherd thread. If this is not
823  
    ///                   given, the system will select a shepherd thread.
824  
    /// \param ec         [in,out] This represents the error status on exit,
825  
    ///                   if this is pre-initialized to \a hpx#throws
826  
    ///                   the function will throw on error instead.
827  
    ///
828  
    /// \note The value returned by the thread function will be interpreted by
829  
    ///       the thread manager as the new thread state the executed HPX-thread
830  
    ///       needs to be switched to. Normally, HPX-threads will either return
831  
    ///       \a threads#terminated (if the thread should be destroyed) or
832  
    ///       \a threads#suspended (if the thread needs to be suspended because
833  
    ///       it is waiting for an external event to happen). The external
834  
    ///       event will set the state of the thread back to pending, which
835  
    ///       will re-schedule the HPX-thread.
836  
    ///
837  
    /// \throws invalid_status if the runtime system has not been started yet.
838  
    ///
839  
    HPX_API_EXPORT void register_work_plain(
840  
        threads::thread_function_type && func,
841  
        util::thread_description const& description = util::thread_description(),
842  
        std::uint64_t /*naming::address_type*/ lva = 0,
843  
        threads::thread_state_enum initial_state = threads::pending,
844  
        threads::thread_priority priority = threads::thread_priority_normal,
845  
        std::size_t os_thread = std::size_t(-1),
846  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
847  
        error_code& ec = throws);
848  
849  
    ///////////////////////////////////////////////////////////////////////////
850  
    /// \brief Create a new work item using the given function as the
851  
    ///        work to be executed.
852  
    ///
853  
    /// \param func       [in] The function to be executed as the thread-function.
854  
    ///                   This function has to expose the minimal low level
855  
    ///                   HPX-thread interface, i.e. it takes one argument (a
856  
    ///                   \a threads#thread_state_ex_enum). The thread will be
857  
    ///                   terminated after the function returns.
858  
    ///
859  
    /// \note All other arguments are equivalent to those of the function
860  
    ///       \a threads#register_work_plain
861  
    ///
862  
    HPX_API_EXPORT void register_work(
863  
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> && func,
864  
        util::thread_description const& description = util::thread_description(),
865  
        threads::thread_state_enum initial_state = threads::pending,
866  
        threads::thread_priority priority = threads::thread_priority_normal,
867  
        std::size_t os_thread = std::size_t(-1),
868  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
869  
        error_code& ec = throws);
870  
871  
    ///////////////////////////////////////////////////////////////////////////
872  
    /// \brief Create a new work item using the given function as the
873  
    ///        work to be executed.
874  
    ///
875  
    /// \param func       [in] The function to be executed as the thread-function.
876  
    ///                   This function has to expose the minimal low level
877  
    ///                   HPX-thread interface, i.e. it takes no arguments. The
878  
    ///                   thread will be terminated after the function returns.
879  
    ///
880  
    /// \note All other arguments are equivalent to those of the function
881  
    ///       \a threads#register_work_plain
882  
    ///
883  
    HPX_API_EXPORT void register_work_nullary(
884  
        util::unique_function_nonser<void()> && func,
885  
        util::thread_description const& description = util::thread_description(),
886  
        threads::thread_state_enum initial_state = threads::pending,
887  
        threads::thread_priority priority = threads::thread_priority_normal,
888  
        std::size_t os_thread = std::size_t(-1),
889  
        threads::thread_stacksize stacksize = threads::thread_stacksize_default,
890  
        error_code& ec = throws);
891  
892  
    ///////////////////////////////////////////////////////////////////////////
893  
    /// \brief Create a new work item using the given function as the
894  
    ///        work to be executed.
895  
    ///
896  
    /// \note This function is completely equivalent to the first overload
897  
    ///       of threads#register_work_plain above, except that part of the
898  
    ///       parameters are passed as members of the threads#thread_init_data
899  
    ///       object.
900  
    ///
901  
    HPX_API_EXPORT void register_work_plain(
902  
        threads::thread_init_data& data,
903  
        threads::thread_state_enum initial_state = threads::pending,
904  
        error_code& ec = throws);
905  
}}
906  
907  
///////////////////////////////////////////////////////////////////////////////
908  
namespace hpx { namespace threads
909  
{
910  
    // Import all thread creation functions into this name space (we will
911  
    // deprecate the functions in namespace applier above at some point).
912  
    using applier::register_thread_plain;
913  
    using applier::register_thread;
914  
    using applier::register_thread_nullary;
915  
916  
    using applier::register_work_plain;
917  
    using applier::register_work;
918  
    using applier::register_work_nullary;
919  
}}
920  
921  
/// \endcond
922  
923  
#endif /*HPX_RUNTIME_THREADS_THREAD_HELPERS_HPP*/
924  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.