MDEV-16264 - prerequisite patch, periodic thr_timer

Threadpool will need a functionality for periodic thr_timer
(the threadpool maintainence task is a timer that runs periodically).

Also increase the stack size for the timer thread, 8k won't be enough.
This commit is contained in:
Vladislav Vaintroub 2019-10-29 18:20:21 +01:00
parent 786b004972
commit ad17c98dd5
2 changed files with 32 additions and 1 deletions

View file

@ -23,6 +23,7 @@ extern "C" {
typedef struct st_timer {
struct timespec expire_time;
ulonglong period;
my_bool expired;
uint index_in_queue;
void (*func)(void*);
@ -36,6 +37,7 @@ void end_thr_timer();
/* Functions for handling one timer */
void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
void *arg);
void thr_timer_set_period(thr_timer_t* timer_data, ulonglong microseconds);
my_bool thr_timer_settime(thr_timer_t *timer_data, ulonglong microseconds);
void thr_timer_end(thr_timer_t *timer_data);

View file

@ -85,7 +85,7 @@ my_bool init_thr_timer(uint alloc_timers)
/* Create a thread to handle timers */
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
pthread_attr_setstacksize(&thr_attr,8196);
pthread_attr_setstacksize(&thr_attr,64*1024);
thr_timer_inited= 1;
if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr,
timer_handler, NULL))
@ -141,6 +141,18 @@ void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
DBUG_VOID_RETURN;
}
/*
Make timer periodic
@param timer_data Timer structure
@param micro_seconds Period
*/
void thr_timer_set_period(thr_timer_t* timer_data, ulonglong micro_seconds)
{
DBUG_ENTER("thr_timer_set_period");
timer_data->period= micro_seconds;
DBUG_VOID_RETURN;
}
/*
Request timer after X milliseconds
@ -240,18 +252,35 @@ static sig_handler process_timers(struct timespec *now)
{
void (*function)(void*);
void *func_arg;
my_bool is_periodic;
timer_data= (thr_timer_t*) queue_top(&timer_queue);
function= timer_data->func;
func_arg= timer_data->func_arg;
is_periodic= timer_data->period != 0;
timer_data->expired= 1; /* Mark expired */
/*
We remove timer before calling timer function to allow thread to
delete it's timer data any time.
Deleting timer inside the callback would not work
for periodic timers, they need to be removed from
queue prior to destroying timer_data.
*/
queue_remove_top(&timer_queue); /* Remove timer */
(*function)(func_arg); /* Inform thread of timeout */
/*
If timer is periodic, recalculate next expiration time, and
reinsert it into the queue.
*/
if (is_periodic && timer_data->period)
{
set_timespec_nsec(timer_data->expire_time, timer_data->period * 1000);
timer_data->expired= 0;
queue_insert(&timer_queue, (uchar*)timer_data);
}
/* Check if next one has also expired */
timer_data= (thr_timer_t*) queue_top(&timer_queue);
if (cmp_timespec(timer_data->expire_time, (*now)) > 0)