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

STEllAR-GROUP / hpx / #853

19 Dec 2022 01:01AM UTC coverage: 86.287% (+0.4%) from 85.912%
#853

push

StellarBot
Merge #6109

6109: Modernize serialization module r=hkaiser a=hkaiser

- flyby separate serialization of Boost types

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

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

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

173939 of 201582 relevant lines covered (86.29%)

1931657.12 hits per line

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

61.59
/libs/full/agas_base/src/server/primary_namespace_server.cpp
1
//  Copyright (c) 2011 Bryce Adelstein-Lelbach
2
//  Copyright (c) 2012-2021 Hartmut Kaiser
3
//  Copyright (c) 2016 Thomas Heller
4
//
5
//  SPDX-License-Identifier: BSL-1.0
6
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
7
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8

9
#include <hpx/config.hpp>
10
#include <hpx/agas_base/server/primary_namespace.hpp>
11
#include <hpx/assert.hpp>
12
#include <hpx/async_distributed/continuation.hpp>
13
#include <hpx/async_distributed/detail/post.hpp>
14
#include <hpx/components_base/agas_interface.hpp>
15
#include <hpx/format.hpp>
16
#include <hpx/lock_registration/detail/register_locks.hpp>
17
#include <hpx/modules/async_distributed.hpp>
18
#include <hpx/modules/errors.hpp>
19
#include <hpx/modules/logging.hpp>
20
#include <hpx/thread_support/assert_owns_lock.hpp>
21
#include <hpx/timing/scoped_timer.hpp>
22
#include <hpx/util/get_and_reset_value.hpp>
23
#include <hpx/util/insert_checked.hpp>
24

25
#include <atomic>
26
#include <cstddef>
27
#include <cstdint>
28
#include <list>
29
#include <memory>
30
#include <mutex>
31
#include <sstream>
32
#include <string>
33
#include <utility>
34
#include <vector>
35

36
namespace hpx { namespace agas {
37

38
    naming::gid_type bootstrap_primary_namespace_gid()
×
39
    {
40
        return naming::gid_type(agas::primary_ns_msb, agas::primary_ns_lsb);
×
41
    }
42

43
    hpx::id_type bootstrap_primary_namespace_id()
×
44
    {
45
        return hpx::id_type(agas::primary_ns_msb, agas::primary_ns_lsb,
×
46
            hpx::id_type::management_type::unmanaged);
47
    }
48
}}    // namespace hpx::agas
49

