Commit ad17c98d authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

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.
parent 786b0049
...@@ -23,6 +23,7 @@ extern "C" { ...@@ -23,6 +23,7 @@ extern "C" {
typedef struct st_timer { typedef struct st_timer {
struct timespec expire_time; struct timespec expire_time;
ulonglong period;
my_bool expired; my_bool expired;
uint index_in_queue; uint index_in_queue;
void (*func)(void*); void (*func)(void*);
...@@ -36,6 +37,7 @@ void end_thr_timer(); ...@@ -36,6 +37,7 @@ void end_thr_timer();
/* Functions for handling one timer */ /* Functions for handling one timer */
void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*), void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
void *arg); 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); my_bool thr_timer_settime(thr_timer_t *timer_data, ulonglong microseconds);
void thr_timer_end(thr_timer_t *timer_data); void thr_timer_end(thr_timer_t *timer_data);
......
...@@ -85,7 +85,7 @@ my_bool init_thr_timer(uint alloc_timers) ...@@ -85,7 +85,7 @@ my_bool init_thr_timer(uint alloc_timers)
/* Create a thread to handle timers */ /* Create a thread to handle timers */
pthread_attr_init(&thr_attr); pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); 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; thr_timer_inited= 1;
if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr, if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr,
timer_handler, NULL)) timer_handler, NULL))
...@@ -141,6 +141,18 @@ void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*), ...@@ -141,6 +141,18 @@ void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
DBUG_VOID_RETURN; 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 Request timer after X milliseconds
...@@ -240,18 +252,35 @@ static sig_handler process_timers(struct timespec *now) ...@@ -240,18 +252,35 @@ static sig_handler process_timers(struct timespec *now)
{ {
void (*function)(void*); void (*function)(void*);
void *func_arg; void *func_arg;
my_bool is_periodic;
timer_data= (thr_timer_t*) queue_top(&timer_queue); timer_data= (thr_timer_t*) queue_top(&timer_queue);
function= timer_data->func; function= timer_data->func;
func_arg= timer_data->func_arg; func_arg= timer_data->func_arg;
is_periodic= timer_data->period != 0;
timer_data->expired= 1; /* Mark expired */ timer_data->expired= 1; /* Mark expired */
/* /*
We remove timer before calling timer function to allow thread to We remove timer before calling timer function to allow thread to
delete it's timer data any time. 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 */ queue_remove_top(&timer_queue); /* Remove timer */
(*function)(func_arg); /* Inform thread of timeout */ (*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 */ /* Check if next one has also expired */
timer_data= (thr_timer_t*) queue_top(&timer_queue); timer_data= (thr_timer_t*) queue_top(&timer_queue);
if (cmp_timespec(timer_data->expire_time, (*now)) > 0) if (cmp_timespec(timer_data->expire_time, (*now)) > 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment