• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #846

05 Dec 2022 11:16PM UTC coverage: 86.482% (+0.8%) from 85.664%
#846

push

StellarBot
Merge #6093

6093: Replace boost::string_ref with std::string_view r=hkaiser a=hkaiser

Working towards #5497 and #3440

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

14 of 14 new or added lines in 6 files covered. (100.0%)

172759 of 199764 relevant lines covered (86.48%)

1842530.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.88
/libs/full/parcelset/src/parcel.cpp
1
//  Copyright (c) 2007-2021 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
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

10
#if defined(HPX_HAVE_NETWORKING)
11
#include <hpx/assert.hpp>
12
#include <hpx/modules/datastructures.hpp>
13
#include <hpx/modules/format.hpp>
14
#include <hpx/modules/itt_notify.hpp>
15
#include <hpx/modules/runtime_local.hpp>
16
#include <hpx/modules/serialization.hpp>
17
#include <hpx/modules/threading_base.hpp>
18
#include <hpx/modules/timing.hpp>
19

20
#include <hpx/actions/transfer_action.hpp>
21
#include <hpx/actions_base/detail/action_factory.hpp>
22
#include <hpx/components_base/agas_interface.hpp>
23
#include <hpx/components_base/component_type.hpp>
24
#include <hpx/naming/detail/preprocess_gid_types.hpp>
25
#include <hpx/parcelset/parcel.hpp>
26
#include <hpx/parcelset/parcelhandler.hpp>
27
#include <hpx/parcelset_base/parcel_interface.hpp>
28

29
#include <cstddef>
30
#include <cstdint>
31
#include <memory>
32
#include <string>
33
#include <type_traits>
34
#include <utility>
35

