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

STEllAR-GROUP / hpx / #862

10 Jan 2023 05:30PM UTC coverage: 86.582% (-0.05%) from 86.634%
#862

push

StellarBot
Merge #6130

6130: Remove the mutex lock in the critical path of get_partitioner. r=hkaiser a=JiakunYan

Remove the mutex lock in the critical path of hpx::resource::detail::get_partitioner.

The protected variable `partitioner_ref` is only set once during initialization.

Co-authored-by: Jiakun Yan <jiakunyan1998@gmail.com>

6 of 6 new or added lines in 1 file covered. (100.0%)

174767 of 201851 relevant lines covered (86.58%)

2069816.07 hits per line

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

93.15
/libs/core/logging/src/format/named_write.cpp
1
// named_write.cpp
2

3
// Boost Logging library
4
//
5
// Author: John Torjo, www.torjo.com
6
//
7
// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
8
//
9
//  SPDX-License-Identifier: BSL-1.0
10
// Distributed under the Boost Software License, Version 1.0.
11
//    (See accompanying file LICENSE_1_0.txt or copy at
12
//          http://www.boost.org/LICENSE_1_0.txt)
13
//
14
// See http://www.boost.org for updates, documentation, and revision history.
15
// See http://www.torjo.com/log2/ for more details
16

17
#include <hpx/logging/format/named_write.hpp>
18

19
#include <hpx/config.hpp>
20
#include <hpx/assert.hpp>
21
#include <hpx/logging/format/destinations.hpp>
22
#include <hpx/logging/format/formatters.hpp>
23

24
#include <cstddef>
25
#include <memory>
26
#include <sstream>
27
#include <string>
28