50
namespace hpx { namespace agas { namespace server {
51

52
    void primary_namespace::register_server_instance(
593✔
53
        char const* servicename, std::uint32_t locality_id, error_code& ec)
54
    {
55
        // set locality_id for this component
56
        if (locality_id == naming::invalid_locality_id)
593✔
57
            locality_id = 0;    // if not given, we're on the root
×
58

59
        this->base_type::set_locality_id(locality_id);
593✔
60

61
        // now register this AGAS instance with AGAS :-P
62
        instance_name_ = agas::service_name;
593✔
63
        instance_name_ += servicename;
593✔
64
        instance_name_ += agas::server::primary_namespace_service_name;
593✔
65

66
        // register a gid (not the id) to avoid AGAS holding a reference to this
67
        // component
68
        agas::register_name(
593✔
69
            launch::sync, instance_name_, get_unmanaged_id().get_gid(), ec);
593✔
70
    }
593✔
71

72
    void primary_namespace::unregister_server_instance(error_code& ec)
×
73
    {
74
        agas::unregister_name(launch::sync, instance_name_, ec);
×
75
        this->base_type::finalize();
×
76
    }
×
77

78
    void primary_namespace::finalize()
×
79
    {
80
        if (!instance_name_.empty())
×
81
        {
82
            error_code ec(throwmode::lightweight);
×
83
            agas::unregister_name(launch::sync, instance_name_, ec);
×
84
        }
×
85
    }
×
86

87
    // start migration of the given object
88
    std::pair<hpx::id_type, naming::address> primary_namespace::begin_migration(
2,736✔
89
        naming::gid_type id)
90
    {
91
        util::scoped_timer<std::atomic<std::int64_t>> update(
2,736✔
92
            counter_data_.begin_migration_.time_,
2,736✔
93
            counter_data_.begin_migration_.enabled_);
2,736✔
94
        counter_data_.increment_begin_migration_count();
2,736✔
95
        using hpx::get;
96

97
        std::unique_lock<mutex_type> l(mutex_);
2,736✔
98

99
        wait_for_migration_locked(l, id, hpx::throws);
2,736✔
100
        resolved_type r = resolve_gid_locked(l, id, hpx::throws);
2,736✔
101
        if (get<0>(r) == naming::invalid_gid)
2,736✔
102
        {
103
            l.unlock();
×
104

105
            LAGAS_(info).format("primary_namespace::begin_migration, gid({1}), "
×
106
                                "response(no_success)",
107
                id);
108

109
            return std::make_pair(hpx::invalid_id, naming::address());
×
110
        }
111

112
        migration_table_type::iterator it = migrating_objects_.find(id);
2,736✔
113
        if (it == migrating_objects_.end())
2,736✔
114
        {
115
            std::pair<migration_table_type::iterator, bool> p =
116
                migrating_objects_.emplace(std::piecewise_construct,
5,472✔
117
                    std::forward_as_tuple(id), std::forward_as_tuple());
2,736✔
118
            HPX_ASSERT(p.second);
2,736✔
119
            it = p.first;
2,736✔
120
        }
2,736✔
121
        else
122
        {
123
            HPX_ASSERT(hpx::get<0>(it->second) == false);
×
124
        }
125

126
        // flag this id as being migrated
127
        hpx::get<0>(it->second) = true;    //-V601
2,736✔
128

129
        gva const& g(hpx::get<1>(r));
2,736✔
130
        naming::address addr(g.prefix, g.type, g.lva());
2,736✔
131
        hpx::id_type loc(
2,736✔
132
            hpx::get<2>(r), hpx::id_type::management_type::unmanaged);
2,736✔
133
        return std::make_pair(loc, addr);
2,736✔
134
    }
2,736✔
135

136
    // migration of the given object is complete
137
    bool primary_namespace::end_migration(naming::gid_type const& id)
2,736✔
138
    {
139
        util::scoped_timer<std::atomic<std::int64_t>> update(
2,736✔
140
            counter_data_.end_migration_.time_,
2,736✔
141
            counter_data_.end_migration_.enabled_);
2,736✔
142
        counter_data_.increment_end_migration_count();
2,736✔
143

144
        std::unique_lock<mutex_type> l(mutex_);
2,736✔
145

146
        using hpx::get;
147

148
        migration_table_type::iterator it = migrating_objects_.find(id);
2,736✔
149
        if (it != migrating_objects_.end())
2,736✔
150
        {
151
            // flag this id as not being migrated anymore
152
            get<0>(it->second) = false;
2,736✔
153
            if (get<1>(it->second) != 0)
2,736✔
154
            {
155
                get<2>(it->second).notify_all(HPX_MOVE(l), hpx::throws);
1,472✔
156
            }
1,472✔
157
            else
158
            {
159
                migrating_objects_.erase(it);
1,264✔
160
            }
161
        }
2,736✔
162

163
        return true;
164
    }
2,736✔
165

166
    // wait if given object is currently being migrated
167
    void primary_namespace::wait_for_migration_locked(
29,493✔
168
        std::unique_lock<mutex_type>& l, naming::gid_type const& id,
169
        error_code& ec)
170
    {
171
        HPX_ASSERT_OWNS_LOCK(l);
29,493✔
172

173
        using hpx::get;
174

175
        migration_table_type::iterator it = migrating_objects_.find(id);
29,493✔
176
        if (it != migrating_objects_.end())
29,493✔
177
        {
178
            if (get<0>(it->second))
1,704✔
179
            {
180
                ++get<1>(it->second);
1,625✔
181

182
                get<2>(it->second).wait(l, ec);
1,625✔
183

184
                if (--get<1>(it->second) == 0)
1,625✔
185
                    migrating_objects_.erase(it);
1,472✔
186
            }
1,625✔
187
            else
188
            {
189
                if (get<1>(it->second) == 0)
79✔
190
                {
191
                    migrating_objects_.erase(it);
×
192
                }
×
193
            }
194
        }
1,704✔
195
    }
29,493✔
196

197
    bool primary_namespace::bind_gid(
7,296✔
198
        gva const& g, naming::gid_type id, naming::gid_type const& locality)
199
    {    // {{{ bind_gid implementation
200
        util::scoped_timer<std::atomic<std::int64_t>> update(
7,296✔
201
            counter_data_.bind_gid_.time_, counter_data_.bind_gid_.enabled_);
7,296✔
202
        counter_data_.increment_bind_gid_count();
7,296✔
203
        using hpx::get;
204

205
        naming::gid_type gid = id;
7,296✔
206
        naming::detail::strip_internal_bits_from_gid(id);
7,296✔
207

208
        std::unique_lock<mutex_type> l(mutex_);
7,296✔
209

210
        gva_table_type::iterator it = gvas_.lower_bound(id),
7,296✔
211
                                 begin = gvas_.begin(), end = gvas_.end();
7,296✔
212

213
        if (it != end)
7,296✔
214
        {
215
            // If we got an exact match, this is a request to update an existing
216
            // binding (e.g. move semantics).
217
            if (it->first == id)
4,702✔
218
            {
219
                // non-migratable gids can't be rebound
220
                if (naming::refers_to_local_lva(gid) &&
1,526✔
221
                    !naming::refers_to_virtual_memory(gid))
×
222
                {
223
                    l.unlock();
×
224

225
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
226
                        "primary_namespace::bind_gid",
227
                        "cannot rebind gids for non-migratable objects");
228

229
                    return false;
230
                }
231

232
                gva& gaddr = it->second.first;
1,526✔
233
                naming::gid_type& loc = it->second.second;
1,526✔
234

235
                // Check for count mismatch (we can't change block sizes of
236
                // existing bindings).
237
                if (HPX_UNLIKELY(gaddr.count != g.count))
1,526✔
238
                {
239
                    // REVIEW: Is this the right error code to use?
240
                    l.unlock();
×
241

242
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
243
                        "primary_namespace::bind_gid",
244
                        "cannot change block size of existing binding");
245
                }
246

247
                if (HPX_UNLIKELY(components::component_invalid == g.type))
1,526✔
248
                {
249
                    l.unlock();
×
250

251
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
252
                        "primary_namespace::bind_gid",
253
                        "attempt to update a GVA with an invalid type, "
254
                        "gid({1}), gva({2}), locality({3})",
255
                        id, g, locality);
256
                }
257

258
                if (HPX_UNLIKELY(!locality))
1,526✔
259
                {
260
                    l.unlock();
×
261

262
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
263
                        "primary_namespace::bind_gid",
264
                        "attempt to update a GVA with an invalid "
265
                        "locality id, "
266
                        "gid({1}), gva({2}), locality({3})",
267
                        id, g, locality);
268
                }
269

270
                // Store the new endpoint and offset
271
                gaddr.prefix = g.prefix;
1,526✔
272
                gaddr.type = g.type;
1,526✔
273
                gaddr.lva(g.lva());
1,526✔
274
                gaddr.offset = g.offset;
1,526✔
275
                loc = locality;
1,526✔
276

277
                l.unlock();
1,526✔
278

279
                LAGAS_(info).format(
1,526✔
280
                    "primary_namespace::bind_gid, gid({1}), gva({2}), "
×
281
                    "locality({3}), response(repeated_request)",
282
                    id, g, locality);
×
283

284
                return false;
1,526✔
285
            }
286

287
            // We're about to decrement the iterator it - first, we
288
            // check that it's safe to do this.
289
            else if (it != begin)
3,176✔
290
            {
291
                --it;
3,034✔
292

293
                // Check that a previous range doesn't cover the new id.
294
                if (HPX_UNLIKELY((it->first + it->second.first.count) > id))
3,034✔
295
                {
296
                    // REVIEW: Is this the right error code to use?
297
                    l.unlock();
×
298

299
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
300
                        "primary_namespace::bind_gid",
301
                        "the new GID is contained in an existing range");
302
                }
303
            }
3,034✔
304
        }
3,176✔
305

306
        else if (HPX_LIKELY(!gvas_.empty()))
2,594✔
307
        {
308
            --it;
2,001✔
309

310
            // Check that a previous range doesn't cover the new id.
311
            if ((it->first + it->second.first.count) > id)
2,001✔
312
            {
313
                // REVIEW: Is this the right error code to use?
314
                l.unlock();
×
315

316
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
317
                    "primary_namespace::bind_gid",
318
                    "the new GID is contained in an existing range");
319
            }
320
        }
2,001✔
321

322
        // non-migratable gids don't need to be bound
323
        if (naming::refers_to_local_lva(gid) &&
5,770✔
324
            !naming::refers_to_virtual_memory(gid))
876✔
325
        {
326
            LAGAS_(info).format(
×
327
                "primary_namespace::bind_gid, gid({1}), gva({2}), "
×
328
                "locality({3})",
329
                gid, g, locality);
×
330

331
            return true;
×
332
        }
