Skip to content

Commit e4726b7

Browse files
committed
Use execution_context allocator in timer queues.
Added new configuration parameter "timer" / "heap_reserve" that may be used to reserve space in the vector used for a timer queue's heap.
1 parent 62a8f90 commit e4726b7

18 files changed

Lines changed: 348 additions & 280 deletions

asio/include/asio/detail/deadline_timer_service.hpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstddef>
2020
#include "asio/associated_cancellation_slot.hpp"
2121
#include "asio/cancellation_type.hpp"
22+
#include "asio/config.hpp"
2223
#include "asio/error.hpp"
2324
#include "asio/execution_context.hpp"
2425
#include "asio/detail/bind_handler.hpp"
@@ -43,16 +44,19 @@
4344
namespace asio {
4445
namespace detail {
4546

46-
template <typename Time_Traits>
47+
template <typename TimeTraits>
4748
class deadline_timer_service
48-
: public execution_context_service_base<deadline_timer_service<Time_Traits>>
49+
: public execution_context_service_base<deadline_timer_service<TimeTraits>>
4950
{
5051
public:
5152
// The time type.
52-
typedef typename Time_Traits::time_type time_type;
53+
typedef typename TimeTraits::time_type time_type;
5354

5455
// The duration type.
55-
typedef typename Time_Traits::duration_type duration_type;
56+
typedef typename TimeTraits::duration_type duration_type;
57+
58+
// The allocator type.
59+
typedef execution_context::allocator<void> allocator_type;
5660

5761
// The implementation type of the timer. This type is dependent on the
5862
// underlying implementation of the timer service.
@@ -61,13 +65,15 @@ class deadline_timer_service
6165
{
6266
time_type expiry;
6367
bool might_have_pending_waits;
64-
typename timer_queue<Time_Traits>::per_timer_data timer_data;
68+
typename timer_queue<TimeTraits, allocator_type>::per_timer_data timer_data;
6569
};
6670

6771
// Constructor.
6872
deadline_timer_service(execution_context& context)
6973
: execution_context_service_base<
70-
deadline_timer_service<Time_Traits>>(context),
74+
deadline_timer_service<TimeTraits>>(context),
75+
timer_queue_(allocator_type(context),
76+
config(context).get("timer", "heap_reserve", 0U)),
7177
scheduler_(asio::use_service<timer_scheduler>(context))
7278
{
7379
scheduler_.init_task();
@@ -204,7 +210,7 @@ class deadline_timer_service
204210
// Get the expiry time for the timer relative to now.
205211
duration_type expires_from_now(const implementation_type& impl) const
206212
{
207-
return Time_Traits::subtract(this->expiry(impl), Time_Traits::now());
213+
return TimeTraits::subtract(this->expiry(impl), TimeTraits::now());
208214
}
209215

210216
// Set the expiry time for the timer as an absolute time.
@@ -222,27 +228,27 @@ class deadline_timer_service
222228
const duration_type& expiry_time, asio::error_code& ec)
223229
{
224230
return expires_at(impl,
225-
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
231+
TimeTraits::add(TimeTraits::now(), expiry_time), ec);
226232
}
227233

228234
// Set the expiry time for the timer relative to now.
229235
std::size_t expires_from_now(implementation_type& impl,
230236
const duration_type& expiry_time, asio::error_code& ec)
231237
{
232238
return expires_at(impl,
233-
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
239+
TimeTraits::add(TimeTraits::now(), expiry_time), ec);
234240
}
235241

236242
// Perform a blocking wait on the timer.
237243
void wait(implementation_type& impl, asio::error_code& ec)
238244
{
239-
time_type now = Time_Traits::now();
245+
time_type now = TimeTraits::now();
240246
ec = asio::error_code();
241-
while (Time_Traits::less_than(now, impl.expiry) && !ec)
247+
while (TimeTraits::less_than(now, impl.expiry) && !ec)
242248
{
243-
this->do_wait(Time_Traits::to_posix_duration(
244-
Time_Traits::subtract(impl.expiry, now)), ec);
245-
now = Time_Traits::now();
249+
this->do_wait(TimeTraits::to_posix_duration(
250+
TimeTraits::subtract(impl.expiry, now)), ec);
251+
now = TimeTraits::now();
246252
}
247253
}
248254

@@ -301,7 +307,7 @@ class deadline_timer_service
301307
{
302308
public:
303309
op_cancellation(deadline_timer_service* s,
304-
typename timer_queue<Time_Traits>::per_timer_data* p)
310+
typename timer_queue<TimeTraits, allocator_type>::per_timer_data* p)
305311
: service_(s),
306312
timer_data_(p)
307313
{
@@ -321,11 +327,12 @@ class deadline_timer_service
321327

322328
private:
323329
deadline_timer_service* service_;
324-
typename timer_queue<Time_Traits>::per_timer_data* timer_data_;
330+
typename timer_queue<TimeTraits, allocator_type>::per_timer_data*
331+
timer_data_;
325332
};
326333

327334
// The queue of timers.
328-
timer_queue<Time_Traits> timer_queue_;
335+
timer_queue<TimeTraits, allocator_type> timer_queue_;
329336

330337
// The object that schedules and executes timers. Usually a reactor.
331338
timer_scheduler& scheduler_;

asio/include/asio/detail/dev_poll_reactor.hpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,38 +140,39 @@ class dev_poll_reactor
140140
ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
141141

142142
// Add a new timer queue to the reactor.
143-
template <typename Time_Traits>
144-
void add_timer_queue(timer_queue<Time_Traits>& queue);
143+
template <typename TimeTraits, typename Allocator>
144+
void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);
145145

146146
// Remove a timer queue from the reactor.
147-
template <typename Time_Traits>
148-
void remove_timer_queue(timer_queue<Time_Traits>& queue);
147+
template <typename TimeTraits, typename Allocator>
148+
void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);
149149

150150
// Schedule a new operation in the given timer queue to expire at the
151151
// specified absolute time.
152-
template <typename Time_Traits>
153-
void schedule_timer(timer_queue<Time_Traits>& queue,
154-
const typename Time_Traits::time_type& time,
155-
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
152+
template <typename TimeTraits, typename Allocator>
153+
void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,
154+
const typename TimeTraits::time_type& time,
155+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
156+
wait_op* op);
156157

157158
// Cancel the timer operations associated with the given token. Returns the
158159
// number of operations that have been posted or dispatched.
159-
template <typename Time_Traits>
160-
std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
161-
typename timer_queue<Time_Traits>::per_timer_data& timer,
160+
template <typename TimeTraits, typename Allocator>
161+
std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,
162+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
162163
std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
163164

164165
// Cancel the timer operations associated with the given key.
165-
template <typename Time_Traits>
166-
void cancel_timer_by_key(timer_queue<Time_Traits>& queue,
167-
typename timer_queue<Time_Traits>::per_timer_data* timer,
166+
template <typename TimeTraits, typename Allocator>
167+
void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,
168+
typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,
168169
void* cancellation_key);
169170

170171
// Move the timer operations associated with the given timer.
171-
template <typename Time_Traits>
172-
void move_timer(timer_queue<Time_Traits>& queue,
173-
typename timer_queue<Time_Traits>::per_timer_data& target,
174-
typename timer_queue<Time_Traits>::per_timer_data& source);
172+
template <typename TimeTraits, typename Allocator>
173+
void move_timer(timer_queue<TimeTraits, Allocator>& queue,
174+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,
175+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);
175176

176177
// Run /dev/poll once until interrupted or events are ready to be dispatched.
177178
ASIO_DECL void run(long usec, op_queue<operation>& ops);

asio/include/asio/detail/epoll_reactor.hpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,38 +169,39 @@ class epoll_reactor
169169
per_descriptor_data& descriptor_data);
170170