36
///////////////////////////////////////////////////////////////////////////////
37
namespace hpx::parcelset::detail {
38

39
    parcel_data::parcel_data()
475,840✔
40
      : source_id_(naming::invalid_gid)
475,839✔
41
      , dest_(naming::invalid_gid)
475,839✔
42
#if defined(HPX_HAVE_PARCEL_PROFILING)
43
      , start_time_(0)
44
      , creation_time_(chrono::high_resolution_timer::now())
45

46
#endif
47
      , has_continuation_(false)
475,839✔
48
    {
49
    }
475,839✔
50

51
    parcel_data::parcel_data(
470,937✔
52
        naming::gid_type&& dest, naming::address&& addr, bool has_continuation)
53
      : source_id_(naming::invalid_gid)
470,937✔
54
      , dest_(HPX_MOVE(dest))
470,937✔
55
      , addr_(HPX_MOVE(addr))
470,937✔
56
#if defined(HPX_HAVE_PARCEL_PROFILING)
57
      , start_time_(0)
58
      , creation_time_(chrono::high_resolution_timer::now())
59
#endif
60
      , has_continuation_(has_continuation)
470,937✔
61
    {
62
    }
470,937✔
63

64
    parcel_data::parcel_data(parcel_data&& rhs) noexcept
65
      : source_id_(HPX_MOVE(rhs.source_id_))
66
      , dest_(HPX_MOVE(rhs.dest_))
67
      , addr_(HPX_MOVE(rhs.addr_))
68
#if defined(HPX_HAVE_PARCEL_PROFILING)
69
      , parcel_id_(HPX_MOVE(rhs.parcel_id_))
70
      , start_time_(rhs.start_time_)
71
      , creation_time_(rhs.creation_time_)
72
#endif
73
      , has_continuation_(rhs.has_continuation_)
74
    {
75
        rhs.source_id_ = naming::invalid_gid;
76
        rhs.dest_ = naming::invalid_gid;
77
        rhs.addr_ = naming::address();
78

79
#if defined(HPX_HAVE_PARCEL_PROFILING)
80
        rhs.parcel_id_ = naming::invalid_gid;
81
        rhs.start_time_ = 0;
82
        rhs.creation_time_ = 0;
83
#endif
84
    }
85

86
    parcel_data& parcel_data::operator=(parcel_data&& rhs) noexcept
×
87
    {
88
        source_id_ = HPX_MOVE(rhs.source_id_);
×
89
        dest_ = HPX_MOVE(rhs.dest_);
×
90
        addr_ = HPX_MOVE(rhs.addr_);
×
91
#if defined(HPX_HAVE_PARCEL_PROFILING)
92
        parcel_id_ = HPX_MOVE(rhs.parcel_id_);
93
        start_time_ = rhs.start_time_;
94
        creation_time_ = rhs.creation_time_;
95
#endif
96
        has_continuation_ = rhs.has_continuation_;
×
97

98
        rhs.source_id_ = naming::invalid_gid;
×
99
        rhs.dest_ = naming::invalid_gid;
×
100
        rhs.addr_ = naming::address();
×
101
#if defined(HPX_HAVE_PARCEL_PROFILING)
102
        rhs.parcel_id_ = naming::invalid_gid;
103
        rhs.start_time_ = 0;
104
        rhs.creation_time_ = 0;
105
#endif
106
        return *this;
×
107
    }
108

109
    void parcel_data::serialize(serialization::input_archive& ar, unsigned)
×
110
    {
111
        ar >> source_id_;
×
112
        ar >> dest_;
×
113
        ar >> addr_;
×
114

115
#if defined(HPX_HAVE_PARCEL_PROFILING)
116
        ar >> parcel_id_;
117
        ar >> start_time_;
118
        ar >> creation_time_;
119
#endif
120

121
        ar >> has_continuation_;
×
122
    }
×
123

124
    void parcel_data::serialize(serialization::output_archive& ar, unsigned)
×
125
    {
126
        ar << source_id_;
×
127
        ar << dest_;
×
128
        ar << addr_;
×
129

130
#if defined(HPX_HAVE_PARCEL_PROFILING)
131
        ar << parcel_id_;
132
        ar << start_time_;
133
        ar << creation_time_;
134
#endif
135

136
        ar << has_continuation_;
×
137
    }
×
138

139
    ///////////////////////////////////////////////////////////////////////////
140
#if defined(HPX_DEBUG)
141
    bool parcel::is_valid() const
489,424✔
142
    {
143
        // empty parcels are always valid
144
#if defined(HPX_HAVE_PARCEL_PROFILING)
145
        if (0.0 == data_.creation_time_)    //-V550
146
            return true;
147
#endif
148

149
        // verify target destination
150
        if (data_.dest_ && data_.addr_.locality_)
489,424✔
151
        {
152
            // if we have a destination we need an action as well
153
            if (!action_)
462,763✔
154
            {
155
                return false;
×
156
            }
157
        }
462,763✔
158

159
        // verify that the action targets the correct type
160
        if (action_ && data_.addr_.type_ != components::component_invalid)
489,425✔
161
        {
162
            int type = action_->get_component_type();
477,792✔
163
            if (!components::types_are_compatible(type, data_.addr_.type_))
477,792✔
164
            {
165
                return false;
×
166
            }
167
        }
477,792✔
168

169
        return true;
489,426✔
170
    }
489,426✔
171
#else
172
    // Only used in debug mode.
173
    bool parcel::is_valid() const
174
    {
175
        return true;
176
    }
177
#endif
178

179
    parcel::parcel()
475,845✔
180
      : data_()
475,836✔
181
      , action_()
475,839✔
182
      , size_(0)
475,839✔
183
      , num_chunks_(0)
475,839✔
184
    {
951,690✔
185
    }
475,836✔
186

187
    parcel::~parcel() = default;
1,893,594✔
188

189
    parcel::parcel(naming::gid_type&& dest, naming::address&& addr,
941,874✔
190
        std::unique_ptr<actions::base_action> act)
191
      : data_(HPX_MOVE(dest), HPX_MOVE(addr), act->has_continuation())
470,937✔
192
      , action_(HPX_MOVE(act))
470,937✔
193
      , size_(0)
470,937✔
194
      , num_chunks_(0)
470,937✔
195
    {
941,874✔
196
    }
470,937✔
197

198
    void parcel::reset()
×
199
    {
200
        data_ = detail::parcel_data();
×
201
        action_.reset();
×
202
    }
×
203

204
    char const* parcel::get_action_name() const
323✔
205
    {
206
        return action_->get_action_name();
323✔
207
    }
208

209
    int parcel::get_component_type() const
320✔
210
    {
211
        return action_->get_component_type();
320✔
212
    }
213

214
    int parcel::get_action_type() const
320✔
215
    {
216
        return static_cast<int>(action_->get_action_type());
320✔
217
    }
218

219
    hpx::id_type parcel::source_id() const
482,238✔
220
    {
221
        return hpx::id_type(
482,238✔
222
            data_.source_id_, hpx::id_type::management_type::unmanaged);
482,238✔
223
    }
224

225
    void parcel::set_source_id(hpx::id_type const& source_id)
470,656✔
226
    {
227
        if (source_id != hpx::invalid_id)
470,654✔
228
        {
229
            data_.source_id_ = source_id.get_gid();
470,654✔
230
        }
470,654✔
231
    }
470,654✔
232

233
    void parcel::set_destination_id(naming::gid_type&& dest)
×
234
    {
235
        data_.dest_ = dest;
×
236
        HPX_ASSERT(is_valid());
×
237
    }
×
238

239
    naming::gid_type const& parcel::destination() const
489,425✔
240
    {
241
        HPX_ASSERT(is_valid());
489,425✔
242
        return data_.dest_;
489,426✔
243
    }
244

245
    naming::address const& parcel::addr() const
950,538✔
246
    {
247
        return data_.addr_;
950,540✔
248
    }
249

250
    naming::address& parcel::addr()
481,931✔
251
    {
252
        return data_.addr_;
481,931✔
253
    }
254

255
    std::uint32_t parcel::destination_locality_id() const
×
256
    {
257
        return naming::get_locality_id_from_gid(destination_locality());
×
258
    }
259

260
    naming::gid_type const& parcel::destination_locality() const
950,548✔
261
    {
262
        return addr().locality_;
950,548✔
263
    }
264

265
    double parcel::start_time() const
320✔
266
    {
267
#if defined(HPX_HAVE_PARCEL_PROFILING)
268
        return data_.start_time_;
269
#else
270
        return 0.0;
320✔
271
#endif
272
    }
273

274
    void parcel::set_start_time(double time)
×
275
    {
276
#if defined(HPX_HAVE_PARCEL_PROFILING)
277
        data_.start_time_ = time;
278
#else
279
        HPX_UNUSED(time);
×
280
#endif
281
    }
×
282

283
    double parcel::creation_time() const
×
284
    {
285
#if defined(HPX_HAVE_PARCEL_PROFILING)
286
        return data_.creation_time_;
287
#else
288
        return 0.0;
×
289
#endif
290
    }
291

292
    threads::thread_priority parcel::get_thread_priority() const
320✔
293
    {
294
        return action_->get_thread_priority();
320✔
295
    }
296

297
    threads::thread_stacksize parcel::get_thread_stacksize() const
320✔
298
    {
299
        return action_->get_thread_stacksize();
320✔
300
    }
301

302
    std::uint32_t parcel::get_parent_locality_id() const
320✔
303
    {
304
        return action_->get_parent_locality_id();
320✔
305
    }
306

307
    threads::thread_id_type parcel::get_parent_thread_id() const
320✔
308
    {
309
        return action_->get_parent_thread_id();
320✔
310
    }
311

312
    std::uint64_t parcel::get_parent_thread_phase() const
320✔
313
    {
314
        return action_->get_parent_thread_phase();
320✔
315
    }
316

317
#if defined(HPX_HAVE_PARCEL_PROFILING)
318
    naming::gid_type const& parcel::parcel_id() const
319
    {
320
        return data_.parcel_id_;
321
    }
322

323
    naming::gid_type& parcel::parcel_id()
324
    {
325
        return data_.parcel_id_;
326
    }
327
#endif
328

329
#if defined(HPX_HAVE_NETWORKING)
330
    serialization::binary_filter* parcel::get_serialization_filter() const
455,787✔
331
    {
332
        hpx::optional<parcelset::parcel> p = action_->get_embedded_parcel();
455,787✔
333
        if (!p)
455,787✔
334
        {
335
            return action_->get_serialization_filter();
448,379✔
336
        }
337
        return p->get_serialization_filter();
7,408✔
338
    }
455,787✔
339

340
    policies::message_handler* parcel::get_message_handler(
472,386✔
341
        locality const& loc) const
342
    {
343
        hpx::optional<parcelset::parcel> p = action_->get_embedded_parcel();
472,387✔
344
        if (!p)
472,387✔
345
        {
346
            return action_->get_message_handler(loc);
465,019✔
347
        }
348
        return p->get_message_handler(loc);
7,368✔
349
    }
472,387✔
350
#endif
351

352
    bool parcel::does_termination_detection() const
474,401✔
353
    {
354
        return action_ ? action_->does_termination_detection() : false;
474,401✔
355
    }
356

357
    parcel::split_gids_type parcel::move_split_gids() const
467,212✔
358
    {
359
        split_gids_type gids;
467,212✔
360
        std::swap(gids, split_gids_);
467,212✔
361
        return gids;
467,212✔
362
    }
467,212✔
363

364
    void parcel::set_split_gids(parcel::split_gids_type&& split_gids)
10,713✔
365
    {
366
        HPX_ASSERT(split_gids_.empty());
10,713✔
367
        split_gids_ = HPX_MOVE(split_gids);
10,713✔
368
    }
10,713✔
369

370
    std::size_t parcel::num_chunks() const
×
371
    {
372
        return num_chunks_;
×
373
    }
374

375
    std::size_t& parcel::num_chunks()
934,821✔
376
    {
377
        return num_chunks_;
934,821✔
378
    }
379

380
    std::size_t parcel::size() const
×
381
    {
382
        return size_;
×
383
    }
384

385
    std::size_t& parcel::size()
934,895✔
386
    {
387
        return size_;
934,895✔
388
    }
389

390
    std::pair<naming::address_type, naming::component_type>
391
    parcel::determine_lva()
482,783✔
392
    {
393
        int comptype = action_->get_component_type();
482,796✔
394

395
        // decode the local virtual address of the parcel
396
        naming::address::address_type lva = data_.addr_.address_;
482,796✔
397

398
        // by convention, a zero address references either the local
399
        // runtime support component or one of the AGAS components
400
        if (nullptr == lva)
482,796✔
401
        {
402
            switch (comptype)
57,181✔
403
            {
404
            case components::component_runtime_support:
405
                lva = agas::get_runtime_support_lva();
5,111✔
406
                break;
5,111✔
407

408
            case components::component_agas_primary_namespace:
409
                lva = agas::get_primary_ns_lva();
18,775✔
410
                break;
18,775✔
411

412
            case components::component_agas_symbol_namespace:
413
                lva = agas::get_symbol_ns_lva();
17,337✔
414
                break;
17,337✔
415

416
            case components::component_plain_function:
417
                break;
15,956✔
418

419
            default:
420
                HPX_ASSERT(false);
×
421
            }
×
422
        }
57,178✔
423

424
        // make sure the component_type of the action matches the
425
        // component type in the destination address
426
        if (HPX_UNLIKELY(
482,788✔
427
                !components::types_are_compatible(data_.addr_.type_, comptype)))
428
        {
429
            HPX_THROW_EXCEPTION(bad_component_type, "parcel::determine_lva",
×
430
                " types are not compatible: destination_type({}) "
431
                "action_type({}) parcel ({})",
432
                data_.addr_.type_, comptype, *this);
433
        }
434

435
        return std::make_pair(lva, comptype);
482,785✔
436
    }
×
437

438
    bool parcel::load_schedule(serialization::input_archive& ar,
467,174✔
439
        std::size_t num_thread, bool& deferred_schedule)
440
    {
441
        load_data(ar);
467,174✔
442

443
        // make sure this parcel destination matches the proper locality
444
        HPX_ASSERT(destination_locality() == data_.addr_.locality_);
467,174✔
445

446
        std::pair<naming::address_type, naming::component_type> p =
447
            determine_lva();
467,177✔
448

449
        // make sure the target has not been migrated away
450
        auto r = action_->was_object_migrated(data_.dest_, p.first);
467,177✔
451
        if (r.first)
467,177✔
452
        {
453
            // If the object was migrated, just load the action and return.
454
            action_->load(ar);
×
455
            return true;
×
456
        }
457

458
        // continuation support, this is handled in the transfer action
459
        action_->load_schedule(ar, HPX_MOVE(data_.dest_), p.first, p.second,
934,354✔
460
            num_thread, deferred_schedule);
467,210✔
461

462
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
463
        static util::itt::event parcel_recv("recv_parcel");
464
        util::itt::event_tick(parcel_recv);
465
#endif
466

467
#if defined(HPX_HAVE_APEX) && defined(HPX_HAVE_PARCEL_PROFILING)
468
        // tell APEX about the received parcel
469
        util::external_timer::recv(data_.parcel_id_.get_lsb(), size_,
470
            naming::get_locality_id_from_gid(data_.source_id_),
471
            reinterpret_cast<std::uint64_t>(
472
                action_->get_parent_thread_id().get()));
473
#endif
474

475
        return false;
467,210✔
476
    }
467,210✔
477

478
    bool parcel::schedule_action(std::size_t num_thread)
15,623✔
479
    {
480
        // make sure this parcel destination matches the proper locality
481
        HPX_ASSERT(destination_locality() == data_.addr_.locality_);
15,623✔
482

483
        std::pair<naming::address_type, naming::component_type> p =
484
            determine_lva();
15,621✔
485

486
        // make sure the target has not been migrated away
487
        auto r = action_->was_object_migrated(data_.dest_, p.first);
15,621✔
488
        if (r.first)
15,621✔
489
        {
490
            // If the object was migrated, just route.
491
            return true;
×
492
        }
493

494
        // dispatch action, register work item either with or without
495
        // continuation support, this is handled in the transfer action
496
        action_->schedule_thread(
31,242✔
497
            HPX_MOVE(data_.dest_), p.first, p.second, num_thread);
15,623✔
498
        return false;
15,623✔
499
    }
15,623✔
500

501
    void parcel::load_data(serialization::input_archive& ar)
475,830✔
502
    {
503
        using hpx::actions::detail::action_registry;
504
        ar >> data_;
475,844✔
505

506
        std::uint32_t id;
507
        ar >> id;
475,844✔
508

509
#if !defined(HPX_DEBUG)
510
        action_.reset(action_registry::create(id, data_.has_continuation_));
511
#else
512
        std::string name;
475,844✔
513
        ar >> name;
475,844✔
514
        action_.reset(
475,844✔
515
            action_registry::create(id, data_.has_continuation_, &name));
475,847✔
516
#endif
517
    }
475,847✔
518

519
    void parcel::load(serialization::input_archive& ar, unsigned)
8,656✔
520
    {
521
        load_data(ar);
8,656✔
522
        action_->load(ar);
8,656✔
523
    }
8,656✔
524

525
    void parcel::save_data(serialization::output_archive& ar) const
968,549✔
526
    {
527
        using hpx::serialization::access;
528
        ar << data_;
968,551✔
529

530
        std::uint32_t const id = action_->get_action_id();
968,551✔
531
        ar << id;
968,551✔
532

533
#if defined(HPX_DEBUG)
534
        std::string const name(action_->get_action_name());
968,549✔
535
        ar << name;
968,558✔
536
#endif
537
    }
968,558✔
538

539
    void parcel::save(serialization::output_archive& ar, unsigned) const
968,549✔
540
    {
541
        save_data(ar);
968,549✔
542
        action_->save(ar);
968,549✔
543
    }
968,549✔
544

545
    std::ostream& operator<<(std::ostream& os, parcel const& p)
×
546
    {
547
        return hpx::util::format_to(
×
548
            os, "({}:{}:{})", p.destination(), p.addr(), p.get_action_name());
×
549
    }
550
}    // namespace hpx::parcelset::detail
551

552
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc