Commit 548bc646 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 6e60da08
...@@ -145,9 +145,14 @@ minicron_do (void *pv) ...@@ -145,9 +145,14 @@ minicron_do (void *pv)
wakeup_at.tv_nsec += (p->period_in_ms % 1000) * 1000000; wakeup_at.tv_nsec += (p->period_in_ms % 1000) * 1000000;
toku_timespec_t now; toku_timespec_t now;
toku_gettime(&now); toku_gettime(&now);
int r = toku_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at); int compare = timespec_compare(&wakeup_at, &now);
if (r!=0 && r!=ETIMEDOUT) fprintf(stderr, "%s:%d r=%d (%s)", __FILE__, __LINE__, r, strerror(r)); // if the time to wakeup has yet to come, then we sleep
assert(r==0 || r==ETIMEDOUT); // 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 // Now we woke up, and we should figure out what to do
if (p->do_shutdown) { if (p->do_shutdown) {
...@@ -161,13 +166,12 @@ minicron_do (void *pv) ...@@ -161,13 +166,12 @@ minicron_do (void *pv)
time_to_call.tv_sec += p->period_in_ms/1000; time_to_call.tv_sec += p->period_in_ms/1000;
time_to_call.tv_nsec += (p->period_in_ms % 1000) * 1000000; time_to_call.tv_nsec += (p->period_in_ms % 1000) * 1000000;
int compare = timespec_compare(&time_to_call, &now); 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) { 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); toku_mutex_unlock(&p->mutex);
int r = p->f(p->arg); int r = p->f(p->arg);
assert(r==0); assert(r==0);
toku_mutex_lock(&p->mutex); 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) { ...@@ -199,9 +199,9 @@ test4 (void *v) {
int counter = 0; int counter = 0;
ZERO_STRUCT(m); ZERO_STRUCT(m);
int r = toku_minicron_setup(&m, 2000, run_3sec, &counter); assert(r==0); 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); r = toku_minicron_shutdown(&m); assert(r==0);
assert(counter==2); assert(counter==3);
return v; return v;
} }
...@@ -212,9 +212,9 @@ test5 (void *v) { ...@@ -212,9 +212,9 @@ test5 (void *v) {
ZERO_STRUCT(m); ZERO_STRUCT(m);
int r = toku_minicron_setup(&m, 10000, run_3sec, &counter); assert(r==0); int r = toku_minicron_setup(&m, 10000, run_3sec, &counter); assert(r==0);
toku_minicron_change_period(&m, 2000); toku_minicron_change_period(&m, 2000);
sleep(9); sleep(10);
r = toku_minicron_shutdown(&m); assert(r==0); r = toku_minicron_shutdown(&m); assert(r==0);
assert(counter==2); assert(counter==3);
return v; return v;
} }
...@@ -229,6 +229,19 @@ test6 (void *v) { ...@@ -229,6 +229,19 @@ test6 (void *v) {
return 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*); typedef void*(*ptf)(void*);
int int
test_main (int argc, const char *argv[]) { test_main (int argc, const char *argv[]) {
...@@ -236,23 +249,24 @@ test_main (int argc, const char *argv[]) { ...@@ -236,23 +249,24 @@ test_main (int argc, const char *argv[]) {
gettimeofday(&starttime, 0); gettimeofday(&starttime, 0);
ptf testfuns[] = {test1, test2, test3, ptf testfuns[] = {test1, test2, test3,
test4, test4,
test5, test5,
test6 test6,
test7
}; };
#define N (sizeof(testfuns)/sizeof(testfuns[0])) #define N (sizeof(testfuns)/sizeof(testfuns[0]))
toku_pthread_t tests[N]; toku_pthread_t tests[N];
unsigned int i; unsigned int i;
for (i=0; i<N; i++) { for (i=0; i<N; i++) {
int r=toku_pthread_create(tests+i, 0, testfuns[i], 0); int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
assert(r==0); assert(r==0);
} }
for (i=0; i<N; i++) { for (i=0; i<N; i++) {
void *v; void *v;
int r=toku_pthread_join(tests[i], &v); int r=toku_pthread_join(tests[i], &v);
assert(r==0); assert(r==0);
assert(v==0); assert(v==0);
} }
return 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