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

STEllAR-GROUP / hpx / #874

25 Jan 2023 02:55PM UTC coverage: 85.911% (+0.03%) from 85.883%
#874

push

StellarBot
Merge #6153

6153: Assign global ids to managed component instances that are locally resolvable r=hkaiser a=hkaiser

This will reduce contention while resolving global ids.

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

61 of 61 new or added lines in 5 files covered. (100.0%)

173513 of 201968 relevant lines covered (85.91%)

2065249.0 hits per line

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

60.18
/libs/full/agas_base/src/server/primary_namespace_server.cpp
1
//  Copyright (c) 2011 Bryce Adelstein-Lelbach
2
//  Copyright (c) 2012-2023 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::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::agas::server {
51

52
    void primary_namespace::register_server_instance(
594✔
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)
594✔
57
            locality_id = 0;    // if not given, we're on the root
×
58

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

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

66
        // register a gid (not the id) to avoid AGAS holding a reference to this
67
        // component
68
        agas::register_name(
594✔
69
            launch::sync, instance_name_, get_unmanaged_id().get_gid(), ec);
594✔
70
    }
594✔
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_non_local(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,449✔
156
            }
1,449✔
157
            else
158
            {
159
                migrating_objects_.erase(it);
1,287✔
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(
32,820✔
168
        std::unique_lock<mutex_type>& l, naming::gid_type const& id,
169
        error_code& ec)
170
    {
171
        HPX_ASSERT_OWNS_LOCK(l);
32,820✔
172

173
        using hpx::get;
174

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

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

184
                if (--get<1>(it->second) == 0)
1,560✔
185
                    migrating_objects_.erase(it);
1,449✔
186
            }
1,560✔
187
            else
188
            {
189
                if (get<1>(it->second) == 0)
135✔
190
                {
191
                    migrating_objects_.erase(it);
×
192
                }
×
193
            }
194
        }
1,695✔
195
    }
32,820✔
196

197
    bool primary_namespace::bind_gid(
4,558✔
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(
4,558✔
201
            counter_data_.bind_gid_.time_, counter_data_.bind_gid_.enabled_);
4,558✔
202
        counter_data_.increment_bind_gid_count();
4,558✔
203
        using hpx::get;
204

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

208
        std::unique_lock<mutex_type> l(mutex_);
4,558✔
209

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

213
        if (it != end)
4,558✔
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)
3,210✔
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)
1,684✔
290
            {
291
                --it;
1,543✔
292

293
                // Check that a previous range doesn't cover the new id.
294
                if (HPX_UNLIKELY((it->first + it->second.first.count) > id))
1,543✔
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
            }
1,543✔
304
        }
1,684✔
305

306
        else if (HPX_LIKELY(!gvas_.empty()))
1,348✔
307
        {
308
            --it;
754✔
309

310
            // Check that a previous range doesn't cover the new id.
311
            if ((it->first + it->second.first.count) > id)
754✔
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
        }
754✔
321

322
        // non-migratable gids don't need to be bound
323
        if (naming::refers_to_local_lva(gid) &&
3,032✔
324
            !naming::refers_to_virtual_memory(gid))
877✔
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));
3,032✔
335

336
        if (HPX_UNLIKELY(id.get_msb() != upper_bound.get_msb()))
3,032✔
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))
3,032✔
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(
3,032✔
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();
3,032✔
370

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

375
        return true;
3,032✔
376
    }    // }}}
4,558✔
377

378
    inline primary_namespace::resolved_type resolve_local_id(
44,545✔
379
        naming::gid_type const& id) noexcept
380
    {
381
        naming::gid_type locality = naming::get_locality_from_gid(id);
44,545✔
382
        gva addr(locality,
44,545✔
383
            naming::detail::get_component_type_from_gid(id.get_msb()), 1,
44,545✔
384
            id.get_lsb());
44,545✔
385
        return primary_namespace::resolved_type(id, addr, locality);
44,545✔
386
    }
387

388
    primary_namespace::resolved_type primary_namespace::resolve_gid(
54,309✔
389
        naming::gid_type const& id)
390
    {    // {{{ resolve_gid implementation
391
        util::scoped_timer<std::atomic<std::int64_t>> update(
54,309✔
392
            counter_data_.resolve_gid_.time_,
54,309✔
393
            counter_data_.resolve_gid_.enabled_);
54,309✔
394
        counter_data_.increment_resolve_gid_count();
54,309✔
395
        using hpx::get;
396

397
        resolved_type r;
54,309✔
398

399
        // handle (non-migratable) components located on this locality first
400
        if (naming::refers_to_local_lva(id) &&
54,309✔
401
            !naming::refers_to_virtual_memory(id))
27,324✔
402
        {
403
            r = resolve_local_id(id);
27,276✔
404
        }
27,276✔
405
        else
406
        {
407
            std::unique_lock<mutex_type> l(mutex_);
27,032✔
408

409
            // wait for any migration to be completed
410
            if (naming::detail::is_migratable(id))
27,032✔
411
            {
412
                wait_for_migration_locked(l, id, hpx::throws);
26,942✔
413
            }
26,942✔
414

415
            // now, resolve the id
416
            r = resolve_gid_locked_non_local(l, id, hpx::throws);
27,032✔
417
        }
27,032✔
418

419
        if (get<0>(r) == naming::invalid_gid)
54,308✔
420
        {
421
            LAGAS_(info).format("primary_namespace::resolve_gid, gid({1}), "
9,913✔
422
                                "response(no_success)",
423
                id);
×
424

425
            return resolved_type(
9,913✔
426
                naming::invalid_gid, gva(), naming::invalid_gid);
9,913✔
427
        }
428

429
        LAGAS_(info).format(
44,395✔
430
            "primary_namespace::resolve_gid, gid({1}), base({2}), gva({3}), "
×
431
            "locality_id({4})",
432
            id, get<0>(r), get<1>(r), get<2>(r));
×
433

434
        return r;
44,396✔
435
    }    // }}}