333

334
        naming::gid_type upper_bound(id + (g.count - 1));
5,770✔
335

336
        if (HPX_UNLIKELY(id.get_msb() != upper_bound.get_msb()))
5,770✔
337
        {
338
            l.unlock();
×
339

340
            HPX_THROW_EXCEPTION(hpx::error::internal_server_error,
×
341
                "primary_namespace::bind_gid",
342
                "MSBs of lower and upper range bound do not match");
343
        }
344

345
        if (HPX_UNLIKELY(components::component_invalid == g.type))
5,770✔
346
        {
347
            l.unlock();
×
348

349
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
350
                "primary_namespace::bind_gid",
351
                "attempt to insert a GVA with an invalid type, "
352
                "gid({1}), gva({2}), locality({3})",
353
                id, g, locality);
354
        }
355

356
        // Insert a GID -> GVA entry into the GVA table.
357
        if (HPX_UNLIKELY(!util::insert_checked(
5,770✔
358
                gvas_.insert(std::make_pair(id, std::make_pair(g, locality))))))
359
        {
360
            l.unlock();
×
361

362
            HPX_THROW_EXCEPTION(hpx::error::lock_error,
×
363
                "primary_namespace::bind_gid",
364
                "GVA table insertion failed due to a locking error or "
365
                "memory corruption, gid({1}), gva({2}), locality({3})",
366
                id, g, locality);
367
        }
368

369
        l.unlock();
5,770✔
370

371
        LAGAS_(info).format(
5,770✔
372
            "primary_namespace::bind_gid, gid({1}), gva({2}), locality({3})",
×
373
            id, g, locality);
×
374

375
        return true;
5,770✔
376
    }    // }}}
7,296✔
377

378
    primary_namespace::resolved_type primary_namespace::resolve_gid(
118,259✔
379
        naming::gid_type const& id)
380
    {    // {{{ resolve_gid implementation
381
        util::scoped_timer<std::atomic<std::int64_t>> update(
118,259✔
382
            counter_data_.resolve_gid_.time_,
118,259✔
383
            counter_data_.resolve_gid_.enabled_);
118,259✔
384
        counter_data_.increment_resolve_gid_count();
118,259✔
385
        using hpx::get;
386

387
        resolved_type r;
118,258✔
388

389
        {
390
            std::unique_lock<mutex_type> l(mutex_);
118,261✔
391

392
            // wait for any migration to be completed
393
            if (naming::detail::is_migratable(id))
118,261✔
394
            {
395
                wait_for_migration_locked(l, id, hpx::throws);
21,476✔
396
            }
21,476✔
397

398
            // now, resolve the id
399
            r = resolve_gid_locked(l, id, hpx::throws);
118,261✔
400
        }
118,261✔
401

402
        if (get<0>(r) == naming::invalid_gid)
118,261✔
403
        {
404
            LAGAS_(info).format("primary_namespace::resolve_gid, gid({1}), "
9,379✔
405
                                "response(no_success)",
406
                id);
×
407

408
            return resolved_type(
9,379✔
409
                naming::invalid_gid, gva(), naming::invalid_gid);
9,379✔
410
        }
411

412
        LAGAS_(info).format(
108,882✔
413
            "primary_namespace::resolve_gid, gid({1}), base({2}), gva({3}), "
×
414
            "locality_id({4})",
415
            id, get<0>(r), get<1>(r), get<2>(r));
×
416

417
        return r;
108,882✔
418
    }    // }}}
118,261✔
419

420
    hpx::id_type primary_namespace::colocate(naming::gid_type const& id)
11,500✔
421
    {
422
        return hpx::id_type(hpx::get<2>(resolve_gid(id)),
11,500✔
423
            hpx::id_type::management_type::unmanaged);
424
    }
425

426
    naming::address primary_namespace::unbind_gid(
20,826✔
427
        std::uint64_t count, naming::gid_type id)
428
    {    // {{{ unbind_gid implementation
429
        util::scoped_timer<std::atomic<std::int64_t>> update(
20,826✔
430
            counter_data_.unbind_gid_.time_,
20,826✔
431
            counter_data_.unbind_gid_.enabled_);
20,826✔
432
        counter_data_.increment_unbind_gid_count();
20,826✔
433

434
        naming::detail::strip_internal_bits_from_gid(id);
20,827✔
435

436
        std::unique_lock<mutex_type> l(mutex_);
20,827✔
437

438
        gva_table_type::iterator it = gvas_.find(id), end = gvas_.end();
20,827✔
439

440
        if (it != end)
20,827✔
441
        {
442
            if (HPX_UNLIKELY(it->second.first.count != count))
2,463✔
443
            {
444
                l.unlock();
×
445

446
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
447
                    "primary_namespace::unbind_gid", "block sizes must match");
448
            }
449

450
            gva_table_data_type data = it->second;
2,463✔
451

452
            gvas_.erase(it);
2,463✔
453

454
            l.unlock();
2,463✔
455
            LAGAS_(info).format(
2,463✔
456
                "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
457
                "gva({3}), locality_id({4})",
458
                id, count, data.first, data.second);
×
459

460
            gva g = data.first;
2,463✔
461
            return naming::address(g.prefix, g.type, g.lva());
2,463✔
462
        }
463

464
        // non-migratable gids are not bound
465
        if (naming::refers_to_local_lva(id) &&
18,364✔
466
            !naming::refers_to_virtual_memory(id))
17,631✔
467
        {
468
            naming::gid_type locality = naming::get_locality_from_gid(id);
17,180✔
469
            gva g(locality,
17,180✔
470
                naming::detail::get_component_type_from_gid(id.get_msb()), 0,
17,180✔
471
                id.get_lsb());
17,180✔
472

473
            LAGAS_(info).format(
17,180✔
474
                "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
475
                "gva({3}), locality({4})",
476
                id, count, g, g.prefix);
×
477

478
            return naming::address(g.prefix, g.type, g.lva());
17,180✔
479
        }
480

481
        l.unlock();
1,184✔
482

483
        LAGAS_(info).format(
1,184✔
484
            "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
485
            "response(no_success)",
486
            id, count);
487

488
        return naming::address();
1,184✔
489
    }    // }}}
20,827✔
490

491
    std::int64_t primary_namespace::increment_credit(
7,914✔
492
        std::int64_t credits, naming::gid_type lower, naming::gid_type upper)
