Commit dc0f5e04 authored by Zardosht Kasheff's avatar Zardosht Kasheff

refs #78 for minicrons with a period of longer than one second (checkpoints),

change minicron to count the period from the beginning of
the callback's execution and not the end. For checkpoints, this makes them
reliably start every 60 seconds.
parent 499645d4
......@@ -145,9 +145,14 @@ minicron_do (void *pv)
wakeup_at.tv_nsec += (p->period_in_ms % 1000) * 1000000;
toku_timespec_t now;
toku_gettime(&now);
int r = toku_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at);
if (r!=0 && r!=ETIMEDOUT) fprintf(stderr, "%s:%d r=%d (%s)", __FILE__, __LINE__, r, strerror(r));
assert(r==0 || r==ETIMEDOUT);
int compare = timespec_compare(&wakeup_at, &now);
// if the time to wakeup has yet to come, then we sleep
// otherwise, we continue
if (compare > 0) {
int r = toku_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at);
if (r!=0 && r!=ETIMEDOUT) fprintf(stderr, "%s:%d r=%d (%s)", __FILE__, __LINE__, r, strerror(r));
assert(r==0 || r==ETIMEDOUT);
}
}
// Now we woke up, and we should figure out what to do
if (p->do_shutdown) {
......@@ -161,13 +166,12 @@ minicron_do (void *pv)
time_to_call.tv_sec += p->period_in_ms/1000;
time_to_call.tv_nsec += (p->period_in_ms % 1000) * 1000000;
int compare = timespec_compare(&time_to_call, &now);
//printf("compare(%.6f, %.6f)=%d\n", time_to_call.tv_sec + time_to_call.tv_nsec*1e-9, now.tv_sec+now.tv_nsec*1e-9, compare);
if (compare <= 0) {
toku_gettime(&p->time_of_last_call_to_f); // the measured period includes the time to make the call.
toku_mutex_unlock(&p->mutex);
int r = p->f(p->arg);
assert(r==0);
toku_mutex_lock(&p->mutex);
toku_gettime(&p->time_of_last_call_to_f); // the period is measured between calls to f.
}
}
......
......@@ -199,9 +199,9 @@ test4 (void *v) {
int counter = 0;
ZERO_STRUCT(m);
int r = toku_minicron_setup(&m, 2000, run_3sec, &counter); assert(r==0);
sleep(9);
sleep(10);
r = toku_minicron_shutdown(&m); assert(r==0);
assert(counter==2);
assert(counter==3);
return v;
}
......@@ -212,9 +212,9 @@ test5 (void *v) {
ZERO_STRUCT(m);
int r = toku_minicron_setup(&m, 10000, run_3sec, &counter); assert(r==0);
toku_minicron_change_period(&m, 2000);
sleep(9);
sleep(10);
r = toku_minicron_shutdown(&m); assert(r==0);
assert(counter==2);
assert(counter==3);
return v;
}
......@@ -229,6 +229,19 @@ test6 (void *v) {
return v;
}
// test that we actually run once per period, even if the execution is long
static void*
test7 (void *v) {
struct minicron m;
int counter = 0;
ZERO_STRUCT(m);
int r = toku_minicron_setup(&m, 5000, run_3sec, &counter); assert(r==0);
sleep(17);
r = toku_minicron_shutdown(&m); assert(r==0);
assert(counter==3);
return v;
}
typedef void*(*ptf)(void*);
int
test_main (int argc, const char *argv[]) {
......@@ -236,23 +249,24 @@ test_main (int argc, const char *argv[]) {
gettimeofday(&starttime, 0);
ptf testfuns[] = {test1, test2, test3,
test4,
test5,
test6
test4,
test5,
test6,
test7
};
#define N (sizeof(testfuns)/sizeof(testfuns[0]))
toku_pthread_t tests[N];
unsigned int i;
for (i=0; i<N; i++) {
int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
assert(r==0);
int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
assert(r==0);
}
for (i=0; i<N; i++) {
void *v;
int r=toku_pthread_join(tests[i], &v);
assert(r==0);
assert(v==0);
void *v;
int r=toku_pthread_join(tests[i], &v);
assert(r==0);
assert(v==0);
}
return 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