171171
// Add a new timer queue to the reactor.
172-
template <typename Time_Traits>
173-
void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
172+
template <typename TimeTraits, typename Allocator>
173+
void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);
174174

175175
// Remove a timer queue from the reactor.
176-
template <typename Time_Traits>
177-
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
176+
template <typename TimeTraits, typename Allocator>
177+
void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);
178178

179179
// Schedule a new operation in the given timer queue to expire at the
180180
// specified absolute time.
181-
template <typename Time_Traits>
182-
void schedule_timer(timer_queue<Time_Traits>& queue,
183-
const typename Time_Traits::time_type& time,
184-
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
181+
template <typename TimeTraits, typename Allocator>
182+
void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,
183+
const typename TimeTraits::time_type& time,
184+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
185+
wait_op* op);
185186

186187
// Cancel the timer operations associated with the given token. Returns the
187188
// number of operations that have been posted or dispatched.
188-
template <typename Time_Traits>
189-
std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
190-
typename timer_queue<Time_Traits>::per_timer_data& timer,
189+
template <typename TimeTraits, typename Allocator>
190+
std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,
191+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
191192
std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
192193

193194
// Cancel the timer operations associated with the given key.
194-
template <typename Time_Traits>
195-
void cancel_timer_by_key(timer_queue<Time_Traits>& queue,
196-
typename timer_queue<Time_Traits>::per_timer_data* timer,
195+
template <typename TimeTraits, typename Allocator>
196+
void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,
197+
typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,
197198
void* cancellation_key);
198199

