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 @@
#include "minicron.h"
static void
toku_gettime (struct timespec *a) {
toku_gettime (toku_timespec_t *a) {
struct timeval tv;
gettimeofday(&tv, 0);
a->tv_sec = tv.tv_sec;
......@@ -20,7 +20,7 @@ toku_gettime (struct timespec *a) {
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_nsec > b->tv_nsec) return 1;
......@@ -51,9 +51,9 @@ minicron_do (void *pv)
assert(r==0);
} else {
// 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;
struct timespec now;
toku_timespec_t 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);
r = toku_pthread_cond_timedwait(&p->condvar, &p->mutex, &wakeup_at);
......@@ -68,9 +68,9 @@ minicron_do (void *pv)
}
if (p->period_in_seconds >0) {
// maybe do a checkpoint
struct timespec now;
toku_timespec_t 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;
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);
......
......@@ -23,7 +23,7 @@
struct minicron {
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_cond_t condvar;
int (*f)(void*);
......
......@@ -16,12 +16,25 @@ 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)
{
struct timespec req = {.tv_sec = 0,
#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
......@@ -111,11 +124,11 @@ static void checkpoint_pending(void) {
// all items should be kept in the cachetable
n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 42;
//printf("E42\n");
pthread_t checkpoint_thread, update_thread;
r = pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0);
r = pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0);
r = pthread_join(checkpoint_thread, 0); assert(r==0);
r = pthread_join(update_thread, 0); assert(r==0);
toku_pthread_t checkpoint_thread, update_thread;
r = toku_pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0);
r = toku_pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0);
r = toku_pthread_join(checkpoint_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);
......
#include "toku_portability.h"
#include "minicron.h"
#include <unistd.h>
#include <assert.h>
......@@ -39,6 +40,9 @@ static int __attribute__((__noreturn__))
never_run (void *a) {
assert(a==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.
......@@ -153,7 +157,7 @@ main (int argc, const char *argv[])
test6
};
#define N (sizeof(testfuns)/sizeof(testfuns[0]))
pthread_t tests[N];
toku_pthread_t tests[N];
unsigned int i;
for (i=0; i<N; i++) {
......
......@@ -47,8 +47,6 @@
toku_stat;
toku_fstat;
toku_tdiff;
local: *;
};
......@@ -136,7 +136,7 @@ setup_data(void) {
length[i] = i * MAX_LENGTH / (NUM-1);
u_int32_t 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]));
descriptors[i].size = length[i];
......
......@@ -90,6 +90,7 @@ typedef int64_t toku_off_t;
# pragma poison pthread_mutexattr_t pthread_mutex_t
# pragma poison pthread_condattr_t pthread_cond_t
# pragma poison pthread_rwlockattr_t pthread_rwlock_t
# pragma poison timespec
# ifndef DONT_DEPRECATE_MALLOC
# pragma deprecated (malloc, free, realloc)
# endif
......
......@@ -205,6 +205,7 @@ toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) {
cond->waiters++;
toku_pthread_mutex_unlock(mutex);
r = WaitForMultipleObjects(TOKU_PTHREAD_COND_NEVENTS, cond->events, FALSE, INFINITE);
assert(r!=WAIT_FAILED);
toku_pthread_mutex_lock(mutex);
cond->waiters--;
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) {
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
toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) {
if (cond->waiters > 0)
......
......@@ -5,8 +5,14 @@
extern "C" {
#endif
#include <toku_time.h>
#include <windows.h>
#if defined(ETIMEDOUT)
#error
#endif
#define ETIMEDOUT (WAIT_TIMEOUT)
// pthread types
typedef struct toku_pthread_attr {
......@@ -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_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_broadcast(toku_pthread_cond_t *cond);
#include <toku_assert.h>
#include "rwlock.h"
#include "../newbrt/rwlock.h"
struct toku_pthread_rwlock {
struct rwlock rwlock;
toku_pthread_mutex_t mutex;
......
......@@ -23,7 +23,7 @@ gettimeofday(struct timeval *tv, struct timezone *tz) {
}
static int
clock_get_realtime(struct timespec *ts) {
clock_get_realtime(toku_timespec_t *ts) {
FILETIME ft;
ULARGE_INTEGER t;
......@@ -40,7 +40,7 @@ clock_get_realtime(struct timespec *ts) {
}
int
clock_gettime(clockid_t clockid, struct timespec *ts) {
clock_gettime(clockid_t clockid, toku_timespec_t *ts) {
if (clockid == CLOCK_REALTIME)
return clock_get_realtime(ts);
else
......
......@@ -19,12 +19,12 @@ typedef enum {
CLOCK_REALTIME = 0
} clockid_t;
struct timespec {
typedef struct toku_timespec_struct {
long tv_sec;
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) {
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