54,309✔
436

437
    hpx::id_type primary_namespace::colocate(naming::gid_type const& id)
11,484✔
438
    {
439
        return hpx::id_type(hpx::get<2>(resolve_gid(id)),
11,484✔
440
            hpx::id_type::management_type::unmanaged);
441
    }
442

443
    naming::address primary_namespace::unbind_gid(
20,824✔
444
        std::uint64_t count, naming::gid_type id)
445
    {    // {{{ unbind_gid implementation
446
        util::scoped_timer<std::atomic<std::int64_t>> update(
20,824✔
447
            counter_data_.unbind_gid_.time_,
20,824✔
448
            counter_data_.unbind_gid_.enabled_);
20,824✔
449
        counter_data_.increment_unbind_gid_count();
20,824✔
450

451
        naming::detail::strip_internal_bits_from_gid(id);
20,825✔
452

453
        std::unique_lock<mutex_type> l(mutex_);
20,825✔
454

455
        gva_table_type::iterator it = gvas_.find(id), end = gvas_.end();
20,825✔
456

457
        if (it != end)
20,825✔
458
        {
459
            if (HPX_UNLIKELY(it->second.first.count != count))
2,290✔
460
            {
461
                l.unlock();
×
462

463
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
464
                    "primary_namespace::unbind_gid", "block sizes must match");
465
            }
466

467
            gva_table_data_type data = it->second;
2,290✔
468

469
            gvas_.erase(it);
2,290✔
470

471
            l.unlock();
2,290✔
472
            LAGAS_(info).format(
2,290✔
473
                "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
474
                "gva({3}), locality_id({4})",
475
                id, count, data.first, data.second);
×
476

477
            gva g = data.first;
2,290✔
478
            return naming::address(g.prefix, g.type, g.lva());
2,290✔
479
        }
480

481
        // non-migratable gids are not bound
482
        if (naming::refers_to_local_lva(id) &&
18,535✔
483
            !naming::refers_to_virtual_memory(id))
17,801✔
484
        {
485
            naming::gid_type locality = naming::get_locality_from_gid(id);
17,349✔
486
            gva g(locality,
17,349✔
487
                naming::detail::get_component_type_from_gid(id.get_msb()), 0,
17,349✔
488
                id.get_lsb());
17,349✔
489

490
            LAGAS_(info).format(
17,349✔
491
                "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
492
                "gva({3}), locality({4})",
493
                id, count, g, g.prefix);
×
494

495
            return naming::address(g.prefix, g.type, g.lva());
17,349✔
496
        }
497

498
        l.unlock();
1,186✔
499

500
        LAGAS_(info).format(
1,186✔
501
            "primary_namespace::unbind_gid, gid({1}), count({2}), "
×
502
            "response(no_success)",
503
            id, count);
504

505
        return naming::address();
1,186✔
506
    }    // }}}
20,825✔
507

508
    std::int64_t primary_namespace::increment_credit(
8,047✔
509
        std::int64_t credits, naming::gid_type lower, naming::gid_type upper)
510
    {    // increment_credit implementation
511
        util::scoped_timer<std::atomic<std::int64_t>> update(
8,047✔
512
            counter_data_.increment_credit_.time_,
8,047✔
513
            counter_data_.increment_credit_.enabled_);
8,047✔
514
        counter_data_.increment_increment_credit_count();
8,047✔
515

516
        naming::detail::strip_internal_bits_from_gid(lower);
8,047✔
517
        naming::detail::strip_internal_bits_from_gid(upper);
8,047✔
518

519
        if (lower == upper)
8,047✔
520
            ++upper;
8,047✔
521

522
        // Increment.
523
        if (credits > 0)
8,047✔
524
        {
525
            increment(lower, upper, credits, hpx::throws);
8,047✔
526
            return 0;
527
        }
528
        else
529
        {
530
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
531
                "primary_namespace::increment_credit",
532
                "invalid credit count of {1}", credits);
533
            return 0;
534
        }
535

536
        return credits;
537
    }
8,047✔
538

539
    std::vector<std::int64_t> primary_namespace::decrement_credit(
19,111✔
540
        std::vector<hpx::tuple<std::int64_t, naming::gid_type,
541
            naming::gid_type>> const& requests)