29
namespace hpx::util::logging::detail {
30

31
    static std::string unescape(std::string escaped)
243,377✔
32
    {
33
        typedef std::size_t size_type;
34
        size_type idx_start = 0;
243,377✔
35
        while (true)
243,377✔
36
        {
37
            size_type found = escaped.find("%%", idx_start);
243,377✔
38
            if (found != std::string::npos)
243,377✔
39
            {
40
                escaped.erase(
×
41
                    escaped.begin() + static_cast<std::ptrdiff_t>(found));
×
42
                ++idx_start;
×
43
            }
×
44
            else
45
                break;
243,377✔
46
        }
47
        return escaped;
243,377✔
48
    }
49

50
    void named_formatters::compute_write_steps()
72,104✔
51
    {
52
        typedef std::size_t size_type;
53

54
        write_steps.clear();
72,104✔
55
        std::string remaining = format_string;
72,104✔
56
        size_type start_search_idx = 0;
72,104✔
57
        while (!remaining.empty())
315,481✔
58
        {
59
            size_type idx = remaining.find_first_of("%|", start_search_idx);
243,377✔
60
            switch (idx != std::string::npos ? remaining[idx] : '\0')
243,377✔
61
            {
62
            case '|':
63
            {
64
                // up to here, this is a spacer string
65
                start_search_idx = 0;
23,237✔
66
                std::string spacer = detail::unescape(remaining.substr(0, idx));
23,237✔
67
                remaining.erase(0, idx + 1);
23,237✔
68

69
                formatter::manipulator* fmt = (formatter::manipulator*) -1;
23,237✔
70
                write_steps.emplace_back(spacer, fmt);
23,237✔
71
                break;
72
            }
23,237✔
73
            case '%':
74
            {
75
                // see if just escaped
76
                if ((idx < remaining.size() - 1) && remaining[idx + 1] == '%')
198,126✔
77
                {
78
                    // we found an escaped char
79
                    start_search_idx = idx + 2;
×
80
                    continue;
×
81
                }
82

83
                // up to here, this is a spacer string
84
                start_search_idx = 0;
198,126✔
85
                std::string spacer = detail::unescape(remaining.substr(0, idx));
198,126✔
86
                remaining.erase(0, idx + 1);
198,126✔
87
                // find end of formatter name
88
                idx = remaining.find('%');
198,126✔
89
                formatter::manipulator* fmt = nullptr;
198,126✔
90
                if (idx != std::string::npos)
198,126✔
91
                {
92
                    std::string name = remaining.substr(0, idx);
198,126✔
93
                    remaining.erase(0, idx + 1);
198,126✔
94
                    auto iter = find_named(formatters, name);
198,126✔
95
                    if (iter != formatters.end())
198,126✔
96
                        fmt = iter->value.get();
124,136✔
97
                }
198,126✔
98
                // note: fmt could be null, in case
99
                write_steps.emplace_back(spacer, fmt);
198,126✔
100
                break;
101
            }
198,126✔
102
            case '\0':
103
            {
104
                // last part
105
                write_steps.emplace_back(detail::unescape(remaining), nullptr);
22,014✔
106
                remaining.clear();
22,014✔
107
                break;
22,014✔
108
            }
109
            }
110
        }
111
    }
72,104✔
112

113
    void named_destinations::compute_write_steps()
71,271✔
114
    {
115
        write_steps.clear();
71,271✔
116

117
        std::istringstream in(format_string);
71,271✔
118
        std::string word;
71,271✔
119
        while (in >> word)
76,661✔
120
        {
121
            if (word[0] == '+')
5,390✔
122
                word.erase(word.begin());
×
123
            else if (word[0] == '-')
5,390✔
124
                // ignore this word
125
                continue;
×
126

127
            auto iter = find_named(destinations, word);
5,390✔
128
            if (iter != destinations.cend())
5,390✔
129
                write_steps.push_back(iter->value.get());
5,390✔
130
        }
131
    }
71,271✔
132

133
    namespace {
134
        struct parse_formatter
7,338✔
135
        {
136
            // formatter starts and ends with %
137
            bool has_manipulator_name() const
324,095✔
138
            {
139
                if (m_manipulator.empty())
324,095✔
140
                    return false;
45,251✔
141
                if (m_manipulator.size() > 1)
278,844✔
142
                    if (m_manipulator[0] == '%' &&
469,632✔
143
                        (*m_manipulator.rbegin() == '%'))
420,712✔
144
                        return true;
48,920✔
145

146
                return false;
229,924✔
147
            }
324,095✔
148

149
            std::string get_manipulator_name() const
2,446✔
150
            {
151
                HPX_ASSERT(has_manipulator_name());
2,446✔
152
                // ignore starting and ending %
153
                return m_manipulator.substr(1, m_manipulator.size() - 2);
2,446✔
154
            }
155

156
            void clear()
22,014✔
157
            {
158
                m_manipulator.clear();
22,014✔
159
            }
22,014✔
160

161
            void add(char c)
270,283✔
162
            {
163
                if (has_manipulator_name())
270,283✔
164
                    // was a manipulator until now
165
                    clear();
19,568✔
166

167
                if (c == '%')
270,283✔
168
                {
169
                    m_manipulator += c;
44,028✔
170
                    if (!has_manipulator_name())
44,028✔
171
                        // it could be the start of a formatter
172
                        m_manipulator = '%';
22,014✔
173
                }
44,028✔
174
                else if (m_manipulator.empty())
226,255✔
175
                {
176
                    ;    // ignore this char - not from a manipulator
177
                }
40,359✔
178
                else if (m_manipulator[0] == '%')
185,896✔
179
                {
180
                    m_manipulator += c;
185,896✔
181
                }
185,896✔
182
                else
183
                {
184
                    // manipulator should always start with %
185
                    HPX_ASSERT(false);
×
186
                }
187
            }
270,283✔
188

189
        private:
190
            std::string m_manipulator;
191
        };
192

193
        struct parse_destination
7,338✔
194
        {
195
            bool has_manipulator_name() const
10,905✔
196
            {
197
                return !m_manipulator.empty();
10,905✔
198
            }
199

200
            std::string get_manipulator_name() const
3,635✔
201
            {
202
                HPX_ASSERT(has_manipulator_name());
3,635✔
203
                if (m_manipulator[0] == '-' || m_manipulator[0] == '+')
3,635✔
204
                    // + or - -> turning on or off a destination
205
                    return m_manipulator.substr(1);
×
206
                else
207
                    return m_manipulator;
3,635✔
208
            }
3,635✔
209

210
            void clear()
4,858✔
211
            {
212
                m_manipulator.clear();
4,858✔
213
            }
4,858✔
214

215
            void add(char c)
20,893✔
216
            {
217
                // destination always follows ' '
218
                if (c == ' ')
20,893✔
219
                    clear();
1,223✔
220
                else
221
                    m_manipulator += c;
19,670✔
222
            }
20,893✔
223

224
        private:
225
            std::string m_manipulator;
226
        };
227

228
        template <typename Named, typename ParserType>
229
        void configure(
7,338✔
230
            Named& named, std::string const& format, ParserType parser)
231
        {
232
            // need to parse string
233
            bool parsing_params = false;
7,338✔
234
            std::string params;
7,338✔
235
            std::string stripped_str;
7,338✔
236
            for (char c : format)
424,851✔
237
            {
238
                if ((c == '(') && !parsing_params)
417,513✔
239
                {
240
                    if (parser.has_manipulator_name())
8,527✔
241
                    {
242
                        parsing_params = true;
6,081✔
243
                        params.clear();
6,081✔
244
                    }
6,081✔
245
                    else
246
                    {
247
                        stripped_str += c;
2,446✔
248
                        parser.add(c);
2,446✔
249
                    }
250
                }
8,527✔
251
                else if (c == ')' && parsing_params)
408,986✔
252
                {
253
                    HPX_ASSERT(parser.has_manipulator_name());
6,081✔
254
                    named.configure(parser.get_manipulator_name(), params);
6,081✔
255
                    parser.clear();
6,081✔
256
                    parsing_params = false;
6,081✔
257
                }
6,081✔
258
                else
259
                {
260
                    if (parsing_params)
402,905✔
261
                        params += c;
114,175✔
262
                    else
263
                    {
264
                        stripped_str += c;
288,730✔
265
                        parser.add(c);
288,730✔
266
                    }
267
                }
268
            }
269
            named.string(stripped_str);
7,338✔
270
        }
7,338✔
271
    }    // namespace
272
}    // namespace hpx::util::logging::detail
273

274
namespace hpx::util::logging::writer {
275

276
    named_write::named_write()
16,289✔
277
    {
278
        set_formatter<formatter::idx>("idx");
16,289✔
279
        set_formatter<formatter::high_precision_time>("time", "$hh:$mm:$ss");
16,289✔
280
        set_formatter<formatter::thread_id>("thread_id");
16,289✔
281

282
        set_destination<destination::file>("file", "");
16,289✔
283
        set_destination<destination::cout>("cout");
16,289✔
284
        set_destination<destination::cerr>("cerr");
16,289✔
285
        set_destination<destination::dbg_window>("debug");
16,289✔
286
    }
16,289✔
287

288
    void named_write::configure_formatter(std::string const& format)
3,669✔
289
    {
290
        detail::configure(m_format, format, detail::parse_formatter{});
3,669✔
291
    }
3,669✔
292

293
    void named_write::configure_destination(std::string const& format)
3,669✔
294
    {
295
        detail::configure(m_destination, format, detail::parse_destination{});
3,669✔
296
    }
3,669✔
297
}    // namespace hpx::util::logging::writer
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