/home/users/khuck/src/hpx-lsu/src/runtime/applier/applier.cpp

Line% of fetchesSource
1  
//  Copyright (c) 2007-2008 Anshul Tandon
2  
//  Copyright (c) 2007-2016 Hartmut Kaiser
3  
//  Copyright (c) 2011      Bryce Lelbach
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  
#include <hpx/config.hpp>
9  
#include <hpx/exception.hpp>
10  
#include <hpx/runtime/actions/continuation.hpp>
11  
#include <hpx/runtime/agas/interface.hpp>
12  
#include <hpx/runtime/applier/applier.hpp>
13  
#include <hpx/runtime/components/pinned_ptr.hpp>
14  
#include <hpx/runtime/components/server/runtime_support.hpp>
15  
#include <hpx/runtime/naming/resolver_client.hpp>
16  
#include <hpx/runtime/parcelset/parcelhandler.hpp>
17  
#include <hpx/runtime/parcelset/parcel.hpp>
18  
#include <hpx/runtime/threads/threadmanager.hpp>
19  
#include <hpx/runtime/threads/thread_helpers.hpp>
20  
#include <hpx/util/register_locks.hpp>
21  
#include <hpx/util/thread_description.hpp>
22  
#if defined(HPX_HAVE_SECURITY)
23  
#include <hpx/components/security/capability.hpp>
24  
#include <hpx/components/security/certificate.hpp>
25  
#include <hpx/components/security/signed_type.hpp>
26  
#endif
27  
28  
#include <cstddef>
29  
#include <cstdint>
30  
#include <functional>
31  
#include <memory>
32  
#include <sstream>
33  
#include <utility>
34  
#include <vector>
35  
36  
namespace hpx { namespace applier
37  
{
38  
    ///////////////////////////////////////////////////////////////////////////
39  
    static inline threads::thread_result_type thread_function(
40  
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> func)
41  
    {
42  
        // execute the actual thread function
43  
        func(threads::wait_signaled);
44  
45  
        // Verify that there are no more registered locks for this
46  
        // OS-thread. This will throw if there are still any locks
47  
        // held.
48  
        util::force_error_on_lock();
49  
50  
        return threads::thread_result_type(threads::terminated, nullptr);
51  
    }
52  
53  
    static inline threads::thread_result_type thread_function_nullary(
54  
        util::unique_function_nonser<void()> func)
55  
    {
56  
        // execute the actual thread function
57  
        func();
58  
59  
        // Verify that there are no more registered locks for this
60  
        // OS-thread. This will throw if there are still any locks
61  
        // held.
62  
        util::force_error_on_lock();
63  
64  
        return threads::thread_result_type(threads::terminated, nullptr);
65  
    }
66  
67  
    ///////////////////////////////////////////////////////////////////////////
68  
    threads::thread_id_type register_thread_nullary(
69  
        util::unique_function_nonser<void()> && func,
70  
        util::thread_description const& desc,
71  
        threads::thread_state_enum state, bool run_now,
72  
        threads::thread_priority priority, std::size_t os_thread,
73  
        threads::thread_stacksize stacksize, error_code& ec)
74  
    {
75  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
76  
        if (nullptr == app)
77  
        {
78  
            HPX_THROWS_IF(ec, invalid_status,
79  
                "hpx::applier::register_thread_nullary",
80  
                "global applier object is not accessible");
81  
            return threads::invalid_thread_id;
82  
        }
83  
84  
        util::thread_description d =
85  
            desc ? desc : util::thread_description(func, "register_thread_nullary");
86  
87  
        threads::thread_init_data data(
88  
            util::bind(util::one_shot(&thread_function_nullary), std::move(func)),
89  
            d, 0, priority, os_thread, threads::get_stack_size(stacksize));
90  
91  
        threads::thread_id_type id = threads::invalid_thread_id;
92  
        app->get_thread_manager().register_thread(data, id, state, run_now, ec);
93  
        return id;
94  
    }
95  
96  
    threads::thread_id_type register_thread(
97  
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> && func,
98  
        util::thread_description const& desc, threads::thread_state_enum state,
99  
        bool run_now, threads::thread_priority priority, std::size_t os_thread,
100  
        threads::thread_stacksize stacksize, error_code& ec)
101  
    {
102  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
103  
        if (nullptr == app)
104  
        {
105  
            HPX_THROWS_IF(ec, invalid_status,
106  
                "hpx::applier::register_thread",
107  
                "global applier object is not accessible");
108  
            return threads::invalid_thread_id;
109  
        }
110  
111  
        util::thread_description d =
112  
            desc ? desc : util::thread_description(func, "register_thread");
113  
114  
        threads::thread_init_data data(
115  
            util::bind(util::one_shot(&thread_function), std::move(func)),
116  
            d, 0, priority, os_thread, threads::get_stack_size(stacksize));
117  
118  
        threads::thread_id_type id = threads::invalid_thread_id;
119  
        app->get_thread_manager().register_thread(data, id, state, run_now, ec);
120  
        return id;
121  
    }
122  
123  
    threads::thread_id_type register_thread_plain(
124  
        threads::thread_function_type && func,
125  
        util::thread_description const& desc, threads::thread_state_enum state,
126  
        bool run_now, threads::thread_priority priority, std::size_t os_thread,
127  
        threads::thread_stacksize stacksize, error_code& ec)
128  
    {
129  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
130  
        if (nullptr == app)
131  
        {
132  
            HPX_THROWS_IF(ec, invalid_status,
133  
                "hpx::applier::register_thread_plain",
134  
                "global applier object is not accessible");
135  
            return threads::invalid_thread_id;
136  
        }
137  
138  
        util::thread_description d =
139  
            desc ? desc : util::thread_description(func, "register_thread_plain");
140  
141  
        threads::thread_init_data data(std::move(func),
142  
            d, 0, priority, os_thread, threads::get_stack_size(stacksize));
143  
144  
        threads::thread_id_type id = threads::invalid_thread_id;
145  
        app->get_thread_manager().register_thread(data, id, state, run_now, ec);
146  
        return id;
147  
    }
148  
149  
    threads::thread_id_type register_thread_plain(
150  
        threads::thread_init_data& data, threads::thread_state_enum state,
151  
        bool run_now, error_code& ec)
152  
    {
153  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
154  
        if (nullptr == app)
155  
        {
156  
            HPX_THROWS_IF(ec, invalid_status,
157  
                "hpx::applier::register_thread_plain",
158  
                "global applier object is not accessible");
159  
            return threads::invalid_thread_id;
160  
        }
161  
162  
        threads::thread_id_type id = threads::invalid_thread_id;
163  
        app->get_thread_manager().register_thread(data, id, state, run_now, ec);
164  
        return id;
165  
    }
166  
167  
    ///////////////////////////////////////////////////////////////////////////
168  
    void register_work_nullary(
169  
        util::unique_function_nonser<void()> && func,
170  
        util::thread_description const& desc,
171  
        threads::thread_state_enum state, threads::thread_priority priority,
172  
        std::size_t os_thread, threads::thread_stacksize stacksize,
173  
        error_code& ec)
174  
    {
175  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
176  
        if (nullptr == app)
177  
        {
178  
            HPX_THROWS_IF(ec, invalid_status,
179  
                "hpx::applier::register_work_nullary",
180  
                "global applier object is not accessible");
181  
            return;
182  
        }
183  
184  
        util::thread_description d =
185  
            desc ? desc : util::thread_description(func, "register_thread_nullary");
186  
187  
        threads::thread_init_data data(
188  
            util::bind(util::one_shot(&thread_function_nullary), std::move(func)),
189  
            d, 0, priority, os_thread, threads::get_stack_size(stacksize));
190  
191  
        app->get_thread_manager().register_work(data, state, ec);
192  
    }
193  
194  
    void register_work(
195  
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> && func,
196  
        util::thread_description const& desc, threads::thread_state_enum state,
197  
        threads::thread_priority priority, std::size_t os_thread,
198  
        threads::thread_stacksize stacksize, error_code& ec)
199  
    {
200  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
201  
        if (nullptr == app)
202  
        {
203  
            HPX_THROWS_IF(ec, invalid_status,
204  
                "hpx::applier::register_work",
205  
                "global applier object is not accessible");
206  
            return;
207  
        }
208  
209  
        util::thread_description d =
210  
            desc ? desc : util::thread_description(func, "register_work");
211  
212  
        threads::thread_init_data data(
213  
            util::bind(util::one_shot(&thread_function), std::move(func)),
214  
            d, 0, priority, os_thread, threads::get_stack_size(stacksize));
215  
216  
        app->get_thread_manager().register_work(data, state, ec);
217  
    }
218  
219  
    void register_work_plain(
220  
        threads::thread_function_type && func,
221  
        util::thread_description const& desc, naming::address::address_type lva,
222  
        threads::thread_state_enum state, threads::thread_priority priority,
223  
        std::size_t os_thread, threads::thread_stacksize stacksize,
224  
        error_code& ec)
225  
    {
226  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
227  
        if (nullptr == app)
228  
        {
229  
            HPX_THROWS_IF(ec, invalid_status,
230  
                "hpx::applier::register_work_plain",
231  
                "global applier object is not accessible");
232  
            return;
233  
        }
234  
235  
        util::thread_description d =
236  
            desc ? desc : util::thread_description(func, "register_work_plain");
237  
238  
        threads::thread_init_data data(std::move(func),
239  
            d, lva, priority, os_thread, threads::get_stack_size(stacksize));
240  
241  
        app->get_thread_manager().register_work(data, state, ec);
242  
    }
243  
244  
    void register_work_plain(
245  
        threads::thread_init_data& data, threads::thread_state_enum state,
246  
        error_code& ec)
247  
    {
248  
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
249  
        if (nullptr == app)
250  
        {
251  
            HPX_THROWS_IF(ec, invalid_status,
252  
                "hpx::applier::register_work_plain",
253  
                "global applier object is not accessible");
254  
            return;
255  
        }
256  
257  
        app->get_thread_manager().register_work(data, state, ec);
258  
    }
259  
260  
    ///////////////////////////////////////////////////////////////////////////
261  
    hpx::util::thread_specific_ptr<applier*, applier::tls_tag> applier::applier_;
262  
263  
    applier::applier(parcelset::parcelhandler &ph, threads::threadmanager_base& tm)
264  
      : parcel_handler_(ph), thread_manager_(tm)
265  
#if defined(HPX_HAVE_SECURITY)
266  
      , verify_capabilities_(false)
267  
#endif
268  
    {}
269  
270  
    void applier::initialize(std::uint64_t rts, std::uint64_t mem)
271  
    {
272  
        naming::resolver_client & agas_client = get_agas_client();
273  
        runtime_support_id_ = naming::id_type(
274  
            agas_client.get_local_locality().get_msb(),
275  
            rts, naming::id_type::unmanaged);
276  
        memory_id_ = naming::id_type(
277  
            agas_client.get_local_locality().get_msb(),
278  
            mem, naming::id_type::unmanaged);
279  
    }
280  
281  
    naming::resolver_client& applier::get_agas_client()
282  
    {
283  
        return hpx::naming::get_agas_client();
284  
    }
285  
286  
    parcelset::parcelhandler& applier::get_parcel_handler()
287  
    {
288  
        return parcel_handler_;
289  
    }
290  
291  
    threads::threadmanager_base& applier::get_thread_manager()
292  
    {
293  
        return thread_manager_;
294  
    }
295  
296  
    naming::gid_type const& applier::get_raw_locality(error_code& ec) const
297  
    {
298  
        return hpx::naming::get_agas_client().get_local_locality(ec);
299  
    }
300  
301  
    std::uint32_t applier::get_locality_id(error_code& ec) const
302  
    {
303  
        return naming::get_locality_id_from_gid(get_raw_locality(ec));
304  
    }
305  
306  
    bool applier::get_raw_remote_localities(
307  
        std::vector<naming::gid_type>& prefixes,
308  
        components::component_type type, error_code& ec) const
309  
    {
310  
        return parcel_handler_.get_raw_remote_localities(prefixes, type, ec);
311  
    }
312  
313  
    bool applier::get_remote_localities(std::vector<naming::id_type>& prefixes,
314  
        components::component_type type, error_code& ec) const
315  
    {
316  
        std::vector<naming::gid_type> raw_prefixes;
317  
        if (!parcel_handler_.get_raw_remote_localities(raw_prefixes, type, ec))
318  
            return false;
319  
320  
        for (naming::gid_type& gid : raw_prefixes)
321  
            prefixes.push_back(naming::id_type(gid, naming::id_type::unmanaged));
322  
323  
        return true;
324  
    }
325  
326  
    bool applier::get_raw_localities(std::vector<naming::gid_type>& prefixes,
327  
        components::component_type type) const
328  
    {
329  
        return parcel_handler_.get_raw_localities(prefixes, type);
330  
    }
331  
332  
    bool applier::get_localities(std::vector<naming::id_type>& prefixes,
333  
        error_code& ec) const
334  
    {
335  
        std::vector<naming::gid_type> raw_prefixes;
336  
        if (!parcel_handler_.get_raw_localities(raw_prefixes,
337  
            components::component_invalid, ec))
338  
            return false;
339  
340  
        for (naming::gid_type& gid : raw_prefixes)
341  
            prefixes.push_back(naming::id_type(gid, naming::id_type::unmanaged));
342  
343  
        return true;
344  
    }
345  
346  
    bool applier::get_localities(std::vector<naming::id_type>& prefixes,
347  
        components::component_type type, error_code& ec) const
348  
    {
349  
        std::vector<naming::gid_type> raw_prefixes;
350  
        if (!parcel_handler_.get_raw_localities(raw_prefixes, type, ec))
351  
            return false;
352  
353  
        for (naming::gid_type& gid : raw_prefixes)
354  
            prefixes.push_back(naming::id_type(gid, naming::id_type::unmanaged));
355  
356  
        return true;
357  
    }
358  
359  
    void applier::init_tss()
360  
    {
361  
        if (nullptr == applier::applier_.get())
362  
            applier::applier_.reset(new applier* (this));
363  
    }
364  
365  
    void applier::deinit_tss()
366  
    {
367  
        applier::applier_.reset();
368  
    }
369  
370  
    applier& get_applier()
371  
    {
372  
        // should have been initialized
373  
        HPX_ASSERT(nullptr != applier::applier_.get());
374  
        return **applier::applier_;
375  
    }
376  
377  
    applier* get_applier_ptr()
378  
    {
379  
        applier** appl = applier::applier_.get();
380  
        return appl ? *appl : nullptr;
381  
    }
382  
383  
    // The function \a get_locality_id returns the id of this locality
384  
    std::uint32_t get_locality_id(error_code& ec) //-V659
385  
    {
386  
        applier** appl = applier::applier_.get();
387  
        return appl ? (*appl)->get_locality_id(ec) : naming::invalid_locality_id;
388  
    }
389  
}}
390  
391  

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