542
    {    // decrement_credit implementation
543
        util::scoped_timer<std::atomic<std::int64_t>> update(
19,111✔
544
            counter_data_.decrement_credit_.time_,
19,111✔
545
            counter_data_.decrement_credit_.enabled_);
19,111✔
546
        counter_data_.increment_decrement_credit_count();
19,111✔
547

548
        std::vector<int64_t> res_credits;
19,111✔
549
        res_credits.reserve(requests.size());
19,111✔
550

551
        for (auto& req : requests)
61,167✔
552
        {
553
            std::int64_t credits = hpx::get<0>(req);
42,052✔
554
            naming::gid_type lower = hpx::get<1>(req);
42,052✔
555
            naming::gid_type upper = hpx::get<1>(req);
42,052✔
556

557
            naming::detail::strip_internal_bits_from_gid(lower);
42,052✔
558
            naming::detail::strip_internal_bits_from_gid(upper);
42,052✔
559

560
            if (lower == upper)
42,052✔
561
                ++upper;
42,053✔
562

563
            // Decrement.
564
            if (credits < 0)
42,054✔
565
            {
566
                free_entry_list_type free_list;
42,056✔
567
                decrement_sweep(free_list, lower, upper, -credits, hpx::throws);
42,056✔
568

569
                free_components_sync(free_list, lower, upper, hpx::throws);
42,055✔
570
            }
42,055✔
571
            else
572
            {
573
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
574
                    "primary_namespace::decrement_credit",
575
                    "invalid credit count of {1}", credits);
576
            }
577
            res_credits.push_back(credits);
42,056✔
578
        }
579

580
        return res_credits;
19,111✔
581
    }
19,111✔
582

583
    std::pair<naming::gid_type, naming::gid_type> primary_namespace::allocate(
594✔
584
        std::uint64_t count)
585
    {    // {{{ allocate implementation
586
        util::scoped_timer<std::atomic<std::int64_t>> update(
594✔
587
            counter_data_.allocate_.time_, counter_data_.allocate_.enabled_);
594✔
588
        counter_data_.increment_allocate_count();
594✔
589

590
        std::uint64_t const real_count = (count) ? (count - 1) : (0);
594✔
591

592
        // Just return the prefix
593
        // REVIEW: Should this be an error?
594
        if (0 == count)
594✔
595
        {
596
            LAGAS_(info).format(
×
597
                "primary_namespace::allocate, count({1}), lower({1}), "
×
598
                "upper({3}), prefix({4}), response(repeated_request)",
599
                count, next_id_, next_id_,
×
600
                naming::get_locality_id_from_gid(next_id_));
×
601

602
            return std::make_pair(next_id_, next_id_);
×
603
        }
604

605
        // Compute the new allocation.
606
        naming::gid_type lower(next_id_ + 1);
594✔
607
        naming::gid_type upper(lower + real_count);
594✔
608

609
        // Check for overflow.
610
        if (upper.get_msb() != lower.get_msb())
594✔
611
        {
612
            // Check for address space exhaustion (we currently use 86 bits of
613
            // the gid for the actual id)
614
            if (HPX_UNLIKELY(
×
615
                    (lower.get_msb() & naming::gid_type::virtual_memory_mask) ==
616
                    naming::gid_type::virtual_memory_mask))
617
            {
618
                HPX_THROW_EXCEPTION(hpx::error::internal_server_error,
×
619
                    "locality_namespace::allocate",
620
                    "primary namespace has been exhausted");
621
            }
622

623
            // Otherwise, correct
624
            lower = naming::gid_type(upper.get_msb(), nullptr);
×
625
            upper = lower + real_count;
×
626
        }
×
627

628
        // Store the new upper bound.
629
        next_id_ = upper;
594✔
630

631
        // Set the initial credit count.
632
        naming::detail::set_credit_for_gid(
594✔
633
            lower, std::int64_t(HPX_GLOBALCREDIT_INITIAL));
634
        naming::detail::set_credit_for_gid(
594✔
635
            upper, std::int64_t(HPX_GLOBALCREDIT_INITIAL));
636

637
        LAGAS_(info).format(
594✔
638
            "primary_namespace::allocate, count({1}), lower({2}), upper({3}), "
×
639
            "response(success)",
640
            count, lower, upper);
641

642
        return std::make_pair(lower, upper);
594✔
643
    }    // }}}
594✔
644

645
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
646
    void primary_namespace::dump_refcnt_matches(
647
        refcnt_table_type::iterator lower_it,
648
        refcnt_table_type::iterator upper_it, naming::gid_type const& lower,
649
        naming::gid_type const& upper, std::unique_lock<mutex_type>& l,
650
        char const* func_name)