493
    {    // increment_credit implementation
494
        util::scoped_timer<std::atomic<std::int64_t>> update(
7,914✔
495
            counter_data_.increment_credit_.time_,
7,914✔
496
            counter_data_.increment_credit_.enabled_);
7,914✔
497
        counter_data_.increment_increment_credit_count();
7,914✔
498

499
        naming::detail::strip_internal_bits_from_gid(lower);
7,914✔
500
        naming::detail::strip_internal_bits_from_gid(upper);
7,914✔
501

502
        if (lower == upper)
7,914✔
503
            ++upper;
7,914✔
504

505
        // Increment.
506
        if (credits > 0)
7,914✔
507
        {
508
            increment(lower, upper, credits, hpx::throws);
7,914✔
509
            return 0;
510
        }
511
        else
512
        {
513
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
514
                "primary_namespace::increment_credit",
515
                "invalid credit count of {1}", credits);
516
            return 0;
517
        }
518

519
        return credits;
520
    }
7,914✔
521

522
    std::vector<std::int64_t> primary_namespace::decrement_credit(
20,315✔
523
        std::vector<hpx::tuple<std::int64_t, naming::gid_type,
524
            naming::gid_type>> const& requests)
525
    {    // decrement_credit implementation
526
        util::scoped_timer<std::atomic<std::int64_t>> update(
20,315✔
527
            counter_data_.decrement_credit_.time_,
20,315✔
528
            counter_data_.decrement_credit_.enabled_);
20,315✔
529
        counter_data_.increment_decrement_credit_count();
20,315✔
530

531
        std::vector<int64_t> res_credits;
20,315✔
532
        res_credits.reserve(requests.size());
20,315✔
533

534
        for (auto& req : requests)
62,637✔
535
        {
536
            std::int64_t credits = hpx::get<0>(req);
42,319✔
537
            naming::gid_type lower = hpx::get<1>(req);
42,319✔
538
            naming::gid_type upper = hpx::get<1>(req);
42,319✔
539

540
            naming::detail::strip_internal_bits_from_gid(lower);
42,319✔
541
            naming::detail::strip_internal_bits_from_gid(upper);
42,319✔
542

543
            if (lower == upper)
42,319✔
544
                ++upper;
42,320✔
545

546
            // Decrement.
547
            if (credits < 0)
42,320✔
548
            {
549
                free_entry_list_type free_list;
42,323✔
550
                decrement_sweep(free_list, lower, upper, -credits, hpx::throws);
42,323✔
551

552
                free_components_sync(free_list, lower, upper, hpx::throws);
42,321✔
553
            }
42,321✔
554
            else
555
            {
556
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
557
                    "primary_namespace::decrement_credit",
558
                    "invalid credit count of {1}", credits);
559
            }
560
            res_credits.push_back(credits);
42,322✔
561
        }
562

563
        return res_credits;
20,314✔
564
    }
20,314✔
565

566
    std::pair<naming::gid_type, naming::gid_type> primary_namespace::allocate(
3,160✔
567
        std::uint64_t count)
568
    {    // {{{ allocate implementation
569
        util::scoped_timer<std::atomic<std::int64_t>> update(
3,160✔
570
            counter_data_.allocate_.time_, counter_data_.allocate_.enabled_);
3,160✔
571
        counter_data_.increment_allocate_count();
3,160✔
572

573
        std::uint64_t const real_count = (count) ? (count - 1) : (0);
3,160✔
574

575
        // Just return the prefix
576
        // REVIEW: Should this be an error?
577
        if (0 == count)
3,160✔
578
        {
579
            LAGAS_(info).format(
×
580
                "primary_namespace::allocate, count({1}), lower({1}), "
×
581
                "upper({3}), prefix({4}), response(repeated_request)",
582
                count, next_id_, next_id_,
×
583
                naming::get_locality_id_from_gid(next_id_));
×
584

585
            return std::make_pair(next_id_, next_id_);
×
586
        }
587

588
        // Compute the new allocation.
589
        naming::gid_type lower(next_id_ + 1);
3,160✔
590
        naming::gid_type upper(lower + real_count);
3,160✔
591

592
        // Check for overflow.
593
        if (upper.get_msb() != lower.get_msb())
3,160✔
594
        {
595
            // Check for address space exhaustion (we currently use 86 bits of
596
            // the gid for the actual id)
597
            if (HPX_UNLIKELY(
×
598
                    (lower.get_msb() & naming::gid_type::virtual_memory_mask) ==
599
                    naming::gid_type::virtual_memory_mask))
600
            {
601
                HPX_THROW_EXCEPTION(hpx::error::internal_server_error,
×
602
                    "locality_namespace::allocate",
603
                    "primary namespace has been exhausted");
604
            }
605

606
            // Otherwise, correct
607
            lower = naming::gid_type(upper.get_msb(), nullptr);
×
608
            upper = lower + real_count;
×
609
        }
×
610

611
        // Store the new upper bound.
612
        next_id_ = upper;
3,160✔
613

614
        // Set the initial credit count.
615
        naming::detail::set_credit_for_gid(
3,160✔
616
            lower, std::int64_t(HPX_GLOBALCREDIT_INITIAL));
617
        naming::detail::set_credit_for_gid(
3,160✔
618
            upper, std::int64_t(HPX_GLOBALCREDIT_INITIAL));
619

620
        LAGAS_(info).format(
3,160✔
621
            "primary_namespace::allocate, count({1}), lower({2}), upper({3}), "
×
622
            "response(success)",
623
            count, lower, upper);
624

625
        return std::make_pair(lower, upper);
3,160✔
626
    }    // }}}
3,160✔
627

628
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
629
    void primary_namespace::dump_refcnt_matches(
630
        refcnt_table_type::iterator lower_it,
631
        refcnt_table_type::iterator upper_it, naming::gid_type const& lower,
632
        naming::gid_type const& upper, std::unique_lock<mutex_type>& l,
633
        const char* func_name)
634
    {    // dump_refcnt_matches implementation
635
        HPX_ASSERT(l.owns_lock());
636

637
        if (lower_it == refcnts_.end() && upper_it == refcnts_.end())
638
            // We got nothing, bail - our caller is probably about to throw.
639
            return;
640

641
        std::stringstream ss;
642
        hpx::util::format_to(ss,
643
            "{1}, dumping server-side refcnt table matches, lower({2}), "
644
            "upper({3}):",
645
            func_name, lower, upper);
646

647
        for (/**/; lower_it != upper_it; ++lower_it)
648
        {
649
            // The [server] tag is in there to make it easier to filter
650
            // through the logs.
651
            hpx::util::format_to(ss, "\n  [server] lower({1}), credits({2})",
652
                lower_it->first, lower_it->second);
653
        }
654

655
        LAGAS_(debug) << ss.str();
656
    }    // dump_refcnt_matches implementation
