Commit 91fd4931 authored by Yoni Fogel's avatar Yoni Fogel

Windows ports Addresses #1665

git-svn-id: file:///svn/toku/tokudb@11337 c7de825b-a66e-492c-adef-691d508d4ae1
parent fe30f599
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "minicron.h" #include "minicron.h"
static void static void
toku_gettime (struct timespec *a) { toku_gettime (toku_timespec_t *a) {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
a->tv_sec = tv.tv_sec; a->tv_sec = tv.tv_sec;
...@@ -20,7 +20,7 @@ toku_gettime (struct timespec *a) { ...@@ -20,7 +20,7 @@ toku_gettime (struct timespec *a) {
static int static int
timespec_compare (struct timespec *a, struct timespec *b) { timespec_compare (toku_timespec_t *a, toku_timespec_t *b) {
if (a->tv_sec > b->tv_sec) return 1; if (a->tv_sec > b->tv_sec) return 1;
if (a->tv_sec < b->tv_sec) return -1; if (a->tv_sec < b->tv_sec) return -1;
if (a->tv_nsec > b->tv_nsec) return 1; if (a->tv_nsec > b->tv_nsec) return 1;
...@@ -51,9 +51,9 @@ minicron_do (void *pv) ...@@ -51,9 +51,9 @@ minicron_do (void *pv)
assert(r==0); assert(r==0);
} else { } else {
// Recompute the wakeup time every time (instead of once per call to f) in case the period changges. // Recompute the wakeup time every time (instead of once per call to f) in case the period changges.
struct timespec wakeup_at = p->time_of_last_call_to_f; toku_timespec_t wakeup_at = p->time_of_last_call_to_f;
wakeup_at.tv_sec += p->period_in_seconds; wakeup_at.tv_sec += p->period_in_seconds;
struct timespec now; toku_timespec_t now;
toku_gettime(&now); toku_gettime(&now);
//printf("wakeup at %.6f (after %d seconds) now=%.6f\n", wakeup_at.tv_sec + wakeup_at.tv_nsec*1e-9, p->period_in_seconds, now.tv_sec + now.tv_nsec*1e-9); //printf("wakeup at %.6f (after %d seconds) now=%.6f\n", wakeup_at.tv_sec + wakeup_at.tv_nsec*1e-9, p->period_in_seconds, now.tv_sec + now.tv_nsec*1e-9);
r = toku_pthread_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at); r = toku_pthread_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at);
...@@ -68,9 +68,9 @@ minicron_do (void *pv) ...@@ -68,9 +68,9 @@ minicron_do (void *pv)
} }
if (p->period_in_seconds >0) { if (p->period_in_seconds >0) {
// maybe do a checkpoint // maybe do a checkpoint
struct timespec now; toku_timespec_t now;
toku_gettime(&now); toku_gettime(&now);
struct timespec time_to_call = p->time_of_last_call_to_f; toku_timespec_t time_to_call = p->time_of_last_call_to_f;
time_to_call.tv_sec += p->period_in_seconds; time_to_call.tv_sec += p->period_in_seconds;
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); //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);
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
struct minicron { struct minicron {
toku_pthread_t thread; toku_pthread_t thread;
struct timespec time_of_last_call_to_f; toku_timespec_t time_of_last_call_to_f;
toku_pthread_mutex_t mutex; toku_pthread_mutex_t mutex;
toku_pthread_cond_t condvar; toku_pthread_cond_t condvar;
int (*f)(void*); int (*f)(void*);
......
...@@ -16,12 +16,25 @@ static const int item_size = sizeof(int); ...@@ -16,12 +16,25 @@ static const int item_size = sizeof(int);
static volatile int n_flush, n_write_me, n_keep_me, n_fetch; 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 static void
sleep_random (void) sleep_random (void)
{ {
struct timespec req = {.tv_sec = 0, #if TOKU_WINDOWS
sleep(1);
#else
toku_timespec_t req = {.tv_sec = 0,
.tv_nsec = random()%1000000}; .tv_nsec = random()%1000000};
nanosleep(&req, NULL); nanosleep(&req, NULL);
#endif
} }
int expect_value = 42; // initially 42, later 43 int expect_value = 42; // initially 42, later 43
...@@ -111,11 +124,11 @@ static void checkpoint_pending(void) { ...@@ -111,11 +124,11 @@ static void checkpoint_pending(void) {
// all items should be kept in the cachetable // all items should be kept in the cachetable
n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 42; n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 42;
//printf("E42\n"); //printf("E42\n");
pthread_t checkpoint_thread, update_thread; toku_pthread_t checkpoint_thread, update_thread;
r = pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0); r = toku_pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0);
r = pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0); r = toku_pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0);
r = pthread_join(checkpoint_thread, 0); assert(r==0); r = toku_pthread_join(checkpoint_thread, 0); assert(r==0);
r = pthread_join(update_thread, 0); assert(r==0); r = toku_pthread_join(update_thread, 0); assert(r==0);
assert(n_flush == N && n_write_me == N && n_keep_me == N); assert(n_flush == N && n_write_me == N && n_keep_me == N);
......
#include "toku_portability.h"
#include "minicron.h" #include "minicron.h"
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
...@@ -39,6 +40,9 @@ static int __attribute__((__noreturn__)) ...@@ -39,6 +40,9 @@ static int __attribute__((__noreturn__))
never_run (void *a) { never_run (void *a) {
assert(a==0); assert(a==0);
assert(0); assert(0);
#if TOKU_WINDOWS
return 0; //ICC ignores the noreturn attribute.
#endif
} }
// Can we start something with period=0 (the function should never run) and shut it down. // Can we start something with period=0 (the function should never run) and shut it down.
...@@ -153,7 +157,7 @@ main (int argc, const char *argv[]) ...@@ -153,7 +157,7 @@ main (int argc, const char *argv[])
test6 test6
}; };
#define N (sizeof(testfuns)/sizeof(testfuns[0])) #define N (sizeof(testfuns)/sizeof(testfuns[0]))
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++) {
......
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
toku_stat; toku_stat;
toku_fstat; toku_fstat;
toku_tdiff;
local: *; local: *;
}; };
...@@ -136,7 +136,7 @@ setup_data(void) { ...@@ -136,7 +136,7 @@ setup_data(void) {
length[i] = i * MAX_LENGTH / (NUM-1); length[i] = i * MAX_LENGTH / (NUM-1);
u_int32_t j; u_int32_t j;
for (j = 0; j < length[i]; j++) { for (j = 0; j < length[i]; j++) {
data[i][j] = random() & 0xFF; data[i][j] = (u_int8_t)(random() & 0xFF);
} }
memset(&descriptors[i], 0, sizeof(descriptors[i])); memset(&descriptors[i], 0, sizeof(descriptors[i]));
descriptors[i].size = length[i]; descriptors[i].size = length[i];
......
...@@ -90,6 +90,7 @@ typedef int64_t toku_off_t; ...@@ -90,6 +90,7 @@ typedef int64_t toku_off_t;
# pragma poison pthread_mutexattr_t pthread_mutex_t # pragma poison pthread_mutexattr_t pthread_mutex_t
# pragma poison pthread_condattr_t pthread_cond_t # pragma poison pthread_condattr_t pthread_cond_t
# pragma poison pthread_rwlockattr_t pthread_rwlock_t # pragma poison pthread_rwlockattr_t pthread_rwlock_t
# pragma poison timespec
# ifndef DONT_DEPRECATE_MALLOC # ifndef DONT_DEPRECATE_MALLOC
# pragma deprecated (malloc, free, realloc) # pragma deprecated (malloc, free, realloc)
# endif # endif
......
...@@ -205,6 +205,7 @@ toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) { ...@@ -205,6 +205,7 @@ toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) {
cond->waiters++; cond->waiters++;
toku_pthread_mutex_unlock(mutex); toku_pthread_mutex_unlock(mutex);
r = WaitForMultipleObjects(TOKU_PTHREAD_COND_NEVENTS, cond->events, FALSE, INFINITE); r = WaitForMultipleObjects(TOKU_PTHREAD_COND_NEVENTS, cond->events, FALSE, INFINITE);
assert(r!=WAIT_FAILED);
toku_pthread_mutex_lock(mutex); toku_pthread_mutex_lock(mutex);
cond->waiters--; cond->waiters--;
if (cond->waiters == 0 && r == WAIT_OBJECT_0 + 1) if (cond->waiters == 0 && r == WAIT_OBJECT_0 + 1)
...@@ -212,6 +213,31 @@ toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) { ...@@ -212,6 +213,31 @@ toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) {
return 0; return 0;
} }
int toku_pthread_cond_timedwait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex, toku_timespec_t *wakeup_at) {
toku_timespec_t current;
int rclock = clock_gettime(CLOCK_REALTIME, &current);
assert(rclock==0);
int64_t milliseconds_wakeup = wakeup_at->tv_sec * 1000 + wakeup_at->tv_nsec / 1000000;
int64_t milliseconds_current = wakeup_at->tv_sec * 1000 + wakeup_at->tv_nsec / 1000000;
int64_t milli_diff = milliseconds_wakeup - milliseconds_current;
DWORD milliseconds_wait;
if (milli_diff <= 0) milliseconds_wait = 1; //Never sleep for 0.
else milliseconds_wait = milli_diff;
DWORD r;
cond->waiters++;
toku_pthread_mutex_unlock(mutex);
r = WaitForMultipleObjects(TOKU_PTHREAD_COND_NEVENTS, cond->events, FALSE, milliseconds_wait);
assert(r!=WAIT_FAILED);
toku_pthread_mutex_lock(mutex);
cond->waiters--;
if (cond->waiters == 0 && r == WAIT_OBJECT_0 + 1)
ResetEvent(cond->events[1]);
if (r==WAIT_TIMEOUT) r = ETIMEDOUT;
else r = 0;
return r;
}
int int
toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) { toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) {
if (cond->waiters > 0) if (cond->waiters > 0)
......
...@@ -5,8 +5,14 @@ ...@@ -5,8 +5,14 @@
extern "C" { extern "C" {
#endif #endif
#include <toku_time.h>
#include <windows.h> #include <windows.h>
#if defined(ETIMEDOUT)
#error
#endif
#define ETIMEDOUT (WAIT_TIMEOUT)
// pthread types // pthread types
typedef struct toku_pthread_attr { typedef struct toku_pthread_attr {
...@@ -87,12 +93,14 @@ int toku_pthread_cond_destroy(toku_pthread_cond_t *cond); ...@@ -87,12 +93,14 @@ int toku_pthread_cond_destroy(toku_pthread_cond_t *cond);
int toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex); int toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex);
int toku_pthread_cond_timedwait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex, toku_timespec_t *wakeup_at);
int toku_pthread_cond_signal(toku_pthread_cond_t *cond); int toku_pthread_cond_signal(toku_pthread_cond_t *cond);
int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond); int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond);
#include <toku_assert.h> #include <toku_assert.h>
#include "rwlock.h" #include "../newbrt/rwlock.h"
struct toku_pthread_rwlock { struct toku_pthread_rwlock {
struct rwlock rwlock; struct rwlock rwlock;
toku_pthread_mutex_t mutex; toku_pthread_mutex_t mutex;
......
...@@ -23,7 +23,7 @@ gettimeofday(struct timeval *tv, struct timezone *tz) { ...@@ -23,7 +23,7 @@ gettimeofday(struct timeval *tv, struct timezone *tz) {
} }
static int static int
clock_get_realtime(struct timespec *ts) { clock_get_realtime(toku_timespec_t *ts) {
FILETIME ft; FILETIME ft;
ULARGE_INTEGER t; ULARGE_INTEGER t;
...@@ -40,7 +40,7 @@ clock_get_realtime(struct timespec *ts) { ...@@ -40,7 +40,7 @@ clock_get_realtime(struct timespec *ts) {
} }
int int
clock_gettime(clockid_t clockid, struct timespec *ts) { clock_gettime(clockid_t clockid, toku_timespec_t *ts) {
if (clockid == CLOCK_REALTIME) if (clockid == CLOCK_REALTIME)
return clock_get_realtime(ts); return clock_get_realtime(ts);
else else
......
...@@ -19,12 +19,12 @@ typedef enum { ...@@ -19,12 +19,12 @@ typedef enum {
CLOCK_REALTIME = 0 CLOCK_REALTIME = 0
} clockid_t; } clockid_t;
struct timespec { typedef struct toku_timespec_struct {
long tv_sec; long tv_sec;
long tv_nsec; long tv_nsec;
}; } toku_timespec_t;
int clock_gettime(clockid_t clock_id, struct timespec *ts); int clock_gettime(clockid_t clock_id, toku_timespec_t *ts);
static inline float toku_tdiff (struct timeval *a, struct timeval *b) { static inline float toku_tdiff (struct timeval *a, struct timeval *b) {
return (a->tv_sec - b->tv_sec) +1e-6*(a->tv_usec - b->tv_usec); return (a->tv_sec - b->tv_sec) +1e-6*(a->tv_usec - b->tv_usec);
......
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