651
    {
652
        // dump_refcnt_matches implementation
653
        HPX_ASSERT(l.owns_lock());
654

655
        if (lower_it == refcnts_.end() && upper_it == refcnts_.end())
656
            // We got nothing, bail - our caller is probably about to throw.
657
            return;
658

659
        std::stringstream ss;
660
        hpx::util::format_to(ss,
661
            "{1}, dumping server-side refcnt table matches, lower({2}), "
662
            "upper({3}):",
663
            func_name, lower, upper);
664

665
        for (/**/; lower_it != upper_it; ++lower_it)
666
        {
667
            // The [server] tag is in there to make it easier to filter
668
            // through the logs.
669
            hpx::util::format_to(ss, "\n  [server] lower({1}), credits({2})",
670
                lower_it->first, lower_it->second);
671
        }
672

673
        LAGAS_(debug) << ss.str();
674
    }    // dump_refcnt_matches implementation
675
#endif
676

677
    ///////////////////////////////////////////////////////////////////////////////
678
    void primary_namespace::increment(naming::gid_type const& lower,
8,047✔
679
        naming::gid_type const& upper, std::int64_t& credits, error_code& ec)
680
    {    // {{{ increment implementation
681
        std::unique_lock<mutex_type> l(mutex_);
8,047✔
682

683
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
684
        if (LAGAS_ENABLED(debug))
685
        {
686
            typedef refcnt_table_type::iterator iterator;
687

688
            // Find the mappings that we're about to touch.
689
            refcnt_table_type::iterator lower_it = refcnts_.find(lower);
690
            refcnt_table_type::iterator upper_it;
691
            if (lower != upper)
692
            {
693
                upper_it = refcnts_.find(upper);
694
            }
695
            else
696
            {
697
                upper_it = lower_it;
698
                ++upper_it;
699
            }
700

701
            dump_refcnt_matches(lower_it, upper_it, lower, upper, l,
702
                "primary_namespace::increment");
703
        }
704
#endif
705

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

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

716
        for (naming::gid_type raw = lower; raw != upper; ++raw)
16,094✔
717
        {
718
            refcnt_table_type::iterator it = refcnts_.find(raw);
8,047✔
719
            if (it == refcnts_.end())
8,047✔
720
            {
721
                std::int64_t count =
1,365✔
722
                    std::int64_t(HPX_GLOBALCREDIT_INITIAL) + credits;
1,365✔
723

724
                std::pair<refcnt_table_type::iterator, bool> p =
725
                    refcnts_.insert(refcnt_table_type::value_type(raw, count));
1,365✔
726
                if (!p.second)
1,365✔
727
                {
728
                    l.unlock();
×
729

730
                    HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
731
                        "primary_namespace::increment",
732
                        "couldn't create entry in reference count table, "
733
                        "raw({1}), ref-count({2})",
734
                        raw, count);
735
                    return;
×
736
                }
737

738
                it = p.first;
1,365✔
739
            }
1,365✔
740
            else
741
            {
742
                it->second += credits;
6,682✔
743
            }
744

745
            LAGAS_(info).format(
8,047✔
746
                "primary_namespace::increment, raw({1}), refcnt({2})", lower,
×
747
                it->second);
×
748
        }
8,047✔
749

750
        if (&ec != &throws)
8,047✔
751
            ec = make_success_code();
×
752
    }    // }}}
8,047✔
753

754
    ///////////////////////////////////////////////////////////////////////////////
755
    void primary_namespace::resolve_free_list(std::unique_lock<mutex_type>& l,
42,056✔
756
        std::list<refcnt_table_type::iterator> const& free_list,
757
        free_entry_list_type& free_entry_list,
758
        naming::gid_type const& /* lower */,
759
        naming::gid_type const& /* upper */, error_code& ec)
760
    {
761
        HPX_ASSERT_OWNS_LOCK(l);
42,056✔
762

763
        using hpx::get;
764

765
        typedef refcnt_table_type::iterator iterator;
766

767
        for (iterator const& it : free_list)
59,383✔
768
        {
769
            typedef refcnt_table_type::key_type key_type;
770

771
            // The mapping's key space.
772
            key_type gid = it->first;
17,327✔
773

774
            if (naming::detail::is_migratable(gid))
17,327✔
775
            {
776
                // wait for any migration to be completed
777
                wait_for_migration_locked(l, gid, ec);
×
778
            }
×
779

780
            // Resolve the query GID.
781
            resolved_type r = resolve_gid_locked(l, gid, ec);
17,327✔
782
            if (ec)
17,327✔
783
                return;
×
784

785
            naming::gid_type& raw = get<0>(r);
17,327✔
786
            if (raw == naming::invalid_gid)
17,327✔
787
            {
788
                l.unlock();
×
789

790
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
791
                    "primary_namespace::resolve_free_list",
792
                    "primary_namespace::resolve_free_list, failed to resolve "
793
                    "gid, gid({1})",
794
                    gid);
795
                return;    // couldn't resolve this one
×
796
            }
797

798
            // Make sure the GVA is valid.
799
            gva& g = get<1>(r);
17,327✔
800

801
            // REVIEW: Should we do more to make sure the GVA is valid?
802
            if (HPX_UNLIKELY(components::component_invalid == g.type))
17,327✔
803
            {
804
                l.unlock();
×
805

806
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
807
                    "primary_namespace::resolve_free_list",
808
                    "encountered a GVA with an invalid type while performing a "
809
                    "decrement, gid({1}), gva({2})",
810
                    gid, g);
811
                return;
×
812
            }
813
            else if (HPX_UNLIKELY(0 == g.count))
17,327✔
814
            {
815
                l.unlock();
×
816

817
                HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
818
                    "primary_namespace::resolve_free_list",
819
                    "encountered a GVA with a count of zero while performing a "
820
                    "decrement, gid({1}), gva({2})",
821
                    gid, g);
822
                return;
×
823
            }
824

825
            LAGAS_(info).format(
17,327✔
826
                "primary_namespace::resolve_free_list, resolved match, "
×
827
                "gid({1}), gva({2})",
828
                gid, g);
×
829

830
            // Fully resolve the range.
831
            gva const resolved = g.resolve(gid, raw);
17,327✔
832

833
            // Add the information needed to destroy these components to the
834
            // free list.
835
            free_entry_list.push_back(free_entry(resolved, gid, get<2>(r)));
17,327✔
836

837
            // remove this entry from the refcnt table
838
            refcnts_.erase(it);
17,327✔
839
        }
840
    }
42,056✔
841

842
    ///////////////////////////////////////////////////////////////////////////////
843
    void primary_namespace::decrement_sweep(
42,053✔
844
        free_entry_list_type& free_entry_list, naming::gid_type const& lower,
845
        naming::gid_type const& upper, std::int64_t credits, error_code& ec)
846
    {    // {{{ decrement_sweep implementation
847
        LAGAS_(info).format(
42,053✔
848
            "primary_namespace::decrement_sweep, lower({1}), upper({2}), "
×
849
            "credits({3})",
850
            lower, upper, credits);
×
851

852
        free_entry_list.clear();
42,056✔
853

854
        {
855
            std::unique_lock<mutex_type> l(mutex_);
42,056✔
856

857
#if defined(HPX_HAVE_AGAS_DUMP_REFCNT_ENTRIES)
858
            if (LAGAS_ENABLED(debug))
859
            {
860
                typedef refcnt_table_type::iterator iterator;
861

862
                // Find the mappings that we just added or modified.
863
                refcnt_table_type::iterator lower_it = refcnts_.find(lower);
864
                refcnt_table_type::iterator upper_it;
865
                if (lower != upper)
866
                {
867
                    upper_it = refcnts_.find(upper);
868
                }
869
                else
870
                {
871
                    upper_it = lower_it;
872
                    ++upper_it;
873
                }
874

875
                dump_refcnt_matches(lower_it, upper_it, lower, upper, l,
876
                    "primary_namespace::decrement_sweep");
877
            }
878
#endif
879

880
            ///////////////////////////////////////////////////////////////////////
881
            // Apply the decrement across the entire key space (e.g. [lower, upper]).
882

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

889
            std::list<refcnt_table_type::iterator> free_list;
42,056✔
890
            for (naming::gid_type raw = lower; raw != upper; ++raw)
84,109✔
891
            {
892
                refcnt_table_type::iterator it = refcnts_.find(raw);
42,056✔
893
                if (it == refcnts_.end())
42,056✔
894
                {
895
                    if (credits > std::int64_t(HPX_GLOBALCREDIT_INITIAL))
18,255✔
896
                    {
897
                        l.unlock();
×
898

899
                        HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
900
                            "primary_namespace::decrement_sweep",
901
                            "negative entry in reference count table, "
902
                            "raw({1}), refcount({2})",
903
                            raw,
904
                            std::int64_t(HPX_GLOBALCREDIT_INITIAL) - credits);
905
                        return;
×
906
                    }
907

908
                    std::int64_t count =
18,255✔
909
                        std::int64_t(HPX_GLOBALCREDIT_INITIAL) - credits;
18,255✔
910

911
                    std::pair<refcnt_table_type::iterator, bool> p =
912
                        refcnts_.insert(
18,255✔
913
                            refcnt_table_type::value_type(raw, count));
18,255✔
914
                    if (!p.second)
18,255✔
915
                    {
916
                        l.unlock();
×
917

918
                        HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
919
                            "primary_namespace::decrement_sweep",
920
                            "couldn't create entry in reference count table, "
921
                            "raw({1}), ref-count({2})",
922
                            raw, count);
923
                        return;
×
924
                    }
925

926
                    it = p.first;
18,255✔
927
                }
18,255✔
928
                else
929
                {
930
                    it->second -= credits;
23,801✔
931
                }
932

933
                // Sanity check.
934
                if (it->second < 0)
42,056✔
935
                {
936
                    l.unlock();
×
937

938
                    HPX_THROWS_IF(ec, hpx::error::invalid_data,
×
939
                        "primary_namespace::decrement_sweep",
940
                        "negative entry in reference count table, raw({1}), "
941
                        "refcount({2})",
942
                        raw, it->second);
943
                    return;
×
944
                }
945

946
                // this objects needs to be deleted
947
                if (it->second == 0)
42,056✔
948
                    free_list.push_back(it);
17,327✔
949
            }
42,056✔
950

951
            // Resolve the objects which have to be deleted.
952
            resolve_free_list(l, free_list, free_entry_list, lower, upper, ec);
42,056✔
953

954
        }    // Unlock the mutex.
42,056✔
955

956
        if (&ec != &throws)
42,056✔
957
            ec = make_success_code();
×
958
    }
42,056✔
959

960
    ///////////////////////////////////////////////////////////////////////////////
961
    void primary_namespace::free_components_sync(
42,056✔
962
        free_entry_list_type& free_list, naming::gid_type const& lower,
963
        naming::gid_type const& upper, error_code& ec)
964
    {
965
        using hpx::get;
966

967
        ///////////////////////////////////////////////////////////////////////////
968
        // Delete the objects on the free list.
969
        for (free_entry const& e : free_list)
59,383✔
970
        {
971
            // Bail if we're in late shutdown and non-local.
972
            if (HPX_UNLIKELY(!threads::threadmanager_is(hpx::state::running)) &&
17,327✔
973
                e.locality_ != locality_)
×
974
            {
975
                LAGAS_(info).format(
×
976
                    "primary_namespace::free_components_sync, cancelling free "
×
977
                    "operation because the threadmanager is down, lower({1}), "
978
                    "upper({2}), base({3}), gva({4}), locality({5})",
979
                    lower, upper, e.gid_, e.gva_, e.locality_);
×
980
                continue;
×
981
            }
982

983
            LAGAS_(info).format(
17,327✔
984
                "primary_namespace::free_components_sync, freeing component, "
×
985
                "lower({1}), upper({2}), base({3}), gva({4}), locality({5})",
986
                lower, upper, e.gid_, e.gva_, e.locality_);
×
987

988
            // Destroy the component.
989
            HPX_ASSERT(e.locality_ == e.gva_.prefix);
17,327✔
990
            naming::address addr(e.locality_, e.gva_.type, e.gva_.lva());
17,327✔
991
            if (e.locality_ == locality_)
17,327✔
992
            {
993
                auto deleter = components::deleter(e.gva_.type);
17,311✔
994
                if (deleter == nullptr)
17,311✔
995
                {
996
                    HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
997
                        "primary_namespace::free_components_sync",
998
                        "Attempting to delete object of unknown component "
999
                        "type: " +
1000
                            std::to_string(e.gva_.type));
1001
                    return;
×
1002
                }
1003
                deleter(e.gid_, HPX_MOVE(addr));
17,311✔
1004
            }
17,311✔
1005
            else
1006
            {
1007
                agas::destroy_component(e.gid_, addr);
16✔
1008
            }
1009
        }
1010

1011
        if (&ec != &throws)
42,055✔
1012
            ec = make_success_code();
×
1013
    }
42,055✔
1014

1015
    primary_namespace::resolved_type primary_namespace::resolve_gid_locked(
20,469✔
1016
        std::unique_lock<mutex_type>& l, naming::gid_type const& gid,
1017
        error_code& ec)
1018
    {
1019
        HPX_ASSERT_OWNS_LOCK(l);
20,469✔
1020

1021
        // handle (non-migratable) components located on this locality first
1022
        if (naming::refers_to_local_lva(gid) &&
20,469✔
1023
            !naming::refers_to_virtual_memory(gid))
17,268✔
1024
        {
1025
            if (&ec != &throws)
17,268✔
1026
                ec = make_success_code();
×
1027

1028
            return resolve_local_id(gid);
17,268✔
1029
        }
1030

1031
        return resolve_gid_locked_non_local(l, gid, ec);
3,201✔
1032
    }
20,469✔
1033

1034
    primary_namespace::resolved_type
1035
    primary_namespace::resolve_gid_locked_non_local(
32,969✔
1036
        std::unique_lock<mutex_type>& l, naming::gid_type const& gid,
1037
        error_code& ec)
