Commit 0802f023 authored by Yoni Fogel's avatar Yoni Fogel

Merge 2.0.0 back into main

svn merge --accept=postpone -r 12123:12373 ../../mysql.branches/2.0.0/tokudb/

git-svn-id: file:///svn/toku/tokudb@12375 c7de825b-a66e-492c-adef-691d508d4ae1
parent b2113fb3
...@@ -13,6 +13,8 @@ DEPEND_COMPILE += \ ...@@ -13,6 +13,8 @@ DEPEND_COMPILE += \
HERE = cxx/tests HERE = cxx/tests
include $(TOKUROOT)toku_include/Makefile.include include $(TOKUROOT)toku_include/Makefile.include
SHELL=/bin/bash #Use of &> is a bash feature
SHOULD_FAIL = SHOULD_FAIL =
$(SHOULD_FAIL): MAYBEINVERTER=;test $$? -ne 0 $(SHOULD_FAIL): MAYBEINVERTER=;test $$? -ne 0
......
...@@ -14,6 +14,29 @@ ...@@ -14,6 +14,29 @@
#include <assert.h> #include <assert.h>
#include <toku_portability.h> #include <toku_portability.h>
#include "toku_os.h" #include "toku_os.h"
#include <malloc.h>
static int
toku_mallopt_init(void) {
int r = mallopt(M_MMAP_THRESHOLD, 1024*64); // 64K and larger should be malloced with mmap().
return r;
}
int
toku_portability_init(void) {
int r = 0;
if (r==0) {
int success = toku_mallopt_init(); //mallopt returns 1 on success, 0 on error
assert(success);
}
return r;
}
int
toku_portability_destroy(void) {
int r = 0;
return r;
}
int int
toku_os_getpid(void) { toku_os_getpid(void) {
......
# -*- Mode: Makefile -*- # -*- Mode: Makefile -*-
CPPFLAGS = -D_GNU_SOURCE CPPFLAGS = -D_GNU_SOURCE
CPPFLAGS += -I../../toku_include -I.. CPPFLAGS += -I../../toku_include -I.. -I.
CFLAGS = -Wall -Werror -g -O0 -std=c99 CFLAGS = -Wall -Werror -g -O0 -std=c99
LDFLAGS = ../libtokuportability.a -lpthread LDFLAGS = ../libtokuportability.a -lpthread
SRCS = $(wildcard test-*.c) SRCS = $(wildcard test-*.c)
......
../../windows/tests/test.h
\ No newline at end of file
...@@ -51,7 +51,7 @@ toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) { ...@@ -51,7 +51,7 @@ toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock); return pthread_rwlock_unlock(rwlock);
} }
int toku_pthread_yield(void); int toku_pthread_yield(void) __attribute__((__visibility__("default")));
static inline static inline
int toku_pthread_attr_init(toku_pthread_attr_t *attr) { int toku_pthread_attr_init(toku_pthread_attr_t *attr) {
......
...@@ -29,12 +29,14 @@ static inline u_int64_t alignup (u_int64_t a, u_int64_t b) { ...@@ -29,12 +29,14 @@ static inline u_int64_t alignup (u_int64_t a, u_int64_t b) {
static toku_pthread_mutex_t pwrite_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER; static toku_pthread_mutex_t pwrite_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
static int pwrite_is_locked=0; static int pwrite_is_locked=0;
void toku_pwrite_lock_init(void) { int toku_pwrite_lock_init(void) {
int r = toku_pthread_mutex_init(&pwrite_mutex, NULL); assert(r == 0); int r = toku_pthread_mutex_init(&pwrite_mutex, NULL); assert(r == 0);
return r;
} }
void toku_pwrite_lock_destroy(void) { int toku_pwrite_lock_destroy(void) {
int r = toku_pthread_mutex_destroy(&pwrite_mutex); assert(r == 0); int r = toku_pthread_mutex_destroy(&pwrite_mutex); assert(r == 0);
return r;
} }
static inline void static inline void
......
...@@ -4796,25 +4796,50 @@ int toku_brt_truncate (BRT brt) { ...@@ -4796,25 +4796,50 @@ int toku_brt_truncate (BRT brt) {
return r; return r;
} }
static void toku_brt_lock_init(void) { static int
toku_pwrite_lock_init(); toku_brt_lock_init(void) {
toku_logger_lock_init(); int r = 0;
toku_leaflock_init(); if (r==0)
r = toku_pwrite_lock_init();
if (r==0)
r = toku_logger_lock_init();
if (r==0)
r = toku_leaflock_init();
return r;
} }
static void toku_brt_lock_destroy(void) { static int
toku_pwrite_lock_destroy(); toku_brt_lock_destroy(void) {
toku_logger_lock_destroy(); int r = 0;
toku_leaflock_destroy(); if (r==0)
r = toku_pwrite_lock_destroy();
if (r==0)
r = toku_logger_lock_destroy();
if (r==0)
r = toku_leaflock_destroy();
return r;
} }
void toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) { int toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) {
toku_brt_lock_init(); int r = 0;
toku_checkpoint_init(ydb_lock_callback, ydb_unlock_callback); //Portability must be initialized first
if (r==0)
r = toku_portability_init();
if (r==0)
r = toku_brt_lock_init();
if (r==0)
r = toku_checkpoint_init(ydb_lock_callback, ydb_unlock_callback);
return r;
} }
void toku_brt_destroy(void) { int toku_brt_destroy(void) {
toku_brt_lock_destroy(); int r = 0;
if (r==0)
r = toku_brt_lock_destroy();
//Portability must be cleaned up last
if (r==0)
r = toku_portability_destroy();
return r;
} }
//Return TRUE if empty, FALSE if not empty. //Return TRUE if empty, FALSE if not empty.
......
...@@ -141,10 +141,10 @@ int toku_brt_stat64 (BRT, TOKUTXN, ...@@ -141,10 +141,10 @@ int toku_brt_stat64 (BRT, TOKUTXN,
u_int64_t *fsize /* the size of the underlying file */ u_int64_t *fsize /* the size of the underlying file */
); );
void toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)); int toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
void toku_brt_destroy(void); int toku_brt_destroy(void);
void toku_pwrite_lock_init(void); int toku_pwrite_lock_init(void);
void toku_pwrite_lock_destroy(void); int toku_pwrite_lock_destroy(void);
void toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used); void toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used);
// Effect: truncate file if overallocated by at least 32MiB // Effect: truncate file if overallocated by at least 32MiB
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h>
#include <time.h> #include <time.h>
#include <toku_portability.h> #include <toku_portability.h>
...@@ -228,15 +227,6 @@ u_int32_t toku_get_checkpoint_period (CACHETABLE ct) { ...@@ -228,15 +227,6 @@ u_int32_t toku_get_checkpoint_period (CACHETABLE ct) {
} }
int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN UU(initial_lsn), TOKULOGGER logger) { int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN UU(initial_lsn), TOKULOGGER logger) {
#if defined __linux__
{
static int did_mallopt = 0;
if (!did_mallopt) {
mallopt(M_MMAP_THRESHOLD, 1024*64); // 64K and larger should be malloced with mmap().
did_mallopt = 1;
}
}
#endif
TAGMALLOC(CACHETABLE, ct); TAGMALLOC(CACHETABLE, ct);
if (ct == 0) return ENOMEM; if (ct == 0) return ENOMEM;
memset(ct, 0, sizeof(*ct)); memset(ct, 0, sizeof(*ct));
......
...@@ -69,16 +69,18 @@ static void (*ydb_unlock)(void) = NULL; ...@@ -69,16 +69,18 @@ static void (*ydb_unlock)(void) = NULL;
// and use the "writer" calls for locking and unlocking. // and use the "writer" calls for locking and unlocking.
static void static int
multi_operation_lock_init(void) { multi_operation_lock_init(void) {
int r = toku_pthread_rwlock_init(&multi_operation_lock, NULL); int r = toku_pthread_rwlock_init(&multi_operation_lock, NULL);
assert(r == 0); assert(r == 0);
return r;
} }
static void static int
multi_operation_lock_destroy(void) { multi_operation_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&multi_operation_lock); int r = toku_pthread_rwlock_destroy(&multi_operation_lock);
assert(r == 0); assert(r == 0);
return r;
} }
static void static void
...@@ -94,16 +96,18 @@ multi_operation_checkpoint_unlock(void) { ...@@ -94,16 +96,18 @@ multi_operation_checkpoint_unlock(void) {
} }
static void static int
checkpoint_safe_lock_init(void) { checkpoint_safe_lock_init(void) {
int r = toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL); int r = toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL);
assert(r == 0); assert(r == 0);
return r;
} }
static void static int
checkpoint_safe_lock_destroy(void) { checkpoint_safe_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&checkpoint_safe_lock); int r = toku_pthread_rwlock_destroy(&checkpoint_safe_lock);
assert(r == 0); assert(r == 0);
return r;
} }
static void static void
...@@ -150,19 +154,29 @@ toku_checkpoint_safe_client_unlock(void) { ...@@ -150,19 +154,29 @@ toku_checkpoint_safe_client_unlock(void) {
static BOOL initialized = FALSE; static BOOL initialized = FALSE;
// Initialize the checkpoint mechanism, must be called before any client operations. // Initialize the checkpoint mechanism, must be called before any client operations.
void int
toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) { toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) {
int r = 0;
ydb_lock = ydb_lock_callback; ydb_lock = ydb_lock_callback;
ydb_unlock = ydb_unlock_callback; ydb_unlock = ydb_unlock_callback;
multi_operation_lock_init(); if (r==0)
checkpoint_safe_lock_init(); r = multi_operation_lock_init();
initialized = TRUE; if (r==0)
r = checkpoint_safe_lock_init();
if (r==0)
initialized = TRUE;
return r;
} }
void toku_checkpoint_destroy(void) { int
multi_operation_lock_destroy(); toku_checkpoint_destroy(void) {
checkpoint_safe_lock_destroy(); int r = 0;
if (r==0)
r = multi_operation_lock_destroy();
if (r==0)
r = checkpoint_safe_lock_destroy();
initialized = FALSE; initialized = FALSE;
return r;
} }
......
...@@ -47,9 +47,9 @@ void toku_multi_operation_client_unlock(void); ...@@ -47,9 +47,9 @@ void toku_multi_operation_client_unlock(void);
// Initialize the checkpoint mechanism, must be called before any client operations. // Initialize the checkpoint mechanism, must be called before any client operations.
// Must pass in function pointers to take/release ydb lock. // Must pass in function pointers to take/release ydb lock.
void toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)); int toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
void toku_checkpoint_destroy(void); int toku_checkpoint_destroy(void);
// Take a checkpoint of all currently open dictionaries // Take a checkpoint of all currently open dictionaries
// Callback is called during checkpoint procedure while checkpoint_safe lock is still held. // Callback is called during checkpoint procedure while checkpoint_safe lock is still held.
......
...@@ -72,14 +72,15 @@ leaflock_pool_unlock(void) { ...@@ -72,14 +72,15 @@ leaflock_pool_unlock(void) {
int r = toku_pthread_mutex_unlock(&pool_mutex); assert(r==0); int r = toku_pthread_mutex_unlock(&pool_mutex); assert(r==0);
} }
void int
toku_leaflock_init(void) { toku_leaflock_init(void) {
int r = toku_pthread_mutex_init(&pool_mutex, NULL); int r = toku_pthread_mutex_init(&pool_mutex, NULL);
assert(r == 0); assert(r == 0);
free_list = NULL; free_list = NULL;
return r;
} }
void int
toku_leaflock_destroy(void) { toku_leaflock_destroy(void) {
leaflock_pool_lock(); leaflock_pool_lock();
int r; int r;
...@@ -92,6 +93,7 @@ toku_leaflock_destroy(void) { ...@@ -92,6 +93,7 @@ toku_leaflock_destroy(void) {
} }
leaflock_pool_unlock(); leaflock_pool_unlock();
r = toku_pthread_mutex_destroy(&pool_mutex); assert(r == 0); r = toku_pthread_mutex_destroy(&pool_mutex); assert(r == 0);
return r;
} }
int int
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
typedef struct leaflock *LEAFLOCK; typedef struct leaflock *LEAFLOCK;
void toku_leaflock_init(void); int toku_leaflock_init(void);
void toku_leaflock_destroy(void); int toku_leaflock_destroy(void);
int toku_leaflock_borrow(LEAFLOCK *leaflockp); int toku_leaflock_borrow(LEAFLOCK *leaflockp);
void toku_leaflock_unlock_and_return(LEAFLOCK *leaflockp); void toku_leaflock_unlock_and_return(LEAFLOCK *leaflockp);
......
...@@ -6,14 +6,18 @@ ...@@ -6,14 +6,18 @@
#include "includes.h" #include "includes.h"
static toku_pthread_mutex_t logger_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER; static toku_pthread_mutex_t logger_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
void toku_logger_lock_init(void) { int
toku_logger_lock_init(void) {
int r = toku_pthread_mutex_init(&logger_mutex, NULL); int r = toku_pthread_mutex_init(&logger_mutex, NULL);
assert(r == 0); assert(r == 0);
return r;
} }
void toku_logger_lock_destroy(void) { int
toku_logger_lock_destroy(void) {
int r = toku_pthread_mutex_destroy(&logger_mutex); int r = toku_pthread_mutex_destroy(&logger_mutex);
assert(r == 0); assert(r == 0);
return r;
} }
void* toku_malloc_in_rollback(TOKUTXN txn, size_t size) { void* toku_malloc_in_rollback(TOKUTXN txn, size_t size) {
......
...@@ -24,8 +24,8 @@ struct logbytes { ...@@ -24,8 +24,8 @@ struct logbytes {
#define MALLOC_LOGBYTES(n) toku_malloc(sizeof(struct logbytes)+n -1) #define MALLOC_LOGBYTES(n) toku_malloc(sizeof(struct logbytes)+n -1)
void toku_logger_lock_init(void); int toku_logger_lock_init(void);
void toku_logger_lock_destroy(void); int toku_logger_lock_destroy(void);
int toku_logger_create(TOKULOGGER */*resultp*/); int toku_logger_create(TOKULOGGER */*resultp*/);
void toku_logger_set_cachetable (TOKULOGGER, CACHETABLE); void toku_logger_set_cachetable (TOKULOGGER, CACHETABLE);
void toku_logger_write_log_files (TOKULOGGER, int do_write_log_files); void toku_logger_write_log_files (TOKULOGGER, int do_write_log_files);
......
#include <toku_portability.h> #include <toku_portability.h>
#include "test.h"
#include "minicron.h" #include "minicron.h"
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
int verbose=0;
static inline void
default_parse_args (int argc, const char *argv[]) {
const char *progname=argv[0];
argc--; argv++;
while (argc>0) {
if (strcmp(argv[0],"-v")==0) {
verbose=1;
} else if (strcmp(argv[0],"-q")==0) {
verbose=0;
} else {
fprintf(stderr, "Usage:\n %s [-v] [-q]\n", progname);
exit(1);
}
argc--; argv++;
}
}
static double static double
tdiff (struct timeval *a, struct timeval *b) { tdiff (struct timeval *a, struct timeval *b) {
return (a->tv_sec-b->tv_sec) + (a->tv_usec-b->tv_usec)*1e-6; return (a->tv_sec-b->tv_sec) + (a->tv_usec-b->tv_usec)*1e-6;
...@@ -146,8 +128,7 @@ test6 (void *v) { ...@@ -146,8 +128,7 @@ test6 (void *v) {
typedef void*(*ptf)(void*); typedef void*(*ptf)(void*);
int int
main (int argc, const char *argv[]) test_main (int argc, const char *argv[]) {
{
default_parse_args(argc,argv); default_parse_args(argc,argv);
gettimeofday(&starttime, 0); gettimeofday(&starttime, 0);
......
#include <toku_portability.h>
#include "test.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
...@@ -6,7 +8,6 @@ ...@@ -6,7 +8,6 @@
#include <errno.h> #include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <toku_portability.h>
#include "toku_os.h" #include "toku_os.h"
#include "toku_pthread.h" #include "toku_pthread.h"
#include "threadpool.h" #include "threadpool.h"
...@@ -83,7 +84,7 @@ usage (void) { ...@@ -83,7 +84,7 @@ usage (void) {
} }
int int
main(int argc, const char *argv[]) { test_main (int argc, const char *argv[]) {
int max_threads = 1; int max_threads = 1;
#if defined(__linux__) #if defined(__linux__)
int do_malloc_fail = 0; int do_malloc_fail = 0;
......
#include <toku_portability.h>
#include "test.h"
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <toku_portability.h>
#include "toku_assert.h" #include "toku_assert.h"
#include "toku_pthread.h" #include "toku_pthread.h"
#include "memory.h" #include "memory.h"
...@@ -183,7 +184,7 @@ test_flow_control (int limit, int n, int maxthreads) { ...@@ -183,7 +184,7 @@ test_flow_control (int limit, int n, int maxthreads) {
} }
int int
main(int argc, const char *argv[]) { test_main (int argc, const char *argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
......
...@@ -19,12 +19,16 @@ ...@@ -19,12 +19,16 @@
static toku_pthread_mutex_t ydb_big_lock = TOKU_PTHREAD_MUTEX_INITIALIZER; static toku_pthread_mutex_t ydb_big_lock = TOKU_PTHREAD_MUTEX_INITIALIZER;
void toku_ydb_lock_init(void) { int
toku_ydb_lock_init(void) {
int r = toku_pthread_mutex_init(&ydb_big_lock, NULL); assert(r == 0); int r = toku_pthread_mutex_init(&ydb_big_lock, NULL); assert(r == 0);
return r;
} }
void toku_ydb_lock_destroy(void) { int
toku_ydb_lock_destroy(void) {
int r = toku_pthread_mutex_destroy(&ydb_big_lock); assert(r == 0); int r = toku_pthread_mutex_destroy(&ydb_big_lock); assert(r == 0);
return r;
} }
void toku_ydb_lock(void) { void toku_ydb_lock(void) {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
toku_os_mkdir; toku_os_mkdir;
toku_realloc; toku_realloc;
toku_strdup; toku_strdup;
toku_pthread_yield;
dlmalloc; dlmalloc;
dlrealloc; dlrealloc;
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#ident "$Id$" #ident "$Id$"
#include <test.h>
#include <db.h> #include <db.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "toku_pthread.h" #include "toku_pthread.h"
#include "test.h"
#include "checkpoint_test.h" #include "checkpoint_test.h"
...@@ -57,8 +57,9 @@ checkpoint_truncate_test(u_int32_t flags, u_int32_t n) { ...@@ -57,8 +57,9 @@ checkpoint_truncate_test(u_int32_t flags, u_int32_t n) {
insert_n_fixed(db_test.db, db_control.db, NULL, firstkey, numkeys); insert_n_fixed(db_test.db, db_control.db, NULL, firstkey, numkeys);
snapshot(&db_test, TRUE); // take checkpoint, truncate db_test during checkpoint callback snapshot(&db_test, TRUE); // take checkpoint, truncate db_test during checkpoint callback
verify_sequential_rows(db_control.db, firstkey, numkeys); verify_sequential_rows(db_control.db, firstkey, numkeys);
pthread_join(thread, &ignore); toku_pthread_join(thread, &ignore);
db_shutdown(&db_control); db_shutdown(&db_control);
db_shutdown(&db_test);
env_shutdown(); env_shutdown();
} }
...@@ -79,7 +80,7 @@ truncate_thread(void * extra) { ...@@ -79,7 +80,7 @@ truncate_thread(void * extra) {
fflush(stdout); fflush(stdout);
} }
if (iter & 1) if (iter & 1)
pthread_yield(); // increase probability of collision by having some different timing toku_pthread_yield(); // increase probability of collision by having some different timing
db_truncate(d->db, NULL); db_truncate(d->db, NULL);
return NULL; return NULL;
} }
......
...@@ -65,8 +65,8 @@ struct __toku_db_env_internal { ...@@ -65,8 +65,8 @@ struct __toku_db_env_internal {
Ephemeral locking Ephemeral locking
********************************************************* */ ********************************************************* */
void toku_ydb_lock_init(void); int toku_ydb_lock_init(void);
void toku_ydb_lock_destroy(void); int toku_ydb_lock_destroy(void);
void toku_ydb_lock(void); void toku_ydb_lock(void);
void toku_ydb_unlock(void); void toku_ydb_unlock(void);
......
...@@ -31,6 +31,7 @@ const char *toku_copyright_string = "Copyright (c) 2007, 2008 Tokutek Inc. All ...@@ -31,6 +31,7 @@ const char *toku_copyright_string = "Copyright (c) 2007, 2008 Tokutek Inc. All
#include "checkpoint.h" #include "checkpoint.h"
#include "key.h" #include "key.h"
#ifdef TOKUTRACE #ifdef TOKUTRACE
#define DB_ENV_CREATE_FUN db_env_create_toku10 #define DB_ENV_CREATE_FUN db_env_create_toku10
#define DB_CREATE_FUN db_create_toku10 #define DB_CREATE_FUN db_create_toku10
...@@ -51,31 +52,24 @@ init_dbt_realloc(DBT *dbt) { ...@@ -51,31 +52,24 @@ init_dbt_realloc(DBT *dbt) {
return dbt; return dbt;
} }
static void int toku_ydb_init(void) {
toku_ydb_init_malloc(void) { int r = 0;
#if defined(TOKU_WINDOWS) && TOKU_WINDOWS //Lower level must be initialized first.
//Set the heap (malloc/free/realloc) to use the low fragmentation mode. if (r==0)
ULONG HeapFragValue = 2; r = toku_brt_init(toku_ydb_lock, toku_ydb_unlock);
if (r==0)
int r; r = toku_ydb_lock_init();
r = HeapSetInformation(GetProcessHeap(), return r;
HeapCompatibilityInformation,
&HeapFragValue,
sizeof(HeapFragValue));
//if (r==0) //Do some error output if necessary.
assert(r!=0);
#endif
}
void toku_ydb_init(void) {
toku_ydb_init_malloc();
toku_brt_init(toku_ydb_lock, toku_ydb_unlock);
toku_ydb_lock_init();
} }
void toku_ydb_destroy(void) { int toku_ydb_destroy(void) {
toku_brt_destroy(); int r = 0;
toku_ydb_lock_destroy(); if (r==0)
r = toku_ydb_lock_destroy();
//Lower level must be cleaned up last.
if (r==0)
r = toku_brt_destroy();
return r;
} }
static int static int
...@@ -3839,3 +3833,14 @@ void db_env_set_checkpoint_callback (void (*callback_f)(void*), void* extra) { ...@@ -3839,3 +3833,14 @@ void db_env_set_checkpoint_callback (void (*callback_f)(void*), void* extra) {
toku_checkpoint_safe_client_unlock(); toku_checkpoint_safe_client_unlock();
//printf("set callback = %p, extra = %p\n", callback_f, extra); //printf("set callback = %p, extra = %p\n", callback_f, extra);
} }
// HACK: To ensure toku_pthread_yield gets included in the .so
// non-static would require a prototype in a header
// static (since unused) would give a warning
// static + unused would not actually help toku_pthread_yield get in the .so
// static + used avoids all the warnings and makes sure toku_pthread_yield is in the .so
static void __attribute__((__used__))
include_toku_pthread_yield (void) {
toku_pthread_yield();
}
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
// Initialize the ydb library globals. // Initialize the ydb library globals.
// Called when the ydb library is loaded. // Called when the ydb library is loaded.
void toku_ydb_init(void); int toku_ydb_init(void);
// Called when the ydb library is unloaded. // Called when the ydb library is unloaded.
void toku_ydb_destroy(void); int toku_ydb_destroy(void);
// Called to use dlmalloc functions. // Called to use dlmalloc functions.
void setup_dlmalloc(void) __attribute__((__visibility__("default"))); void setup_dlmalloc(void) __attribute__((__visibility__("default")));
......
...@@ -3,17 +3,20 @@ ...@@ -3,17 +3,20 @@
#include <toku_portability.h> #include <toku_portability.h>
#include <db.h> #include <db.h>
#include "ydb.h" #include "ydb.h"
#include <toku_assert.h>
#if defined(__GNUC__) #if defined(__GNUC__)
static void __attribute__((constructor)) libtokudb_init(void) { static void __attribute__((constructor)) libtokudb_init(void) {
// printf("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); // printf("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);
toku_ydb_init(); int r = toku_ydb_init();
assert(r==0);
} }
static void __attribute__((destructor)) libtokudb_destroy(void) { static void __attribute__((destructor)) libtokudb_destroy(void) {
// printf("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); // printf("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);
toku_ydb_destroy(); int r = toku_ydb_destroy();
assert(r==0);
} }
#endif #endif
...@@ -25,10 +28,12 @@ static void __attribute__((destructor)) libtokudb_destroy(void) { ...@@ -25,10 +28,12 @@ static void __attribute__((destructor)) libtokudb_destroy(void) {
BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID reserved) { BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID reserved) {
UNUSED(h); UNUSED(reserved); UNUSED(h); UNUSED(reserved);
// printf("%s:%lu\n", __FUNCTION__, reason); // printf("%s:%lu\n", __FUNCTION__, reason);
int r = 0;
if (reason == DLL_PROCESS_ATTACH) if (reason == DLL_PROCESS_ATTACH)
toku_ydb_init(); r = toku_ydb_init();
if (reason == DLL_PROCESS_DETACH) if (reason == DLL_PROCESS_DETACH)
toku_ydb_destroy(); r = toku_ydb_destroy();
assert(r==0);
return TRUE; return TRUE;
} }
......
...@@ -230,7 +230,7 @@ ifneq ($(CYGWIN),) ...@@ -230,7 +230,7 @@ ifneq ($(CYGWIN),)
CRUNTIME=MTd CRUNTIME=MTd
endif endif
endif endif
ALWAYS_LINK=$(LIBPORTABILITY) $(TOKUROOT)windows/lib/$(CRUNTIME)/pthreadVC2.lib $(TOKUROOT)windows/lib/$(CRUNTIME)/zlib.lib Ws2_32.lib psapi.lib ALWAYS_LINK=$(LIBPORTABILITY) $(TOKUROOT)windows/lib/$(CRUNTIME)/zlib.lib Ws2_32.lib psapi.lib
LINK=#Empty LINK=#Empty
BINOUTPUT=-Fe BINOUTPUT=-Fe
OOUTPUT=-Fo OOUTPUT=-Fo
...@@ -393,11 +393,11 @@ $(NOIPO_YDB) $(IPO_YDB): $(@D)*.[ch] ...@@ -393,11 +393,11 @@ $(NOIPO_YDB) $(IPO_YDB): $(@D)*.[ch]
endif endif
ifeq ($(OS_CHOICE),windows) ifeq ($(OS_CHOICE),windows)
PTHREAD_LIB=$(TOKUROOT)windows/lib/$(CRUNTIME)/pthreadVC2.dll PTHREAD_LIB=$(TOKUROOT)lib/pthreadVC2.dll
PTHREAD_LOCAL=$(notdir $(PTHREAD_LIB)) PTHREAD_LOCAL=$(notdir $(PTHREAD_LIB))
$(PTHREAD_LOCAL): $(PTHREAD_LIB) $(PTHREAD_LOCAL): $(PTHREAD_LIB)
cp $< $@ cp -u $< $@
else else
PTHREAD_LOCAL= PTHREAD_LOCAL=
endif endif
......
...@@ -129,6 +129,9 @@ int toku_set_func_free (void (*)(void*)); ...@@ -129,6 +129,9 @@ int toku_set_func_free (void (*)(void*));
int toku_set_func_pwrite (ssize_t (*pwrite_fun)(int, const void *, size_t, toku_off_t)); int toku_set_func_pwrite (ssize_t (*pwrite_fun)(int, const void *, size_t, toku_off_t));
int toku_set_func_write (ssize_t (*pwrite_fun)(int, const void *, size_t)); int toku_set_func_write (ssize_t (*pwrite_fun)(int, const void *, size_t));
int toku_portability_init (void);
int toku_portability_destroy (void);
#if defined __cplusplus #if defined __cplusplus
}; };
#endif #endif
......
...@@ -95,7 +95,7 @@ build.tdb: $(UTILS) $(STATIC_UTILS); ...@@ -95,7 +95,7 @@ build.tdb: $(UTILS) $(STATIC_UTILS);
build.bdb: $(BDB_UTILS); build.bdb: $(BDB_UTILS);
endif endif
copy.tdb: copy.tdb: $(PTHREAD_LOCAL)
cp ../lib/*.dll ./ cp ../lib/*.dll ./
copy.bdb: copy.bdb:
cp $(BDBDIR)/lib/*.dll ./ cp $(BDBDIR)/lib/*.dll ./
......
...@@ -12,10 +12,14 @@ SRCS = $(wildcard *.c) ...@@ -12,10 +12,14 @@ SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.$(OEXT),$(SRCS)) OBJS = $(patsubst %.c,%.$(OEXT),$(SRCS))
TARGET = libtokuportability.$(AEXT) TARGET = libtokuportability.$(AEXT)
build install: $(LIBPORTABILITY) build install: $(LIBPORTABILITY) $(PTHREAD_LIB)
PTHREAD_LIB_CRUNTIME=$(TOKUROOT)windows/lib/$(CRUNTIME)/pthreadVC2.dll
$(PTHREAD_LIB): $(PTHREAD_LIB_CRUNTIME)
cp -u $< $@
$(LIBPORTABILITY): $(TARGET) $(LIBPORTABILITY): $(TARGET)
if ! diff $< $@ 2>/dev/null; then cp $< $@; fi cp -u $< $@
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
...@@ -23,5 +27,5 @@ check: $(TARGET) ...@@ -23,5 +27,5 @@ check: $(TARGET)
cd tests && $(MAKE) check cd tests && $(MAKE) check
clean: clean:
rm -rf $(TARGET) $(LIBPORTABILITY) rm -rf $(TARGET) $(LIBPORTABILITY) $(PTHREAD_LIB)
cd tests && $(MAKE) clean cd tests && $(MAKE) clean
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.DEFAULT_GOAL=all .DEFAULT_GOAL=all
TOKUROOT=../../ TOKUROOT=../../
INCLUDEDIRS=-I$(TOKUROOT)include/windows -I$(TOKUROOT)newbrt INCLUDEDIRS=-I$(TOKUROOT)include/windows -I$(TOKUROOT)newbrt -I$(TOKUROOT)windows/tests
include $(TOKUROOT)toku_include/Makefile.include include $(TOKUROOT)toku_include/Makefile.include
SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes. SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <toku_portability.h> #include <test.h>
#include "toku_os.h" #include "toku_os.h"
#include <dirent.h> #include <dirent.h>
...@@ -33,7 +33,7 @@ static int walk(const char *dirname) { ...@@ -33,7 +33,7 @@ static int walk(const char *dirname) {
return otherfound; return otherfound;
} }
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
int found; int found;
int fd; int fd;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <toku_portability.h> #include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose=0; int verbose=0;
...@@ -28,7 +28,7 @@ static void test_handles(const char *fname) { ...@@ -28,7 +28,7 @@ static void test_handles(const char *fname) {
assert(r==0); assert(r==0);
} }
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
......
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
...@@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) { ...@@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) {
} }
#endif #endif
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
int fd; int fd;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <toku_time.h> #include <toku_time.h>
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include <toku_portability.h> #include <test.h>
#include <toku_os.h> #include <toku_os.h>
int main(void) { int test_main(int argc, char *argv[]) {
uint64_t maxdata; uint64_t maxdata;
int r = toku_os_get_max_process_data_size(&maxdata); int r = toku_os_get_max_process_data_size(&maxdata);
assert(r == 0); assert(r == 0);
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
...@@ -5,7 +6,7 @@ ...@@ -5,7 +6,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
int fd = open(argv[i], O_RDONLY); int fd = open(argv[i], O_RDONLY);
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
...@@ -18,7 +19,7 @@ ...@@ -18,7 +19,7 @@
#define TESTFILE "test-open-unlink-file" #define TESTFILE "test-open-unlink-file"
#define NEWNAME TESTFILE ".junk" #define NEWNAME TESTFILE ".junk"
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
int fd; int fd;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
...@@ -17,7 +18,7 @@ ...@@ -17,7 +18,7 @@
const char TESTFILE[] = "test-open-unlink-file"; const char TESTFILE[] = "test-open-unlink-file";
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
int fd; int fd;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <toku_portability.h> #include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose; int verbose;
...@@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) { ...@@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) {
printf("close %s %"PRIu64"\n", fname, r); printf("close %s %"PRIu64"\n", fname, r);
} }
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
......
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
...@@ -68,7 +68,7 @@ static void *reader(void *arg) { ...@@ -68,7 +68,7 @@ static void *reader(void *arg) {
return arg; return arg;
} }
int main(void) { int test_main(int argc, char *argv[]) {
int i; int i;
void *ret; void *ret;
toku_pthread_t t[2]; toku_pthread_t t[2];
......
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
...@@ -20,7 +20,7 @@ static void *myfunc2(void *arg) { ...@@ -20,7 +20,7 @@ static void *myfunc2(void *arg) {
return arg; return arg;
} }
int main(void) { int test_main(int argc, char *argv[]) {
#define N 10 #define N 10
toku_pthread_t t[N]; toku_pthread_t t[N];
int i; int i;
......
// test for a pthread handle leak // test for a pthread handle leak
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
...@@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) { ...@@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) {
return arg; return arg;
} }
int main(void) { int test_main(int argc, char *argv[]) {
#define N 1000000 #define N 1000000
int i; int i;
......
/* Verify that toku_os_pwrite does the right thing when writing beyond 4GB. */ /* Verify that toku_os_pwrite does the right thing when writing beyond 4GB. */
#include <fcntl.h> #include <fcntl.h>
#include <toku_portability.h> #include <test.h>
#include <assert.h> #include <assert.h>
int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) { int test_main(int argc, char *argv[]) {
char fname[] = "pwrite4g.data"; char fname[] = "pwrite4g.data";
int r; int r;
unlink(fname); unlink(fname);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <toku_portability.h> #include <test.h>
#include <toku_os.h> #include <toku_os.h>
static void do_mallocs(void) { static void do_mallocs(void) {
...@@ -16,7 +16,7 @@ static void do_mallocs(void) { ...@@ -16,7 +16,7 @@ static void do_mallocs(void) {
} }
} }
int main(void) { int test_main(int argc, char *argv[]) {
int64_t rss; int64_t rss;
toku_os_get_max_rss(&rss); toku_os_get_max_rss(&rss);
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
...@@ -6,7 +7,7 @@ ...@@ -6,7 +7,7 @@
int verbose; int verbose;
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
......
/* -*- mode: C; c-basic-offset: 4 -*- */ /* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
...@@ -36,7 +36,7 @@ check_snprintf(int i) { ...@@ -36,7 +36,7 @@ check_snprintf(int i) {
} }
int main(void) { int test_main(int argc, char *argv[]) {
int i; int i;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
check_snprintf(i); check_snprintf(i);
......
#include <toku_portability.h> #include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
...@@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) { ...@@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) {
if (r!=0) assert(errno == ex_errno); if (r!=0) assert(errno == ex_errno);
} }
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
test_stat(".", 0, 0); test_stat(".", 0, 0);
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <toku_portability.h> #include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose; int verbose;
...@@ -17,7 +17,7 @@ void testit(int64_t i, int base) { ...@@ -17,7 +17,7 @@ void testit(int64_t i, int base) {
assert(i == o); assert(i == o);
} }
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
int64_t n; int64_t n;
int64_t o; int64_t o;
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <toku_portability.h> #include <test.h>
int main(void) { int test_main(int argc, char *argv[]) {
int r; int r;
int fd; int fd;
struct fileid fid; struct fileid fid;
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <windows.h> #include <windows.h>
#include <winsock.h> #include <winsock.h>
int verbose;
int usleep(SOCKET s, unsigned int useconds) { int usleep(SOCKET s, unsigned int useconds) {
fd_set dummy; fd_set dummy;
...@@ -16,7 +15,10 @@ int usleep(SOCKET s, unsigned int useconds) { ...@@ -16,7 +15,10 @@ int usleep(SOCKET s, unsigned int useconds) {
return select(0, 0, 0, &dummy, &tv); return select(0, 0, 0, &dummy, &tv);
} }
int main(int argc, char *argv[]) { #include <test.h>
int verbose;
int test_main(int argc, char *argv[]) {
int i; int i;
int n = 1; int n = 1;
WSADATA wsadata; WSADATA wsadata;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
...@@ -6,7 +7,7 @@ ...@@ -6,7 +7,7 @@
int verbose; int verbose;
int main(int argc, char *argv[]) { int test_main(int argc, char *argv[]) {
int i; int i;
int n = 1; int n = 1;
......
#include <toku_portability.h>
int test_main(int argc, char *argv[]);
int
main(int argc, char *argv[]) {
toku_portability_init();
int r = test_main(argc, argv);
toku_portability_destroy();
return r;
}
#include <toku_portability.h> #include <toku_portability.h>
#include <windows.h> #include <windows.h>
#include <toku_pthread.h> #include <toku_pthread.h>
#include "toku_assert.h"
int int
toku_pthread_yield(void) { toku_pthread_yield(void) {
...@@ -8,3 +9,67 @@ toku_pthread_yield(void) { ...@@ -8,3 +9,67 @@ toku_pthread_yield(void) {
return 0; return 0;
} }
toku_pthread_win32_funcs pthread_win32 = {0};
HMODULE pthread_win32_dll = NULL;
//TODO: add a portability_init/destroy function (call in brt_init)
//TODO: Call in portability_init
int
toku_pthread_win32_init(void) {
int r = 0;
pthread_win32_dll = NULL;
memset(&pthread_win32, 0, sizeof(pthread_win32));
pthread_win32_dll = LoadLibrary(TEXT("pthreadVC2"));
if (pthread_win32_dll == NULL)
r = GetLastError();
else {
#define LOAD_PTHREAD_FUNC(name) do { \
pthread_win32.pthread_ ## name = (toku_pthread_win32_ ## name ## _func) GetProcAddress(pthread_win32_dll, "pthread_" #name); \
assert(pthread_win32.pthread_ ## name != NULL); \
} while (0)
LOAD_PTHREAD_FUNC(attr_init);
LOAD_PTHREAD_FUNC(attr_destroy);
LOAD_PTHREAD_FUNC(attr_getstacksize);
LOAD_PTHREAD_FUNC(attr_setstacksize);
LOAD_PTHREAD_FUNC(mutex_init);
LOAD_PTHREAD_FUNC(mutex_destroy);
LOAD_PTHREAD_FUNC(mutex_lock);
LOAD_PTHREAD_FUNC(mutex_trylock);
LOAD_PTHREAD_FUNC(mutex_unlock);
LOAD_PTHREAD_FUNC(cond_init);
LOAD_PTHREAD_FUNC(cond_destroy);
LOAD_PTHREAD_FUNC(cond_wait);
LOAD_PTHREAD_FUNC(cond_timedwait);
LOAD_PTHREAD_FUNC(cond_signal);
LOAD_PTHREAD_FUNC(cond_broadcast);
LOAD_PTHREAD_FUNC(rwlock_init);
LOAD_PTHREAD_FUNC(rwlock_destroy);
LOAD_PTHREAD_FUNC(rwlock_rdlock);
LOAD_PTHREAD_FUNC(rwlock_wrlock);
LOAD_PTHREAD_FUNC(rwlock_unlock);
LOAD_PTHREAD_FUNC(create);
LOAD_PTHREAD_FUNC(join);
LOAD_PTHREAD_FUNC(self);
#undef LOAD_PTHREAD_FUNC
}
return r;
}
//TODO: Call in brt_destroy
int toku_pthread_win32_destroy(void) {
assert(pthread_win32_dll != NULL);
BOOL succ = FreeLibrary(pthread_win32_dll);
assert(succ);
return 0;
}
...@@ -8,137 +8,204 @@ extern "C" { ...@@ -8,137 +8,204 @@ extern "C" {
#include "pthread.h" #include "pthread.h"
#include <toku_time.h> #include <toku_time.h>
typedef pthread_attr_t toku_pthread_attr_t; int toku_pthread_win32_init(void);
typedef pthread_t toku_pthread_t; int toku_pthread_win32_destroy(void);
typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
typedef pthread_mutex_t toku_pthread_mutex_t; typedef pthread_attr_t toku_pthread_attr_t;
typedef pthread_condattr_t toku_pthread_condattr_t; typedef pthread_t toku_pthread_t;
typedef pthread_cond_t toku_pthread_cond_t; typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
typedef pthread_rwlock_t toku_pthread_rwlock_t; typedef pthread_mutex_t toku_pthread_mutex_t;
typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t; typedef pthread_condattr_t toku_pthread_condattr_t;
//typedef struct timespec toku_timespec_t; //Already defined in toku_time.h typedef pthread_cond_t toku_pthread_cond_t;
typedef pthread_rwlock_t toku_pthread_rwlock_t;
typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
//typedef struct timespec toku_timespec_t; //Already defined in toku_time.h
typedef int (__cdecl *toku_pthread_win32_rwlock_init_func) (pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr);
typedef int (__cdecl *toku_pthread_win32_rwlock_destroy_func) (pthread_rwlock_t *lock);
typedef int (__cdecl *toku_pthread_win32_rwlock_rdlock_func) (pthread_rwlock_t *rwlock);
typedef int (__cdecl *toku_pthread_win32_rwlock_wrlock_func) (pthread_rwlock_t *rwlock);
typedef int (__cdecl *toku_pthread_win32_rwlock_unlock_func) (pthread_rwlock_t *rwlock);
typedef int (__cdecl *toku_pthread_win32_attr_init_func) (pthread_attr_t *attr);
typedef int (__cdecl *toku_pthread_win32_attr_destroy_func) (pthread_attr_t *attr);
typedef int (__cdecl *toku_pthread_win32_attr_getstacksize_func)(pthread_attr_t *attr, size_t *stacksize);
typedef int (__cdecl *toku_pthread_win32_attr_setstacksize_func)(pthread_attr_t *attr, size_t *stacksize);
typedef int (__cdecl *toku_pthread_win32_create_func) (pthread_t *thread, const pthread_attr_t *attr, void *(*start_function)(void *), void *arg);
typedef int (__cdecl *toku_pthread_win32_join_func) (pthread_t thread, void **value_ptr);
typedef pthread_t (__cdecl *toku_pthread_win32_self_func)(void);
typedef int (__cdecl *toku_pthread_win32_mutex_init_func) (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
typedef int (__cdecl *toku_pthread_win32_mutex_destroy_func) (pthread_mutex_t *mutex);
typedef int (__cdecl *toku_pthread_win32_mutex_lock_func) (pthread_mutex_t *mutex);
typedef int (__cdecl *toku_pthread_win32_mutex_trylock_func) (pthread_mutex_t *mutex);
typedef int (__cdecl *toku_pthread_win32_mutex_unlock_func) (pthread_mutex_t *mutex);
typedef int (__cdecl *toku_pthread_win32_cond_init_func) (pthread_cond_t *cond, const pthread_condattr_t *attr);
typedef int (__cdecl *toku_pthread_win32_cond_destroy_func) (pthread_cond_t *cond);
typedef int (__cdecl *toku_pthread_win32_cond_wait_func) (pthread_cond_t *cond, pthread_mutex_t *mutex);
typedef int (__cdecl *toku_pthread_win32_cond_timedwait_func) (pthread_cond_t *cond, pthread_mutex_t *mutex, toku_timespec_t *wakeup_at);
typedef int (__cdecl *toku_pthread_win32_cond_signal_func) (pthread_cond_t *cond);
typedef int (__cdecl *toku_pthread_win32_cond_broadcast_func) (pthread_cond_t *cond);
typedef struct toku_pthread_win32_funcs_struct {
toku_pthread_win32_attr_init_func pthread_attr_init;
toku_pthread_win32_attr_destroy_func pthread_attr_destroy;
toku_pthread_win32_attr_getstacksize_func pthread_attr_getstacksize;
toku_pthread_win32_attr_setstacksize_func pthread_attr_setstacksize;
toku_pthread_win32_mutex_init_func pthread_mutex_init;
toku_pthread_win32_mutex_destroy_func pthread_mutex_destroy;
toku_pthread_win32_mutex_lock_func pthread_mutex_lock;
toku_pthread_win32_mutex_trylock_func pthread_mutex_trylock;
toku_pthread_win32_mutex_unlock_func pthread_mutex_unlock;
toku_pthread_win32_cond_init_func pthread_cond_init;
toku_pthread_win32_cond_destroy_func pthread_cond_destroy;
toku_pthread_win32_cond_wait_func pthread_cond_wait;
toku_pthread_win32_cond_timedwait_func pthread_cond_timedwait;
toku_pthread_win32_cond_signal_func pthread_cond_signal;
toku_pthread_win32_cond_broadcast_func pthread_cond_broadcast;
toku_pthread_win32_rwlock_init_func pthread_rwlock_init;
toku_pthread_win32_rwlock_destroy_func pthread_rwlock_destroy;
toku_pthread_win32_rwlock_rdlock_func pthread_rwlock_rdlock;
toku_pthread_win32_rwlock_wrlock_func pthread_rwlock_wrlock;
toku_pthread_win32_rwlock_unlock_func pthread_rwlock_unlock;
toku_pthread_win32_create_func pthread_create;
toku_pthread_win32_join_func pthread_join;
toku_pthread_win32_self_func pthread_self;
} toku_pthread_win32_funcs;
extern toku_pthread_win32_funcs pthread_win32;
static inline int static inline int
toku_pthread_rwlock_init(toku_pthread_rwlock_t *__restrict rwlock, const toku_pthread_rwlockattr_t *__restrict attr) { toku_pthread_rwlock_init(toku_pthread_rwlock_t *__restrict rwlock, const toku_pthread_rwlockattr_t *__restrict attr) {
return pthread_rwlock_init(rwlock, attr); return pthread_win32.pthread_rwlock_init(rwlock, attr);
} }
static inline int static inline int
toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) { toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_destroy(rwlock); return pthread_win32.pthread_rwlock_destroy(rwlock);
} }
static inline int static inline int
toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) { toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_rdlock(rwlock); return pthread_win32.pthread_rwlock_rdlock(rwlock);
} }
static inline int static inline int
toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) { toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock); return pthread_win32.pthread_rwlock_unlock(rwlock);
} }
static inline int static inline int
toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) { toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_wrlock(rwlock); return pthread_win32.pthread_rwlock_wrlock(rwlock);
} }
static inline int static inline int
toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) { toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock); return pthread_win32.pthread_rwlock_unlock(rwlock);
} }
int toku_pthread_yield(void); int toku_pthread_yield(void);
static inline static inline
int toku_pthread_attr_init(toku_pthread_attr_t *attr) { int toku_pthread_attr_init(toku_pthread_attr_t *attr) {
return pthread_attr_init(attr); return pthread_win32.pthread_attr_init(attr);
} }
static inline static inline
int toku_pthread_attr_destroy(toku_pthread_attr_t *attr) { int toku_pthread_attr_destroy(toku_pthread_attr_t *attr) {
return pthread_attr_destroy(attr); return pthread_win32.pthread_attr_destroy(attr);
} }
static inline static inline
int toku_pthread_attr_getstacksize(toku_pthread_attr_t *attr, size_t *stacksize) { int toku_pthread_attr_getstacksize(toku_pthread_attr_t *attr, size_t *stacksize) {
return pthread_attr_getstacksize(attr, stacksize); return pthread_win32.pthread_attr_getstacksize(attr, stacksize);
} }
static inline static inline
int toku_pthread_attr_setstacksize(toku_pthread_attr_t *attr, size_t stacksize) { int toku_pthread_attr_setstacksize(toku_pthread_attr_t *attr, size_t stacksize) {
return pthread_attr_setstacksize(attr, stacksize); return pthread_win32.pthread_attr_setstacksize(attr, stacksize);
} }
static inline static inline
int toku_pthread_create(toku_pthread_t *thread, const toku_pthread_attr_t *attr, void *(*start_function)(void *), void *arg) { int toku_pthread_create(toku_pthread_t *thread, const toku_pthread_attr_t *attr, void *(*start_function)(void *), void *arg) {
return pthread_create(thread, attr, start_function, arg); return pthread_win32.pthread_create(thread, attr, start_function, arg);
} }
static inline static inline
int toku_pthread_join(toku_pthread_t thread, void **value_ptr) { int toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
return pthread_join(thread, value_ptr); return pthread_win32.pthread_join(thread, value_ptr);
} }
static inline static inline
toku_pthread_t toku_pthread_self(void) { toku_pthread_t toku_pthread_self(void) {
return pthread_self(); return pthread_win32.pthread_self();
} }
#define TOKU_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define TOKU_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
static inline static inline
int toku_pthread_mutex_init(toku_pthread_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) { int toku_pthread_mutex_init(toku_pthread_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) {
return pthread_mutex_init(mutex, attr); return pthread_win32.pthread_mutex_init(mutex, attr);
} }
static inline static inline
int toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex) { int toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex) {
return pthread_mutex_destroy(mutex); return pthread_win32.pthread_mutex_destroy(mutex);
} }
static inline static inline
int toku_pthread_mutex_lock(toku_pthread_mutex_t *mutex) { int toku_pthread_mutex_lock(toku_pthread_mutex_t *mutex) {
return pthread_mutex_lock(mutex); return pthread_win32.pthread_mutex_lock(mutex);
} }
int toku_pthread_mutex_trylock(toku_pthread_mutex_t *mutex); int toku_pthread_mutex_trylock(toku_pthread_mutex_t *mutex);
static inline static inline
int toku_pthread_mutex_unlock(toku_pthread_mutex_t *mutex) { int toku_pthread_mutex_unlock(toku_pthread_mutex_t *mutex) {
return pthread_mutex_unlock(mutex); return pthread_win32.pthread_mutex_unlock(mutex);
} }
static inline static inline
int toku_pthread_cond_init(toku_pthread_cond_t *cond, const toku_pthread_condattr_t *attr) { int toku_pthread_cond_init(toku_pthread_cond_t *cond, const toku_pthread_condattr_t *attr) {
return pthread_cond_init(cond, attr); return pthread_win32.pthread_cond_init(cond, attr);
} }
static inline static inline
int toku_pthread_cond_destroy(toku_pthread_cond_t *cond) { int toku_pthread_cond_destroy(toku_pthread_cond_t *cond) {
return pthread_cond_destroy(cond); return pthread_win32.pthread_cond_destroy(cond);
} }
static inline static inline
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) {
return pthread_cond_wait(cond, mutex); return pthread_win32.pthread_cond_wait(cond, mutex);
} }
static inline static inline
int toku_pthread_cond_timedwait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex, toku_timespec_t *wakeup_at) { int toku_pthread_cond_timedwait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex, toku_timespec_t *wakeup_at) {
return pthread_cond_timedwait(cond, mutex, wakeup_at); return pthread_win32.pthread_cond_timedwait(cond, mutex, wakeup_at);
} }
static inline static inline
int toku_pthread_cond_signal(toku_pthread_cond_t *cond) { int toku_pthread_cond_signal(toku_pthread_cond_t *cond) {
return pthread_cond_signal(cond); return pthread_win32.pthread_cond_signal(cond);
} }
static inline static inline
int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) { int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) {
return pthread_cond_broadcast(cond); return pthread_win32.pthread_cond_broadcast(cond);
} }
int
initialize_pthread_functions();
int
pthread_functions_free();
#if defined(__cplusplus) #if defined(__cplusplus)
......
...@@ -20,6 +20,40 @@ ...@@ -20,6 +20,40 @@
#include <fcntl.h> #include <fcntl.h>
#include <Crtdbg.h> #include <Crtdbg.h>
static int
toku_malloc_init(void) {
int r = 0;
//Set the heap (malloc/free/realloc) to use the low fragmentation mode.
ULONG HeapFragValue = 2;
int success;
success = HeapSetInformation(GetProcessHeap(),
HeapCompatibilityInformation,
&HeapFragValue,
sizeof(HeapFragValue));
//if (success==0) //Do some error output if necessary.
if (!success)
r = GetLastError();
return r;
}
int
toku_portability_init(void) {
int r = 0;
if (r==0)
r = toku_malloc_init();
if (r==0)
r = toku_pthread_win32_init();
return r;
}
int
toku_portability_destroy(void) {
int r = 0;
if (r==0)
r = toku_pthread_win32_destroy();
return r;
}
int int
toku_os_get_file_size(int fildes, int64_t *sizep) { toku_os_get_file_size(int fildes, int64_t *sizep) {
......
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