Skip to content

Commit

Permalink
MDEV-16264 - prerequisite patch, periodic thr_timer
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vaintroub committed Nov 15, 2019
1 parent 786b004 commit ad17c98
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/thr_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand All @@ -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);

Expand Down
31 changes: 30 additions & 1 deletion mysys/thr_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit ad17c98

Please sign in to comment.