199200
// Move the timer operations associated with the given timer.
200-
template <typename Time_Traits>
201-
void move_timer(timer_queue<Time_Traits>& queue,
202-
typename timer_queue<Time_Traits>::per_timer_data& target,
203-
typename timer_queue<Time_Traits>::per_timer_data& source);
201+
template <typename TimeTraits, typename Allocator>
202+
void move_timer(timer_queue<TimeTraits, Allocator>& queue,
203+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,
204+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);
204205

205206
// Run epoll once until interrupted or events are ready to be dispatched.
206207
ASIO_DECL void run(long usec, op_queue<operation>& ops);

asio/include/asio/detail/impl/dev_poll_reactor.hpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,26 @@ inline void dev_poll_reactor::post_immediate_completion(
3232
scheduler_.post_immediate_completion(op, is_continuation);
3333
}
3434

35-
template <typename Time_Traits>
36-
void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
35+
template <typename TimeTraits, typename Allocator>
36+
void dev_poll_reactor::add_timer_queue(
37+
timer_queue<TimeTraits, Allocator>& queue)
3738
{
3839
do_add_timer_queue(queue);
3940
}
4041

41-
template <typename Time_Traits>
42-
void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
42+
template <typename TimeTraits, typename Allocator>
43+
void dev_poll_reactor::remove_timer_queue(
44+
timer_queue<TimeTraits, Allocator>& queue)
4345
{
4446
do_remove_timer_queue(queue);
4547
}
4648

47-
template <typename Time_Traits>
48-
void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
49-
const typename Time_Traits::time_type& time,
50-
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
49+
template <typename TimeTraits, typename Allocator>
50+
void dev_poll_reactor::schedule_timer(
51+
timer_queue<TimeTraits, Allocator>& queue,
52+
const typename TimeTraits::time_type& time,
53+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
54+
wait_op* op)
5155
{
5256
asio::detail::mutex::scoped_lock lock(mutex_);
5357

@@ -63,9 +67,10 @@ void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
6367
interrupter_.interrupt();
6468
}
6569

66-
template <typename Time_Traits>
67-
std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
68-
typename timer_queue<Time_Traits>::per_timer_data& timer,
70+
template <typename TimeTraits, typename Allocator>
71+
std::size_t dev_poll_reactor::cancel_timer(
72+
timer_queue<TimeTraits, Allocator>& queue,
73+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
6974
std::size_t max_cancelled)
7075
{
7176
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -76,9 +81,10 @@ std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
7681
return n;
7782
}
7883

