Skip to content

Commit

Permalink
UCS/ASYNC: Use heap to process expired timers in batch
Browse files Browse the repository at this point in the history
  • Loading branch information
tvegas1 committed Oct 7, 2024
1 parent 27ab197 commit dfb56ec
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/ucs/async/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,19 @@ ucs_status_t ucs_async_dispatch_handlers(int *handler_ids, size_t count,
ucs_status_t ucs_async_dispatch_timerq(ucs_timer_queue_t *timerq,
ucs_time_t current_time)
{
size_t max_timers, num_timers = 0;
size_t num_timers = 0;
ucs_status_t status;
size_t max_timers, size;
int *expired_timers;
ucs_timer_t *timer;

max_timers = ucs_max(1, ucs_timerq_size(timerq));
expired_timers = ucs_alloca(max_timers * sizeof(*expired_timers));
max_timers = ucs_max(1, ucs_timerq_size(timerq));
size = max_timers * sizeof(*expired_timers);

expired_timers = ucs_alloc_on_stack(size, "async_dispatch_timerq");
if (expired_timers == NULL) {
return UCS_ERR_NO_MEMORY;
}

ucs_timerq_for_each_expired(timer, timerq, current_time, {
expired_timers[num_timers++] = timer->id;
Expand All @@ -346,8 +353,10 @@ ucs_status_t ucs_async_dispatch_timerq(ucs_timer_queue_t *timerq,
}
})

return ucs_async_dispatch_handlers(expired_timers, num_timers,
UCS_ASYNC_EVENT_DUMMY);
status = ucs_async_dispatch_handlers(expired_timers, num_timers,
UCS_ASYNC_EVENT_DUMMY);
ucs_free_on_stack(expired_timers, size);
return status;
}

ucs_status_t ucs_async_context_init(ucs_async_context_t *async, ucs_async_mode_t mode)
Expand Down
20 changes: 20 additions & 0 deletions src/ucs/sys/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@
} \
}

/**
* Use stack or heap allocation depending on size. Free function @ref
* ucs_free_on_stack must always be called.
*/
#define ucs_alloc_on_stack(_size, _name) \
({ \
size_t _sz = (_size); \
(_sz <= UCS_ALLOCA_MAX_SIZE) ? alloca(_sz) : ucs_malloc(_sz, _name); \
})

/**
* Release function to be paired with @ref ucs_alloc_on_stack.
*/
#define ucs_free_on_stack(_ptr, _size) \
({ \
if ((_size) > UCS_ALLOCA_MAX_SIZE) { \
ucs_free(_ptr); \
} \
})

/**
* alloca which makes sure the size is small enough.
*/
Expand Down

0 comments on commit dfb56ec

Please sign in to comment.