657
#endif
658

659
    ///////////////////////////////////////////////////////////////////////////////
660
    void primary_namespace::increment(naming::gid_type const& lower,
7,914✔
661
        naming::gid_type const& upper, std::int64_t& credits, error_code& ec)
662
    {    // {{{ increment implementation
663
        std::unique_lock<mutex_type> l(mutex_);
7,914✔
664

665
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
666
        if (LAGAS_ENABLED(debug))
667
        {
668
            typedef refcnt_table_type::iterator iterator;
669

670
            // Find the mappings that we're about to touch.
671
            refcnt_table_type::iterator lower_it = refcnts_.find(lower);
672
            refcnt_table_type::iterator upper_it;
673
            if (lower != upper)
674
            {
675
                upper_it = refcnts_.find(upper);
676
            }
677
            else
678
            {
679
                upper_it = lower_it;
680
                ++upper_it;
681
            }
682

683
            dump_refcnt_matches(lower_it, upper_it, lower, upper, l,
684
                "primary_namespace::increment");
685
        }
686
#endif
687

688
        // TODO: Whine loudly if a reference count overflows. We reserve ~0 for
689
        // internal bookkeeping in the decrement algorithm, so the maximum global
690
        // reference count is 2^64 - 2. The maximum number of credits a single GID
691
        // can hold, however, is limited to 2^32 - 1.
692

693
        // The third parameter we pass here is the default data to use in case the
694
        // key is not mapped. We don't insert GIDs into the refcnt table when we
695
        // allocate/bind them, so if a GID is not in the refcnt table, we know that
696
        // it's global reference count is the initial global reference count.
697

698
        for (naming::gid_type raw = lower; raw != upper; ++raw)
15,828✔
699
        {
700
            refcnt_table_type::iterator it = refcnts_.find(raw);
7,914✔
701
            if (it == refcnts_.end())
7,914✔
702
            {
703
                std::int64_t count =
1,367✔
704
                    std::int64_t(HPX_GLOBALCREDIT_INITIAL) + credits;
1,367✔
705

706
                std::pair<refcnt_table_type::iterator, bool> p =
707
                    refcnts_.insert(refcnt_table_type::value_type(raw, count));
1,367✔
708
                if (!p.second)
1,367✔
709
                {
710
                    l.unlock();
×
711

712
                    HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
713
                        "primary_namespace::increment",
714
                        "couldn't create entry in reference count table, "
715
                        "raw({1}), ref-count({2})",
716
                        raw, count);
717
                    return;
×
718
                }
719

720
                it = p.first;
1,367✔
721
            }
1,367✔
722
            else
723
            {
724
                it->second += credits;
6,547✔
725
            }
726

727
            LAGAS_(info).format(
7,914✔
728
                "primary_namespace::increment, raw({1}), refcnt({2})", lower,
×
729
                it->second);
×
730
        }
7,914✔
731

732
        if (&ec != &throws)
7,914✔
733
            ec = make_success_code();
×
734
    }    // }}}
7,914✔
735

736
    ///////////////////////////////////////////////////////////////////////////////
737
    void primary_namespace::resolve_free_list(std::unique_lock<mutex_type>& l,
42,323✔
738
        std::list<refcnt_table_type::iterator> const& free_list,
739
        free_entry_list_type& free_entry_list,
740
        naming::gid_type const& /* lower */,
741
        naming::gid_type const& /* upper */, error_code& ec)
742
    {
743
        HPX_ASSERT_OWNS_LOCK(l);
42,323✔
744

745
        using hpx::get;
746

747
        typedef refcnt_table_type::iterator iterator;
748

749
        for (iterator const& it : free_list)
59,634✔
750
        {
751
            typedef refcnt_table_type::key_type key_type;
752

753
            // The mapping's key space.
754
            key_type gid = it->first;
17,311✔
755

756
            if (naming::detail::is_migratable(gid))
17,311✔
757
            {
758
                // wait for any migration to be completed
759
                wait_for_migration_locked(l, gid, ec);
×
760
            }
×
761

762
            // Resolve the query GID.
763
            resolved_type r = resolve_gid_locked(l, gid, ec);
17,311✔
764
            if (ec)
17,311✔
765
                return;
×
766

767
            naming::gid_type& raw = get<0>(r);
17,311✔
768
            if (raw == naming::invalid_gid)
17,311✔
769
            {
770
                l.unlock();
×
771

772
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
773
                    "primary_namespace::resolve_free_list",
774
                    "primary_namespace::resolve_free_list, failed to resolve "
775
                    "gid, gid({1})",
776
                    gid);
777
                return;    // couldn't resolve this one
×
778
            }
779

780
            // Make sure the GVA is valid.
781
            gva& g = get<1>(r);
17,311✔
782

783
            // REVIEW: Should we do more to make sure the GVA is valid?
784
            if (HPX_UNLIKELY(components::component_invalid == g.type))
17,311✔
785
            {
786
                l.unlock();
×
787

788
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
789
                    "primary_namespace::resolve_free_list",
790
                    "encountered a GVA with an invalid type while performing a "
791
                    "decrement, gid({1}), gva({2})",
792
                    gid, g);
793
                return;
×
794
            }
795
            else if (HPX_UNLIKELY(0 == g.count))
17,311✔
796
            {
797
                l.unlock();
×
798

799
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
800
                    "primary_namespace::resolve_free_list",
801
                    "encountered a GVA with a count of zero while performing a "
802
                    "decrement, gid({1}), gva({2})",
803
                    gid, g);
804
                return;
×
805
            }
806

807
            LAGAS_(info).format(
17,311✔
808
                "primary_namespace::resolve_free_list, resolved match, "
×
809
                "gid({1}), gva({2})",
810
                gid, g);
×
811

812
            // Fully resolve the range.
813
            gva const resolved = g.resolve(gid, raw);
17,311✔
814

815
            // Add the information needed to destroy these components to the
816
            // free list.
817
            free_entry_list.push_back(free_entry(resolved, gid, get<2>(r)));
17,311✔
818

819
            // remove this entry from the refcnt table
820
            refcnts_.erase(it);
17,311✔
821
        }
822
    }
42,323✔
823

824
    ///////////////////////////////////////////////////////////////////////////////
825
    void primary_namespace::decrement_sweep(
42,322✔
826
        free_entry_list_type& free_entry_list, naming::gid_type const& lower,
827
        naming::gid_type const& upper, std::int64_t credits, error_code& ec)