79-
template <typename Time_Traits>
80-
void dev_poll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,
81-
typename timer_queue<Time_Traits>::per_timer_data* timer,
84+
template <typename TimeTraits, typename Allocator>
85+
void dev_poll_reactor::cancel_timer_by_key(
86+
timer_queue<TimeTraits, Allocator>& queue,
87+
typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,
8288
void* cancellation_key)
8389
{
8490
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -88,10 +94,10 @@ void dev_poll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,
8894
scheduler_.post_deferred_completions(ops);
8995
}
9096

91-
template <typename Time_Traits>
92-
void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,
93-
typename timer_queue<Time_Traits>::per_timer_data& target,
94-
typename timer_queue<Time_Traits>::per_timer_data& source)
97+
template <typename TimeTraits, typename Allocator>
98+
void dev_poll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,
99+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,
100+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)
95101
{
96102
asio::detail::mutex::scoped_lock lock(mutex_);
97103
op_queue<operation> ops;

asio/include/asio/detail/impl/epoll_reactor.hpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,25 @@ inline void epoll_reactor::post_immediate_completion(
3030
scheduler_.post_immediate_completion(op, is_continuation);
3131
}
3232

33-
template <typename Time_Traits>
34-
void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
33+
template <typename TimeTraits, typename Allocator>
34+
void epoll_reactor::add_timer_queue(
35+
timer_queue<TimeTraits, Allocator>& queue)
3536
{
3637
do_add_timer_queue(queue);
3738
}
3839

39-
template <typename Time_Traits>
40-
void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
40+
template <typename TimeTraits, typename Allocator>
41+
void epoll_reactor::remove_timer_queue(
42+
timer_queue<TimeTraits, Allocator>& queue)
4143
{
4244
do_remove_timer_queue(queue);
4345
}
4446

45-
template <typename Time_Traits>
46-
void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
47-
const typename Time_Traits::time_type& time,
48-
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
47+
template <typename TimeTraits, typename Allocator>
48+
void epoll_reactor::schedule_timer(timer_queue<TimeTraits, Allocator>& queue,
49+
const typename TimeTraits::time_type& time,
50+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
51+
wait_op* op)
4952
{
5053
mutex::scoped_lock lock(mutex_);
5154

@@ -61,9 +64,10 @@ void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
6164
update_timeout();
6265
}
6366

64-
template <typename Time_Traits>
65-
std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
66-
typename timer_queue<Time_Traits>::per_timer_data& timer,
67+
template <typename TimeTraits, typename Allocator>
68+
std::size_t epoll_reactor::cancel_timer(
69+
timer_queue<TimeTraits, Allocator>& queue,
70+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,
6771
std::size_t max_cancelled)
6872
{
6973
mutex::scoped_lock lock(mutex_);
@@ -74,9 +78,10 @@ std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
7478
return n;
7579
}
7680

77-
template <typename Time_Traits>
78-
void epoll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,
79-
typename timer_queue<Time_Traits>::per_timer_data* timer,
81+
template <typename TimeTraits, typename Allocator>
82+
void epoll_reactor::cancel_timer_by_key(
83+
timer_queue<TimeTraits, Allocator>& queue,
84+
typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,
8085
void* cancellation_key)
8186
{
8287
mutex::scoped_lock lock(mutex_);
@@ -86,10 +91,10 @@ void epoll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,
8691
scheduler_.post_deferred_completions(ops);
8792
}
8893

89-
template <typename Time_Traits>
90-
void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,
91-
typename timer_queue<Time_Traits>::per_timer_data& target,
92-
typename timer_queue<Time_Traits>::per_timer_data& source)
94+
template <typename TimeTraits, typename Allocator>
95+
void epoll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,
96+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,
97+
typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)
9398
{
9499
mutex::scoped_lock lock(mutex_);
95100
op_queue<operation> ops;

0 commit comments

Comments
 (0)