// Make sure that the pending stuff gets checkpointed, but subsequent changes don't, even with concurrent updates. #include #include #include #include "test.h" #include "checkpoint.h" static int N; // how many items in the table static CACHEFILE cf; static CACHETABLE ct; int *values; static const int item_size = sizeof(int); static volatile int n_flush, n_write_me, n_keep_me, n_fetch; #if TOKU_WINDOWS //This is NOT correct, but close enough for now. //Obviously has race conditions. static void __sync_fetch_and_add(volatile int *num, int incr) { *num += incr; } #endif static void sleep_random (void) { #if TOKU_WINDOWS sleep(1); #else toku_timespec_t req = {.tv_sec = 0, .tv_nsec = random()%1000000}; nanosleep(&req, NULL); #endif } int expect_value = 42; // initially 42, later 43 static void flush (CACHEFILE UU(thiscf), CACHEKEY UU(key), void *value, void *UU(extraargs), long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) { // printf("f"); assert(size == item_size); int *v = value; if (*v!=expect_value) printf("got %d expect %d\n", *v, expect_value); assert(*v==expect_value); (void)__sync_fetch_and_add(&n_flush, 1); if (write_me) (void)__sync_fetch_and_add(&n_write_me, 1); if (keep_me) (void)__sync_fetch_and_add(&n_keep_me, 1); sleep_random(); } static int fetch (CACHEFILE UU(thiscf), CACHEKEY UU(key), u_int32_t UU(fullhash), void **UU(value), long *UU(sizep), void *UU(extraargs)) { assert(0); // should not be called return 0; } static void* do_update (void *UU(ignore)) { while (n_flush==0); // wait until the first checkpoint ran int i; for (i=0; i