828
    {    // {{{ decrement_sweep implementation
829
        LAGAS_(info).format(
42,322✔
830
            "primary_namespace::decrement_sweep, lower({1}), upper({2}), "
×
831
            "credits({3})",
832
            lower, upper, credits);
×
833

834
        free_entry_list.clear();
42,323✔
835

836
        {
837
            std::unique_lock<mutex_type> l(mutex_);
42,323✔
838

839
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
840
            if (LAGAS_ENABLED(debug))
841
            {
842
                typedef refcnt_table_type::iterator iterator;
843

844
                // Find the mappings that we just added or modified.
845
                refcnt_table_type::iterator lower_it = refcnts_.find(lower);
846
                refcnt_table_type::iterator upper_it;
847
                if (lower != upper)
848
                {
849
                    upper_it = refcnts_.find(upper);
850
                }
851
                else
852
                {
853
                    upper_it = lower_it;
854
                    ++upper_it;
855
                }
856

857
                dump_refcnt_matches(lower_it, upper_it, lower, upper, l,
858
                    "primary_namespace::decrement_sweep");
859
            }
860
#endif
861

862
            ///////////////////////////////////////////////////////////////////////
863
            // Apply the decrement across the entire key space (e.g. [lower, upper]).
864

865
            // The third parameter we pass here is the default data to use in case
866
            // the key is not mapped. We don't insert GIDs into the refcnt table
867
            // when we allocate/bind them, so if a GID is not in the refcnt table,
868
            // we know that it's global reference count is the initial global
869
            // reference count.
870

871
            std::list<refcnt_table_type::iterator> free_list;
42,323✔
872
            for (naming::gid_type raw = lower; raw != upper; ++raw)
84,643✔
873
            {
874
                refcnt_table_type::iterator it = refcnts_.find(raw);
42,323✔
875
                if (it == refcnts_.end())
42,323✔
876
                {
877
                    if (credits > std::int64_t(HPX_GLOBALCREDIT_INITIAL))
18,236✔
878
                    {
879
                        l.unlock();
×
880

881
                        HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
882
                            "primary_namespace::decrement_sweep",
883
                            "negative entry in reference count table, "
884
                            "raw({1}), refcount({2})",
885
                            raw,
886
                            std::int64_t(HPX_GLOBALCREDIT_INITIAL) - credits);
887
                        return;
×
888
                    }
889

890
                    std::int64_t count =
18,236✔
891
                        std::int64_t(HPX_GLOBALCREDIT_INITIAL) - credits;
18,236✔
892

893
                    std::pair<refcnt_table_type::iterator, bool> p =
894
                        refcnts_.insert(
18,236✔
895
                            refcnt_table_type::value_type(raw, count));
18,236✔
896
                    if (!p.second)
18,236✔
897
                    {
898
                        l.unlock();
×
899

900
                        HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
901
                            "primary_namespace::decrement_sweep",
902
                            "couldn't create entry in reference count table, "
903
                            "raw({1}), ref-count({2})",
904
                            raw, count);
905
                        return;
×
906
                    }
907

908
                    it = p.first;
18,236✔
909
                }
18,236✔
910
                else
911
                {
912
                    it->second -= credits;
24,087✔
913
                }
914

915
                // Sanity check.
916
                if (it->second < 0)
42,323✔
917
                {
918
                    l.unlock();
×
919

920
                    HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
921
                        "primary_namespace::decrement_sweep",
922
                        "negative entry in reference count table, raw({1}), "
923
                        "refcount({2})",
924
                        raw, it->second);
925
                    return;
×
926
                }
927

928
                // this objects needs to be deleted
929
                if (it->second == 0)
42,323✔
930
                    free_list.push_back(it);
17,311✔
931
            }
42,323✔
932

933
            // Resolve the objects which have to be deleted.
934
            resolve_free_list(l, free_list, free_entry_list, lower, upper, ec);
42,323✔
935

936
        }    // Unlock the mutex.
42,323✔
937

938
        if (&ec != &throws)
42,323✔
939
            ec = make_success_code();
×
940
    }
42,323✔
941

942
    ///////////////////////////////////////////////////////////////////////////////
943
    void primary_namespace::free_components_sync(
42,323✔
944
        free_entry_list_type& free_list, naming::gid_type const& lower,
945
        naming::gid_type const& upper, error_code& ec)
946
    {    // {{{ free_components_sync implementation
947
        using hpx::get;
948

949
        ///////////////////////////////////////////////////////////////////////////
950
        // Delete the objects on the free list.
951
        for (free_entry const& e : free_list)
59,634✔
952
        {
953
            // Bail if we're in late shutdown and non-local.
954
            if (HPX_UNLIKELY(!threads::threadmanager_is(hpx::state::running)) &&
17,311✔
955
                e.locality_ != locality_)
×
956
            {
957
                LAGAS_(info).format(
×
958
                    "primary_namespace::free_components_sync, cancelling free "
×
959
                    "operation because the threadmanager is down, lower({1}), "
960
                    "upper({2}), base({3}), gva({4}), locality({5})",
961
                    lower, upper, e.gid_, e.gva_, e.locality_);
×
962
                continue;
×
963
            }
964

965
            LAGAS_(info).format(
17,311✔
966
                "primary_namespace::free_components_sync, freeing component, "
×
967
                "lower({1}), upper({2}), base({3}), gva({4}), locality({5})",
968
                lower, upper, e.gid_, e.gva_, e.locality_);
×
969

970
            // Destroy the component.
971
            HPX_ASSERT(e.locality_ == e.gva_.prefix);
17,311✔
972
            naming::address addr(e.locality_, e.gva_.type, e.gva_.lva());
17,311✔
973
            if (e.locality_ == locality_)
17,311✔
974
            {
975
                auto deleter = components::deleter(e.gva_.type);
17,295✔
976
                if (deleter == nullptr)
17,295✔
977
                {
978
                    HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
979
                        "primary_namespace::free_components_sync",
980
                        "Attempting to delete object of unknown component "
981
                        "type: " +
982
                            std::to_string(e.gva_.type));
983
                    return;
×
984
                }
985
                deleter(e.gid_, HPX_MOVE(addr));
17,295✔
986
            }
17,295✔
987
            else
988
            {
989
                agas::destroy_component(e.gid_, addr);
16✔
990
            }
991
        }
992

993
        if (&ec != &throws)
42,322✔
994
            ec = make_success_code();
×
995
    }    // }}}
42,322✔
996

997
    primary_namespace::resolved_type primary_namespace::resolve_gid_locked(
144,671✔
998
        std::unique_lock<mutex_type>& l, naming::gid_type const& gid,
999
        error_code& ec)
