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

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

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

60.47
/libs/full/components_base/src/server/one_size_heap_list.cpp
1
//  Copyright (c) 1998-2024 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#include <hpx/config.hpp>
9
#include <hpx/assert.hpp>
10
#include <hpx/components_base/server/one_size_heap_list.hpp>
11
#include <hpx/components_base/server/wrapper_heap_base.hpp>
12
#include <hpx/modules/errors.hpp>
13
#include <hpx/modules/format.hpp>
14
#include <hpx/modules/functional.hpp>
15
#include <hpx/modules/runtime_local.hpp>
16
#include <hpx/modules/synchronization.hpp>
17
#include <hpx/modules/threading_base.hpp>
18
#if defined(HPX_DEBUG)
19
#include <hpx/modules/logging.hpp>
20
#endif
21

22
#include <cstddef>
23
#include <memory>
24
#include <mutex>
25
#include <shared_mutex>
26
#include <string>
27

28
namespace hpx::util {
29

30
    one_size_heap_list::one_size_heap_list()
31
    {
125✔
32
        HPX_ASSERT(false);    // shouldn't ever be called
33
    }
34

35
    one_size_heap_list::~one_size_heap_list() noexcept
36
    {
37
#if defined(HPX_DEBUG)
38
        LOSH_(info).format(
39
            "{1}::~{1}: size({2}), max_count({3}), alloc_count({4}), "
40
            "free_count({5})",
41
            name(), heap_count_, max_alloc_count_, alloc_count_, free_count_);
42

43
        if (alloc_count_ > free_count_)
44
        {
45
            LOSH_(warning).format(
46
                "{1}::~{1}: releasing with {2} allocated objects", name(),
125✔
47
                alloc_count_ - free_count_);
48
        }
40,740✔
49
#endif
50
    }
40,740✔
51

52
    void* one_size_heap_list::alloc(std::size_t count)
40,740✔
53
    {
54
        if (HPX_UNLIKELY(0 == count))
×
55
        {
×
56
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter, name() + "::alloc",
57
                "cannot allocate 0 objects");
58
        }
59

40,740✔
60
        void* p = nullptr;
61

40,740✔
62
        {
63
            std::shared_lock<hpx::shared_mutex> sl(rwlock_);
44,760✔
64

65
            if (!heap_list_.empty())
66
            {
67
                for (auto& heap : heap_list_)
68
                {
69
                    if (heap->alloc(&p, count))
44,750✔
70
                    {
71
#if defined(HPX_DEBUG)
72
                        // Allocation succeeded, update statistics.
44,750✔
73
                        alloc_count_ += count;
74
                        if (alloc_count_ - free_count_ > max_alloc_count_)
75
                            max_alloc_count_ = alloc_count_ - free_count_;
76
#endif
77
                        return p;
78
                    }
79

80
#if defined(HPX_DEBUG)
40,605✔
81
                    LOSH_(info).format(
82
                        "{1}::alloc: failed to allocate from heap[{2}] "
83
                        "(heap[{2}] has allocated {3} objects and has "
84
                        "space for {4} more objects)",
85
                        name(), heap->heap_count(), heap->size(),
86
                        heap->free_size());
87
#endif
88
                }
89
            }
90
        }
91

92
        // Create new heap.
93
        bool result = false;
94
        std::shared_ptr<util::wrapper_heap_base> heap;
95
#if defined(HPX_DEBUG)
96
        heap = create_heap_(class_name_.c_str(), heap_count_ + 1, parameters_);
97
#else
98
        heap = create_heap_(class_name_.c_str(), 0, parameters_);
99
#endif
135✔
100
        result = heap->alloc((void**) &p, count);
270✔
101

102
        // Add the heap into the list
103
        {
104
            std::unique_lock<hpx::shared_mutex> ul(rwlock_);
105
            heap_list_.push_front(heap);
106
        }
107

108
        if (HPX_UNLIKELY(!result || nullptr == p))
109
        {
135✔
110
            // out of memory
111
            HPX_THROW_BAD_ALLOC("one_size_heap_list::alloc");
112
        }
135✔
113

114
#if defined(HPX_DEBUG)
115
        alloc_count_ += count;
×
116
        ++heap_count_;
×
117

118
        LOSH_(info).format(
119
            "{1}::alloc: creating new heap[{2}], size is now {3}", name(),
120
            heap_count_, heap_list_.size());
121
#endif
122

123
        return p;
124
    }
125

126
    bool one_size_heap_list::reschedule(void* p, std::size_t count)
127
    {
128
        if (nullptr == threads::get_self_ptr())
129
        {
130
            hpx::threads::thread_init_data data(
131
                hpx::threads::make_thread_function_nullary(
132
                    hpx::bind_front(&one_size_heap_list::free, this, p, count)),
40,676✔
133
                "one_size_heap_list::free");
134
            hpx::threads::register_work(data);
40,676✔
135
            return true;
136
        }
137
        return false;
×
138
    }
139

140
    void one_size_heap_list::free(void* p, std::size_t count)
×
141
    {
142
        if (nullptr == p || !threads::threadmanager_is(hpx::state::running))
143
        {
144
            return;
145
        }
146

40,676✔
147
        // if this is called from outside a HPX thread we need to
148
        // re-schedule the request
40,676✔
149
        if (reschedule(p, count))
150
            return;
×
151

152
        {
153
            std::shared_lock<hpx::shared_mutex> sl(rwlock_);
154

155
            // Find the heap which allocated this pointer.
40,676✔
156
            for (auto const& heap : heap_list_)
157
            {
158
                if (heap->did_alloc(p))
40,676✔
159
                {
160
                    heap->free(p, count);
161
#if defined(HPX_DEBUG)
62,435✔
162
                    free_count_ += count;
163
#endif
164
                    return;
165
                }
166
            }
167
        }
62,435✔
168

62,435✔
169
        HPX_THROW_EXCEPTION(hpx::error::bad_parameter, name() + "::free",
170
            "pointer {1} was not allocated by this {2}", p, name());
40,676✔
171
    }
172

173
    bool one_size_heap_list::did_alloc(void* p) const
174
    {
62,435✔
175
        std::shared_lock<hpx::shared_mutex> sl(rwlock_);
176
        for (auto const& heap : heap_list_)
177
        {
178
            if (heap->did_alloc(p))
179
            {
180
                return true;
181
            }
182
        }
183
        return false;
×
184
    }
185

×
186
    std::string one_size_heap_list::name() const
187
    {
188
        if (class_name_.empty())
189
        {
×
190
            return {"one_size_heap_list(unknown)"};
191
        }
×
192
        return std::string("one_size_heap_list(") + class_name_ + ")";
×
193
    }
194
}    // namespace hpx::util
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

© 2026 Coveralls, Inc