1038
    {
1039
        HPX_ASSERT_OWNS_LOCK(l);
32,969✔
1040

1041
        HPX_ASSERT(!(naming::refers_to_local_lva(gid) &&
32,969✔
1042
            !naming::refers_to_virtual_memory(gid)));
1043

1044
        // parameters
1045
        naming::gid_type id = gid;
32,969✔
1046
        naming::detail::strip_internal_bits_from_gid(id);
32,969✔
1047

1048
        gva_table_type::const_iterator it = gvas_.lower_bound(id),
32,969✔
1049
                                       begin = gvas_.begin(), end = gvas_.end();
32,969✔
1050

1051
        if (it != end)
32,969✔
1052
        {
1053
            // Check for exact match
1054
            if (it->first == id)
23,056✔
1055
            {
1056
                if (&ec != &throws)
23,056✔
1057
                    ec = make_success_code();
×
1058

1059
                gva_table_data_type const& data = it->second;
23,056✔
1060
                return resolved_type(it->first, data.first, data.second);
23,056✔
1061
            }
1062

1063
            // We need to decrement the iterator, first we check that it's safe
1064
            // to do this.
1065
            else if (it != begin)
×
1066
            {
1067
                --it;
×
1068

1069
                // Found the GID in a range
1070
                gva_table_data_type const& data = it->second;
×
1071
                if ((it->first + data.first.count) > id)
×
1072
                {
1073
                    if (HPX_UNLIKELY(id.get_msb() != it->first.get_msb()))
×
1074
                    {
1075
                        l.unlock();
×
1076

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

1085
                    if (&ec != &throws)
×
1086
                        ec = make_success_code();
×
1087

1088
                    return resolved_type(it->first, data.first, data.second);
×
1089
                }
1090
            }
×
1091
        }
×
1092

1093
        else if (HPX_LIKELY(!gvas_.empty()))
9,913✔
1094
        {
1095
            --it;
9,913✔
1096

1097
            // Found the GID in a range
1098
            gva_table_data_type const& data = it->second;
9,913✔
1099
            if ((it->first + data.first.count) > id)
9,913✔
1100
            {
1101
                if (HPX_UNLIKELY(id.get_msb() != it->first.get_msb()))
×
1102
                {
1103
                    l.unlock();
×
1104

1105
                    HPX_THROWS_IF(ec, hpx::error::internal_server_error,
×
1106
                        "primary_namespace::resolve_gid_locked",
1107
                        "MSBs of lower and upper range bound do not match");
1108
                    return resolved_type(
×
1109
                        naming::invalid_gid, gva(), naming::invalid_gid);
×
1110
                }
1111

1112
                if (&ec != &throws)
×
1113
                    ec = make_success_code();
×
1114

1115
                return resolved_type(it->first, data.first, data.second);
×
1116
            }
1117
        }
9,913✔
1118

1119
        if (&ec != &throws)
9,913✔
1120
            ec = make_success_code();
×
1121

1122
        return resolved_type(naming::invalid_gid, gva(), naming::invalid_gid);
9,913✔
1123
    }
32,969✔
1124

1125
    // access current counter values
1126
    std::int64_t primary_namespace::counter_data::get_bind_gid_count(bool reset)
×
1127
    {
1128
        return util::get_and_reset_value(bind_gid_.count_, reset);
×
1129
    }
1130

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

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

1143
    std::int64_t primary_namespace::counter_data::get_increment_credit_count(
×
1144
        bool reset)
1145
    {
1146
        return util::get_and_reset_value(increment_credit_.count_, reset);
×
1147
    }
1148

1149
    std::int64_t primary_namespace::counter_data::get_decrement_credit_count(
×
1150
        bool reset)
1151
    {
1152
        return util::get_and_reset_value(decrement_credit_.count_, reset);
×
1153
    }
1154

1155
    std::int64_t primary_namespace::counter_data::get_allocate_count(bool reset)
×
1156
    {
1157
        return util::get_and_reset_value(allocate_.count_, reset);
×
1158
    }
1159

1160
    std::int64_t primary_namespace::counter_data::get_begin_migration_count(
×
1161
        bool reset)
1162
    {
1163
        return util::get_and_reset_value(begin_migration_.count_, reset);
×
1164
    }
1165

1166
    std::int64_t primary_namespace::counter_data::get_end_migration_count(
×
1167
        bool reset)
1168
    {
1169
        return util::get_and_reset_value(end_migration_.count_, reset);
×
1170
    }
1171

1172
    std::int64_t primary_namespace::counter_data::get_overall_count(bool reset)
×
1173
    {
1174
        return
×
1175
#if defined(HPX_HAVE_NETWORKING)
1176
            util::get_and_reset_value(route_.count_, reset) +
×
1177
#endif
1178
            util::get_and_reset_value(bind_gid_.count_, reset) +
×
1179
            util::get_and_reset_value(resolve_gid_.count_, reset) +
×
1180
            util::get_and_reset_value(unbind_gid_.count_, reset) +
×
1181
            util::get_and_reset_value(increment_credit_.count_, reset) +
×
1182
            util::get_and_reset_value(decrement_credit_.count_, reset) +
×
1183
            util::get_and_reset_value(allocate_.count_, reset) +
×
1184
            util::get_and_reset_value(begin_migration_.count_, reset) +
×
1185
            util::get_and_reset_value(end_migration_.count_, reset);
×
1186
    }
1187

1188
    // access execution time counters
1189
    std::int64_t primary_namespace::counter_data::get_bind_gid_time(bool reset)
×
1190
    {
1191
        return util::get_and_reset_value(bind_gid_.time_, reset);
×
1192
    }
1193

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

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

1206
    std::int64_t primary_namespace::counter_data::get_increment_credit_time(
×
1207
        bool reset)
1208
    {
1209
        return util::get_and_reset_value(increment_credit_.time_, reset);
×
1210
    }
1211

1212
    std::int64_t primary_namespace::counter_data::get_decrement_credit_time(
×
1213
        bool reset)
1214
    {
1215
        return util::get_and_reset_value(decrement_credit_.time_, reset);
×
1216
    }
1217

1218
    std::int64_t primary_namespace::counter_data::get_allocate_time(bool reset)
×
1219
    {
1220
        return util::get_and_reset_value(allocate_.time_, reset);
×
1221
    }
1222

1223
    std::int64_t primary_namespace::counter_data::get_begin_migration_time(
×
1224
        bool reset)
1225
    {
1226
        return util::get_and_reset_value(begin_migration_.time_, reset);
×
1227
    }
1228

1229
    std::int64_t primary_namespace::counter_data::get_end_migration_time(
×
1230
        bool reset)
1231
    {
1232
        return util::get_and_reset_value(end_migration_.time_, reset);
×
1233
    }
1234

1235
    std::int64_t primary_namespace::counter_data::get_overall_time(bool reset)
×
1236
    {
1237
        return
×
1238
#if defined(HPX_HAVE_NETWORKING)
1239
            util::get_and_reset_value(route_.time_, reset) +
×
1240
#endif
1241
            util::get_and_reset_value(bind_gid_.time_, reset) +
×
1242
            util::get_and_reset_value(resolve_gid_.time_, reset) +
×
1243
            util::get_and_reset_value(unbind_gid_.time_, reset) +
×
1244
            util::get_and_reset_value(increment_credit_.time_, reset) +
×
1245
            util::get_and_reset_value(decrement_credit_.time_, reset) +
×
1246
            util::get_and_reset_value(allocate_.time_, reset) +
×
1247
            util::get_and_reset_value(begin_migration_.time_, reset) +
×
1248
            util::get_and_reset_value(end_migration_.time_, reset);
×
1249
    }
1250

1251
    void primary_namespace::counter_data::enable_all()
×
1252
    {
1253
#if defined(HPX_HAVE_NETWORKING)
1254
        route_.enabled_ = true;
×
1255
#endif
1256
        bind_gid_.enabled_ = true;
×
1257
        resolve_gid_.enabled_ = true;
×
1258
        unbind_gid_.enabled_ = true;
×
1259
        increment_credit_.enabled_ = true;
×
1260
        decrement_credit_.enabled_ = true;
×
1261
        allocate_.enabled_ = true;
×
1262
        begin_migration_.enabled_ = true;
×
1263
        end_migration_.enabled_ = true;
×
1264
    }
×
1265

1266
    // increment counter values
1267
    void primary_namespace::counter_data::increment_bind_gid_count()
4,558✔
1268
    {
1269
        if (bind_gid_.enabled_)
4,558✔
1270
        {
1271
            ++bind_gid_.count_;
×
1272
        }
×
1273
    }
4,558✔
1274

1275
    void primary_namespace::counter_data::increment_resolve_gid_count()
54,309✔
1276
    {
1277
        if (resolve_gid_.enabled_)
54,309✔
1278
        {
1279
            ++resolve_gid_.count_;
×
1280
        }
×
1281
    }
54,309✔
1282

1283
    void primary_namespace::counter_data::increment_unbind_gid_count()
20,824✔
1284
    {
1285
        if (unbind_gid_.enabled_)
20,824✔
1286
        {
1287
            ++unbind_gid_.count_;
×
1288
        }
×
1289
    }
20,824✔
1290

1291
    void primary_namespace::counter_data::increment_increment_credit_count()
8,047✔
1292
    {
1293
        if (increment_credit_.enabled_)
8,047✔
1294
        {
1295
            ++increment_credit_.count_;
×
1296
        }
×
1297
    }
8,047✔
1298

1299
    void primary_namespace::counter_data::increment_decrement_credit_count()
19,111✔
1300
    {
1301
        if (decrement_credit_.enabled_)
19,111✔
1302
        {
1303
            ++decrement_credit_.count_;
×
1304
        }
×
1305
    }
19,111✔
1306

1307
    void primary_namespace::counter_data::increment_allocate_count()
594✔
1308
    {
1309
        if (allocate_.enabled_)
594✔
1310
        {
1311
            ++allocate_.count_;
×
1312
        }
×
1313
    }
594✔
1314

1315
    void primary_namespace::counter_data::increment_begin_migration_count()
2,736✔
1316
    {
1317
        if (begin_migration_.enabled_)
2,736✔
1318
        {
1319
            ++begin_migration_.count_;
×
1320
        }
×
1321
    }
2,736✔
1322

1323
    void primary_namespace::counter_data::increment_end_migration_count()
2,736✔
1324
    {
1325
        if (end_migration_.enabled_)
2,736✔
1326
        {
1327
            ++end_migration_.count_;
×
1328
        }
×
1329
    }
2,736✔
1330

1331
#if defined(HPX_HAVE_NETWORKING)
1332
    std::int64_t primary_namespace::counter_data::get_route_count(bool reset)
×
1333
    {
1334
        return util::get_and_reset_value(route_.count_, reset);
×
1335
    }
1336

1337
    std::int64_t primary_namespace::counter_data::get_route_time(bool reset)
×
1338
    {
1339
        return util::get_and_reset_value(route_.time_, reset);
×
1340
    }
1341

1342
    void primary_namespace::counter_data::increment_route_count()
3,142✔
1343
    {
1344
        if (route_.enabled_)
3,142✔
1345
        {
1346
            ++route_.count_;
×
1347
        }
×
1348
    }
3,142✔
1349
#endif
1350
}    // 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