1000
    {    // {{{ resolve_gid_locked implementation
1001
        HPX_ASSERT_OWNS_LOCK(l);
144,671✔
1002

1003
        // handle (non-migratable) components located on this locality first
1004
        if (naming::refers_to_local_lva(gid) &&
144,671✔
1005
            !naming::refers_to_virtual_memory(gid))
26,663✔
1006
        {
1007
            naming::gid_type locality = naming::get_locality_from_gid(gid);
26,616✔
1008
            gva addr(locality,
26,616✔
1009
                naming::detail::get_component_type_from_gid(gid.get_msb()), 1,
26,616✔
1010
                gid.get_lsb());
26,616✔
1011
            return resolved_type(gid, addr, locality);
26,616✔
1012
        }
1013

1014
        // parameters
1015
        naming::gid_type id = gid;
118,055✔
1016
        naming::detail::strip_internal_bits_from_gid(id);
118,055✔
1017

1018
        gva_table_type::const_iterator it = gvas_.lower_bound(id),
118,055✔
1019
                                       begin = gvas_.begin(), end = gvas_.end();
118,055✔
1020

1021
        if (it != end)
118,055✔
1022
        {
1023
            // Check for exact match
1024
            if (it->first == id)
87,645✔
1025
            {
1026
                if (&ec != &throws)
24,197✔
1027
                    ec = make_success_code();
×
1028

1029
                gva_table_data_type const& data = it->second;
24,197✔
1030
                return resolved_type(it->first, data.first, data.second);
24,197✔
1031
            }
1032

1033
            // We need to decrement the iterator, first we check that it's safe
1034
            // to do this.
1035
            else if (it != begin)
63,448✔
1036
            {
1037
                --it;
61,080✔
1038

1039
                // Found the GID in a range
1040
                gva_table_data_type const& data = it->second;
61,080✔
1041
                if ((it->first + data.first.count) > id)
61,080✔
1042
                {
1043
                    if (HPX_UNLIKELY(id.get_msb() != it->first.get_msb()))
61,078✔
1044
                    {
1045
                        l.unlock();
×
1046

1047
                        HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
1048
                            "primary_namespace::resolve_gid_locked",
1049
                            "MSBs of lower and upper range bound do not "
1050
                            "match");
1051
                        return resolved_type(
×
1052
                            naming::invalid_gid, gva(), naming::invalid_gid);
×
1053
                    }
1054

1055
                    if (&ec != &throws)
61,078✔
1056
                        ec = make_success_code();
×
1057

1058
                    return resolved_type(it->first, data.first, data.second);
61,078✔
1059
                }
1060
            }
2✔
1061
        }
2,370✔
1062

1063
        else if (HPX_LIKELY(!gvas_.empty()))
30,410✔
1064
        {
1065
            --it;
30,410✔
1066

1067
            // Found the GID in a range
1068
            gva_table_data_type const& data = it->second;
30,410✔
1069
            if ((it->first + data.first.count) > id)
30,410✔
1070
            {
1071
                if (HPX_UNLIKELY(id.get_msb() != it->first.get_msb()))
23,401✔
1072
                {
1073
                    l.unlock();
×
1074

1075
                    HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
1076
                        "primary_namespace::resolve_gid_locked",
1077
                        "MSBs of lower and upper range bound do not match");
1078
                    return resolved_type(
×
1079
                        naming::invalid_gid, gva(), naming::invalid_gid);
×
1080
                }
1081

1082
                if (&ec != &throws)
23,401✔
1083
                    ec = make_success_code();
×
1084

1085
                return resolved_type(it->first, data.first, data.second);
23,401✔
1086
            }
1087
        }
7,009✔
1088

1089
        if (&ec != &throws)
9,379✔
1090
            ec = make_success_code();
×
1091

1092
        return resolved_type(naming::invalid_gid, gva(), naming::invalid_gid);
9,379✔
1093
    }    // }}}
144,671✔
1094

1095
    // access current counter values
1096
    std::int64_t primary_namespace::counter_data::get_bind_gid_count(bool reset)
×
1097
    {
1098
        return util::get_and_reset_value(bind_gid_.count_, reset);
×
1099
    }
1100

1101
    std::int64_t primary_namespace::counter_data::get_resolve_gid_count(
×
1102
        bool reset)
1103
    {
1104
        return util::get_and_reset_value(resolve_gid_.count_, reset);
×
1105
    }
1106

1107
    std::int64_t primary_namespace::counter_data::get_unbind_gid_count(
×
1108
        bool reset)
1109
    {
1110
        return util::get_and_reset_value(unbind_gid_.count_, reset);
×
1111
    }
1112

1113
    std::int64_t primary_namespace::counter_data::get_increment_credit_count(
×
1114
        bool reset)
1115
    {
1116
        return util::get_and_reset_value(increment_credit_.count_, reset);
×
1117
    }
1118

1119
    std::int64_t primary_namespace::counter_data::get_decrement_credit_count(
×
1120
        bool reset)
1121
    {
1122
        return util::get_and_reset_value(decrement_credit_.count_, reset);
×
1123
    }
1124

1125
    std::int64_t primary_namespace::counter_data::get_allocate_count(bool reset)
×
1126
    {
1127
        return util::get_and_reset_value(allocate_.count_, reset);
×
1128
    }
1129

1130
    std::int64_t primary_namespace::counter_data::get_begin_migration_count(
×
1131
        bool reset)
1132
    {
1133
        return util::get_and_reset_value(begin_migration_.count_, reset);
×
1134
    }
1135

1136
    std::int64_t primary_namespace::counter_data::get_end_migration_count(
×
1137
        bool reset)
1138
    {
1139
        return util::get_and_reset_value(end_migration_.count_, reset);
×
1140
    }
1141

1142
    std::int64_t primary_namespace::counter_data::get_overall_count(bool reset)
×
1143
    {
1144
        return
×
1145
#if defined(HPX_HAVE_NETWORKING)
1146
            util::get_and_reset_value(route_.count_, reset) +
×
1147
#endif
1148
            util::get_and_reset_value(bind_gid_.count_, reset) +
×
1149
            util::get_and_reset_value(resolve_gid_.count_, reset) +
×
1150
            util::get_and_reset_value(unbind_gid_.count_, reset) +
×
1151
            util::get_and_reset_value(increment_credit_.count_, reset) +
×
1152
            util::get_and_reset_value(decrement_credit_.count_, reset) +
×
1153
            util::get_and_reset_value(allocate_.count_, reset) +
×
1154
            util::get_and_reset_value(begin_migration_.count_, reset) +
×
1155
            util::get_and_reset_value(end_migration_.count_, reset);
×
1156
    }
1157

1158
    // access execution time counters
1159
    std::int64_t primary_namespace::counter_data::get_bind_gid_time(bool reset)
×
1160
    {
1161
        return util::get_and_reset_value(bind_gid_.time_, reset);
×
1162
    }
1163

1164
    std::int64_t primary_namespace::counter_data::get_resolve_gid_time(
×
1165
        bool reset)
1166
    {
1167
        return util::get_and_reset_value(resolve_gid_.time_, reset);
×
1168
    }
1169

1170
    std::int64_t primary_namespace::counter_data::get_unbind_gid_time(
×
1171
        bool reset)
1172
    {
1173
        return util::get_and_reset_value(unbind_gid_.time_, reset);
×
1174
    }
1175

1176
    std::int64_t primary_namespace::counter_data::get_increment_credit_time(
×
1177
        bool reset)
1178
    {
1179
        return util::get_and_reset_value(increment_credit_.time_, reset);
×
1180
    }
1181

1182
    std::int64_t primary_namespace::counter_data::get_decrement_credit_time(
×
1183
        bool reset)
1184
    {
1185
        return util::get_and_reset_value(decrement_credit_.time_, reset);
×
1186
    }
1187

1188
    std::int64_t primary_namespace::counter_data::get_allocate_time(bool reset)
×
1189
    {
1190
        return util::get_and_reset_value(allocate_.time_, reset);
×
1191
    }
1192

1193
    std::int64_t primary_namespace::counter_data::get_begin_migration_time(
×
1194
        bool reset)
1195
    {
1196
        return util::get_and_reset_value(begin_migration_.time_, reset);
×
1197
    }
1198

1199
    std::int64_t primary_namespace::counter_data::get_end_migration_time(
×
1200
        bool reset)
1201
    {
1202
        return util::get_and_reset_value(end_migration_.time_, reset);
×
1203
    }
1204

1205
    std::int64_t primary_namespace::counter_data::get_overall_time(bool reset)
×
1206
    {
1207
        return
×
1208
#if defined(HPX_HAVE_NETWORKING)
1209
            util::get_and_reset_value(route_.time_, reset) +
×
1210
#endif
1211
            util::get_and_reset_value(bind_gid_.time_, reset) +
×
1212
            util::get_and_reset_value(resolve_gid_.time_, reset) +
×
1213
            util::get_and_reset_value(unbind_gid_.time_, reset) +
×
1214
            util::get_and_reset_value(increment_credit_.time_, reset) +
×
1215
            util::get_and_reset_value(decrement_credit_.time_, reset) +
×
1216
            util::get_and_reset_value(allocate_.time_, reset) +
×
1217
            util::get_and_reset_value(begin_migration_.time_, reset) +
×
1218
            util::get_and_reset_value(end_migration_.time_, reset);
×
1219
    }
1220

1221
    void primary_namespace::counter_data::enable_all()
×
1222
    {
1223
#if defined(HPX_HAVE_NETWORKING)
1224
        route_.enabled_ = true;
×
1225
#endif
1226
        bind_gid_.enabled_ = true;
×
1227
        resolve_gid_.enabled_ = true;
×
1228
        unbind_gid_.enabled_ = true;
×
1229
        increment_credit_.enabled_ = true;
×
1230
        decrement_credit_.enabled_ = true;
×
1231
        allocate_.enabled_ = true;
×
1232
        begin_migration_.enabled_ = true;
×
1233
        end_migration_.enabled_ = true;
×
1234
    }
×
1235

1236
    // increment counter values
1237
    void primary_namespace::counter_data::increment_bind_gid_count()
7,296✔
1238
    {
1239
        if (bind_gid_.enabled_)
7,296✔
1240
        {
1241
            ++bind_gid_.count_;
×
1242
        }
×
1243
    }
7,296✔
1244

1245
    void primary_namespace::counter_data::increment_resolve_gid_count()
118,259✔
1246
    {
1247
        if (resolve_gid_.enabled_)
118,259✔
1248
        {
1249
            ++resolve_gid_.count_;
×
1250
        }
×
1251
    }
118,259✔
1252

1253
    void primary_namespace::counter_data::increment_unbind_gid_count()
20,826✔
1254
    {
1255
        if (unbind_gid_.enabled_)
20,826✔
1256
        {
1257
            ++unbind_gid_.count_;
×
1258
        }
×
1259
    }
20,826✔
1260

1261
    void primary_namespace::counter_data::increment_increment_credit_count()
7,914✔
1262
    {
1263
        if (increment_credit_.enabled_)
7,914✔
1264
        {
1265
            ++increment_credit_.count_;
×
1266
        }
×
1267
    }
7,914✔
1268

1269
    void primary_namespace::counter_data::increment_decrement_credit_count()
20,315✔
1270
    {
1271
        if (decrement_credit_.enabled_)
20,315✔
1272
        {
1273
            ++decrement_credit_.count_;
×
1274
        }
×
1275
    }
20,315✔
1276

1277
    void primary_namespace::counter_data::increment_allocate_count()
3,160✔
1278
    {
1279
        if (allocate_.enabled_)
3,160✔
1280
        {
1281
            ++allocate_.count_;
×
1282
        }
×
1283
    }
3,160✔
1284

1285
    void primary_namespace::counter_data::increment_begin_migration_count()
2,736✔
1286
    {
1287
        if (begin_migration_.enabled_)
2,736✔
1288
        {
1289
            ++begin_migration_.count_;
×
1290
        }
×
1291
    }
2,736✔
1292

1293
    void primary_namespace::counter_data::increment_end_migration_count()
2,736✔
1294
    {
1295
        if (end_migration_.enabled_)
2,736✔
1296
        {
1297
            ++end_migration_.count_;
×
1298
        }
×
1299
    }
2,736✔
1300

1301
#if defined(HPX_HAVE_NETWORKING)
1302
    std::int64_t primary_namespace::counter_data::get_route_count(bool reset)
×
1303
    {
1304
        return util::get_and_reset_value(route_.count_, reset);
×
1305
    }
1306

1307
    std::int64_t primary_namespace::counter_data::get_route_time(bool reset)
×
1308
    {
1309
        return util::get_and_reset_value(route_.time_, reset);
×
1310
    }
1311

1312
    void primary_namespace::counter_data::increment_route_count()
6,363✔
1313
    {
1314
        if (route_.enabled_)
6,363✔
1315
        {
1316
            ++route_.count_;
×
1317
        }
×
1318
    }
6,363✔
1319
#endif
1320

1321
}}}    // namespace hpx::agas::server
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