diff --git a/cxx/tests/Makefile b/cxx/tests/Makefile index bf654fb12e4..bea85870218 100644 --- a/cxx/tests/Makefile +++ b/cxx/tests/Makefile @@ -13,6 +13,8 @@ DEPEND_COMPILE += \ HERE = cxx/tests include $(TOKUROOT)toku_include/Makefile.include +SHELL=/bin/bash #Use of &> is a bash feature + SHOULD_FAIL = $(SHOULD_FAIL): MAYBEINVERTER=;test $$? -ne 0 diff --git a/linux/linux.c b/linux/linux.c index 3c2c482421f..5cac7d76640 100644 --- a/linux/linux.c +++ b/linux/linux.c @@ -14,6 +14,29 @@ #include #include #include "toku_os.h" +#include + +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 toku_os_getpid(void) { diff --git a/linux/tests/Makefile b/linux/tests/Makefile index c5b64faafc7..7a9453f04e7 100644 --- a/linux/tests/Makefile +++ b/linux/tests/Makefile @@ -1,6 +1,6 @@ # -*- Mode: Makefile -*- CPPFLAGS = -D_GNU_SOURCE -CPPFLAGS += -I../../toku_include -I.. +CPPFLAGS += -I../../toku_include -I.. -I. CFLAGS = -Wall -Werror -g -O0 -std=c99 LDFLAGS = ../libtokuportability.a -lpthread SRCS = $(wildcard test-*.c) diff --git a/linux/tests/test.h b/linux/tests/test.h new file mode 120000 index 00000000000..2234cd338b2 --- /dev/null +++ b/linux/tests/test.h @@ -0,0 +1 @@ +../../windows/tests/test.h \ No newline at end of file diff --git a/linux/toku_pthread.h b/linux/toku_pthread.h index 4072b24dd3c..44c2331ff75 100644 --- a/linux/toku_pthread.h +++ b/linux/toku_pthread.h @@ -51,7 +51,7 @@ toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) { return pthread_rwlock_unlock(rwlock); } -int toku_pthread_yield(void); +int toku_pthread_yield(void) __attribute__((__visibility__("default"))); static inline int toku_pthread_attr_init(toku_pthread_attr_t *attr) { diff --git a/newbrt/brt-serialize.c b/newbrt/brt-serialize.c index d1cee07538c..dfd9ba0e60f 100644 --- a/newbrt/brt-serialize.c +++ b/newbrt/brt-serialize.c @@ -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 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); + 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); + return r; } static inline void diff --git a/newbrt/brt.c b/newbrt/brt.c index 575b184ea91..18dab5c5c6a 100644 --- a/newbrt/brt.c +++ b/newbrt/brt.c @@ -4796,25 +4796,50 @@ int toku_brt_truncate (BRT brt) { return r; } -static void toku_brt_lock_init(void) { - toku_pwrite_lock_init(); - toku_logger_lock_init(); - toku_leaflock_init(); +static int +toku_brt_lock_init(void) { + int r = 0; + 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) { - toku_pwrite_lock_destroy(); - toku_logger_lock_destroy(); - toku_leaflock_destroy(); +static int +toku_brt_lock_destroy(void) { + int r = 0; + 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)) { - toku_brt_lock_init(); - toku_checkpoint_init(ydb_lock_callback, ydb_unlock_callback); +int toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) { + int r = 0; + //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) { - toku_brt_lock_destroy(); +int toku_brt_destroy(void) { + 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. diff --git a/newbrt/brt.h b/newbrt/brt.h index aa1bdeb52c8..eed4dba9ebb 100644 --- a/newbrt/brt.h +++ b/newbrt/brt.h @@ -141,10 +141,10 @@ int toku_brt_stat64 (BRT, TOKUTXN, u_int64_t *fsize /* the size of the underlying file */ ); -void toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)); -void toku_brt_destroy(void); -void toku_pwrite_lock_init(void); -void toku_pwrite_lock_destroy(void); +int toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)); +int toku_brt_destroy(void); +int toku_pwrite_lock_init(void); +int toku_pwrite_lock_destroy(void); void toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used); // Effect: truncate file if overallocated by at least 32MiB diff --git a/newbrt/cachetable.c b/newbrt/cachetable.c index e73bf80a734..d5897e6ae78 100644 --- a/newbrt/cachetable.c +++ b/newbrt/cachetable.c @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -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) { -#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); if (ct == 0) return ENOMEM; memset(ct, 0, sizeof(*ct)); diff --git a/newbrt/checkpoint.c b/newbrt/checkpoint.c index 24c73955fc3..7f71d8094db 100644 --- a/newbrt/checkpoint.c +++ b/newbrt/checkpoint.c @@ -69,16 +69,18 @@ static void (*ydb_unlock)(void) = NULL; // and use the "writer" calls for locking and unlocking. -static void +static int multi_operation_lock_init(void) { int r = toku_pthread_rwlock_init(&multi_operation_lock, NULL); assert(r == 0); + return r; } -static void +static int multi_operation_lock_destroy(void) { int r = toku_pthread_rwlock_destroy(&multi_operation_lock); assert(r == 0); + return r; } static void @@ -94,16 +96,18 @@ multi_operation_checkpoint_unlock(void) { } -static void +static int checkpoint_safe_lock_init(void) { int r = toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL); assert(r == 0); + return r; } -static void +static int checkpoint_safe_lock_destroy(void) { int r = toku_pthread_rwlock_destroy(&checkpoint_safe_lock); assert(r == 0); + return r; } static void @@ -150,19 +154,29 @@ toku_checkpoint_safe_client_unlock(void) { static BOOL initialized = FALSE; // 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)) { + int r = 0; ydb_lock = ydb_lock_callback; ydb_unlock = ydb_unlock_callback; - multi_operation_lock_init(); - checkpoint_safe_lock_init(); - initialized = TRUE; + if (r==0) + r = multi_operation_lock_init(); + if (r==0) + r = checkpoint_safe_lock_init(); + if (r==0) + initialized = TRUE; + return r; } -void toku_checkpoint_destroy(void) { - multi_operation_lock_destroy(); - checkpoint_safe_lock_destroy(); +int +toku_checkpoint_destroy(void) { + int r = 0; + if (r==0) + r = multi_operation_lock_destroy(); + if (r==0) + r = checkpoint_safe_lock_destroy(); initialized = FALSE; + return r; } diff --git a/newbrt/checkpoint.h b/newbrt/checkpoint.h index f4cfdf0e55c..00e7c674d05 100644 --- a/newbrt/checkpoint.h +++ b/newbrt/checkpoint.h @@ -47,9 +47,9 @@ void toku_multi_operation_client_unlock(void); // Initialize the checkpoint mechanism, must be called before any client operations. // 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 // Callback is called during checkpoint procedure while checkpoint_safe lock is still held. diff --git a/newbrt/leaflock.c b/newbrt/leaflock.c index 812b6845402..7f7c1e90911 100644 --- a/newbrt/leaflock.c +++ b/newbrt/leaflock.c @@ -72,14 +72,15 @@ leaflock_pool_unlock(void) { int r = toku_pthread_mutex_unlock(&pool_mutex); assert(r==0); } -void +int toku_leaflock_init(void) { int r = toku_pthread_mutex_init(&pool_mutex, NULL); assert(r == 0); free_list = NULL; + return r; } -void +int toku_leaflock_destroy(void) { leaflock_pool_lock(); int r; @@ -92,6 +93,7 @@ toku_leaflock_destroy(void) { } leaflock_pool_unlock(); r = toku_pthread_mutex_destroy(&pool_mutex); assert(r == 0); + return r; } int diff --git a/newbrt/leaflock.h b/newbrt/leaflock.h index 1bcae0bafe7..dce097045e1 100644 --- a/newbrt/leaflock.h +++ b/newbrt/leaflock.h @@ -7,8 +7,8 @@ typedef struct leaflock *LEAFLOCK; -void toku_leaflock_init(void); -void toku_leaflock_destroy(void); +int toku_leaflock_init(void); +int toku_leaflock_destroy(void); int toku_leaflock_borrow(LEAFLOCK *leaflockp); void toku_leaflock_unlock_and_return(LEAFLOCK *leaflockp); diff --git a/newbrt/log.c b/newbrt/log.c index c1e1187a8d2..8bc383f634d 100644 --- a/newbrt/log.c +++ b/newbrt/log.c @@ -6,14 +6,18 @@ #include "includes.h" 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); 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); assert(r == 0); + return r; } void* toku_malloc_in_rollback(TOKUTXN txn, size_t size) { diff --git a/newbrt/log.h b/newbrt/log.h index 063e9277d0c..7a0e5a06634 100644 --- a/newbrt/log.h +++ b/newbrt/log.h @@ -24,8 +24,8 @@ struct logbytes { #define MALLOC_LOGBYTES(n) toku_malloc(sizeof(struct logbytes)+n -1) -void toku_logger_lock_init(void); -void toku_logger_lock_destroy(void); +int toku_logger_lock_init(void); +int toku_logger_lock_destroy(void); int toku_logger_create(TOKULOGGER */*resultp*/); void toku_logger_set_cachetable (TOKULOGGER, CACHETABLE); void toku_logger_write_log_files (TOKULOGGER, int do_write_log_files); diff --git a/newbrt/tests/minicron-test.c b/newbrt/tests/minicron-test.c index b66596e019c..1048061a5d3 100644 --- a/newbrt/tests/minicron-test.c +++ b/newbrt/tests/minicron-test.c @@ -1,29 +1,11 @@ #include +#include "test.h" #include "minicron.h" #include #include #include #include -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 tdiff (struct timeval *a, struct timeval *b) { return (a->tv_sec-b->tv_sec) + (a->tv_usec-b->tv_usec)*1e-6; @@ -146,8 +128,7 @@ test6 (void *v) { typedef void*(*ptf)(void*); int -main (int argc, const char *argv[]) -{ +test_main (int argc, const char *argv[]) { default_parse_args(argc,argv); gettimeofday(&starttime, 0); diff --git a/newbrt/tests/threadpool-test.c b/newbrt/tests/threadpool-test.c index e6996f5184d..34c43ed5f9f 100644 --- a/newbrt/tests/threadpool-test.c +++ b/newbrt/tests/threadpool-test.c @@ -1,3 +1,5 @@ +#include +#include "test.h" #include #include #include @@ -6,7 +8,6 @@ #include #include -#include #include "toku_os.h" #include "toku_pthread.h" #include "threadpool.h" @@ -83,7 +84,7 @@ usage (void) { } int -main(int argc, const char *argv[]) { +test_main (int argc, const char *argv[]) { int max_threads = 1; #if defined(__linux__) int do_malloc_fail = 0; diff --git a/newbrt/tests/workqueue-test.c b/newbrt/tests/workqueue-test.c index 21c64cb7082..851efdc5c76 100644 --- a/newbrt/tests/workqueue-test.c +++ b/newbrt/tests/workqueue-test.c @@ -1,8 +1,9 @@ +#include +#include "test.h" #include #include #include -#include #include "toku_assert.h" #include "toku_pthread.h" #include "memory.h" @@ -183,7 +184,7 @@ test_flow_control (int limit, int n, int maxthreads) { } int -main(int argc, const char *argv[]) { +test_main (int argc, const char *argv[]) { int i; for (i=1; i #include #include #include "toku_pthread.h" -#include "test.h" #include "checkpoint_test.h" @@ -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); snapshot(&db_test, TRUE); // take checkpoint, truncate db_test during checkpoint callback verify_sequential_rows(db_control.db, firstkey, numkeys); - pthread_join(thread, &ignore); + toku_pthread_join(thread, &ignore); db_shutdown(&db_control); + db_shutdown(&db_test); env_shutdown(); } @@ -79,7 +80,7 @@ truncate_thread(void * extra) { fflush(stdout); } 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); return NULL; } diff --git a/src/ydb-internal.h b/src/ydb-internal.h index 32232bb56f2..8647d1514c5 100644 --- a/src/ydb-internal.h +++ b/src/ydb-internal.h @@ -65,8 +65,8 @@ struct __toku_db_env_internal { Ephemeral locking ********************************************************* */ -void toku_ydb_lock_init(void); -void toku_ydb_lock_destroy(void); +int toku_ydb_lock_init(void); +int toku_ydb_lock_destroy(void); void toku_ydb_lock(void); void toku_ydb_unlock(void); diff --git a/src/ydb.c b/src/ydb.c index 69fcccf534e..66e76859591 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -31,6 +31,7 @@ const char *toku_copyright_string = "Copyright (c) 2007, 2008 Tokutek Inc. All #include "checkpoint.h" #include "key.h" + #ifdef TOKUTRACE #define DB_ENV_CREATE_FUN db_env_create_toku10 #define DB_CREATE_FUN db_create_toku10 @@ -51,31 +52,24 @@ init_dbt_realloc(DBT *dbt) { return dbt; } -static void -toku_ydb_init_malloc(void) { -#if defined(TOKU_WINDOWS) && TOKU_WINDOWS - //Set the heap (malloc/free/realloc) to use the low fragmentation mode. - ULONG HeapFragValue = 2; - - int r; - r = HeapSetInformation(GetProcessHeap(), - HeapCompatibilityInformation, - &HeapFragValue, - sizeof(HeapFragValue)); - //if (r==0) //Do some error output if necessary. - assert(r!=0); -#endif +int toku_ydb_init(void) { + int r = 0; + //Lower level must be initialized first. + if (r==0) + r = toku_brt_init(toku_ydb_lock, toku_ydb_unlock); + if (r==0) + r = toku_ydb_lock_init(); + return r; } -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) { - toku_brt_destroy(); - toku_ydb_lock_destroy(); +int toku_ydb_destroy(void) { + int r = 0; + 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 @@ -3839,3 +3833,14 @@ void db_env_set_checkpoint_callback (void (*callback_f)(void*), void* extra) { toku_checkpoint_safe_client_unlock(); //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(); +} + diff --git a/src/ydb.h b/src/ydb.h index 2a8259c33fb..be1b48c9ec7 100644 --- a/src/ydb.h +++ b/src/ydb.h @@ -5,10 +5,10 @@ // Initialize the ydb library globals. // Called when the ydb library is loaded. -void toku_ydb_init(void); +int toku_ydb_init(void); // Called when the ydb library is unloaded. -void toku_ydb_destroy(void); +int toku_ydb_destroy(void); // Called to use dlmalloc functions. void setup_dlmalloc(void) __attribute__((__visibility__("default"))); diff --git a/src/ydb_lib.c b/src/ydb_lib.c index eacd3bc822f..09b81cb2fcc 100644 --- a/src/ydb_lib.c +++ b/src/ydb_lib.c @@ -3,17 +3,20 @@ #include #include #include "ydb.h" +#include #if defined(__GNUC__) static void __attribute__((constructor)) libtokudb_init(void) { // 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) { // printf("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); - toku_ydb_destroy(); + int r = toku_ydb_destroy(); + assert(r==0); } #endif @@ -25,10 +28,12 @@ static void __attribute__((destructor)) libtokudb_destroy(void) { BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID reserved) { UNUSED(h); UNUSED(reserved); // printf("%s:%lu\n", __FUNCTION__, reason); + int r = 0; if (reason == DLL_PROCESS_ATTACH) - toku_ydb_init(); + r = toku_ydb_init(); if (reason == DLL_PROCESS_DETACH) - toku_ydb_destroy(); + r = toku_ydb_destroy(); + assert(r==0); return TRUE; } diff --git a/toku_include/Makefile.include b/toku_include/Makefile.include index 4428986ee33..75bf6c75d5b 100644 --- a/toku_include/Makefile.include +++ b/toku_include/Makefile.include @@ -230,7 +230,7 @@ ifneq ($(CYGWIN),) CRUNTIME=MTd 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 BINOUTPUT=-Fe OOUTPUT=-Fo @@ -393,11 +393,11 @@ $(NOIPO_YDB) $(IPO_YDB): $(@D)*.[ch] endif 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): $(PTHREAD_LIB) - cp $< $@ + cp -u $< $@ else PTHREAD_LOCAL= endif diff --git a/toku_include/toku_portability.h b/toku_include/toku_portability.h index 3fdc59fa209..e39b52ba39e 100644 --- a/toku_include/toku_portability.h +++ b/toku_include/toku_portability.h @@ -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_write (ssize_t (*pwrite_fun)(int, const void *, size_t)); +int toku_portability_init (void); +int toku_portability_destroy (void); + #if defined __cplusplus }; #endif diff --git a/utils/Makefile b/utils/Makefile index abf5232b10d..5691acd1eda 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -95,7 +95,7 @@ build.tdb: $(UTILS) $(STATIC_UTILS); build.bdb: $(BDB_UTILS); endif -copy.tdb: +copy.tdb: $(PTHREAD_LOCAL) cp ../lib/*.dll ./ copy.bdb: cp $(BDBDIR)/lib/*.dll ./ diff --git a/windows/Makefile b/windows/Makefile index 24a9ec97a65..64966e4b0b9 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -12,10 +12,14 @@ SRCS = $(wildcard *.c) OBJS = $(patsubst %.c,%.$(OEXT),$(SRCS)) 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) - if ! diff $< $@ 2>/dev/null; then cp $< $@; fi + cp -u $< $@ $(TARGET): $(OBJS) @@ -23,5 +27,5 @@ check: $(TARGET) cd tests && $(MAKE) check clean: - rm -rf $(TARGET) $(LIBPORTABILITY) + rm -rf $(TARGET) $(LIBPORTABILITY) $(PTHREAD_LIB) cd tests && $(MAKE) clean diff --git a/windows/tests/Makefile b/windows/tests/Makefile index fdb227fa3ce..6908b65decd 100644 --- a/windows/tests/Makefile +++ b/windows/tests/Makefile @@ -2,7 +2,7 @@ .DEFAULT_GOAL=all 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 SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes. diff --git a/windows/tests/test-dirs.c b/windows/tests/test-dirs.c index 5ff4c71586e..2346412326c 100644 --- a/windows/tests/test-dirs.c +++ b/windows/tests/test-dirs.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "toku_os.h" #include @@ -33,7 +33,7 @@ static int walk(const char *dirname) { return otherfound; } -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; int found; int fd; diff --git a/windows/tests/test-fileid.c b/windows/tests/test-fileid.c index e1ca58e3eae..e5f4138a908 100644 --- a/windows/tests/test-fileid.c +++ b/windows/tests/test-fileid.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "toku_os.h" int verbose=0; @@ -28,7 +28,7 @@ static void test_handles(const char *fname) { assert(r==0); } -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; for (i=1; i +#include #include #include #include @@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) { } #endif -int main(void) { +int test_main(int argc, char *argv[]) { int r; int fd; diff --git a/windows/tests/test-gettimeofday.c b/windows/tests/test-gettimeofday.c index a2b849c67e1..df0ae775d99 100644 --- a/windows/tests/test-gettimeofday.c +++ b/windows/tests/test-gettimeofday.c @@ -1,8 +1,9 @@ +#include #include #include #include -int main(void) { +int test_main(int argc, char *argv[]) { int r; struct timeval tv; struct timezone tz; diff --git a/windows/tests/test-max-data.c b/windows/tests/test-max-data.c index 66745569d01..983e4efd87f 100644 --- a/windows/tests/test-max-data.c +++ b/windows/tests/test-max-data.c @@ -4,10 +4,10 @@ #include #include #include -#include +#include #include -int main(void) { +int test_main(int argc, char *argv[]) { uint64_t maxdata; int r = toku_os_get_max_process_data_size(&maxdata); assert(r == 0); diff --git a/windows/tests/test-open-dir.c b/windows/tests/test-open-dir.c index b18dd27dbef..2cae10778b5 100644 --- a/windows/tests/test-open-dir.c +++ b/windows/tests/test-open-dir.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,7 +6,7 @@ #include #include -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; for (i=1; i #include #include #include @@ -18,7 +19,7 @@ #define TESTFILE "test-open-unlink-file" #define NEWNAME TESTFILE ".junk" -int main(void) { +int test_main(int argc, char *argv[]) { int r; int fd; diff --git a/windows/tests/test-open-unlink.c b/windows/tests/test-open-unlink.c index 7f6ee952fea..63b61c1a191 100644 --- a/windows/tests/test-open-unlink.c +++ b/windows/tests/test-open-unlink.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -17,7 +18,7 @@ const char TESTFILE[] = "test-open-unlink-file"; -int main(void) { +int test_main(int argc, char *argv[]) { int r; int fd; diff --git a/windows/tests/test-pread.c b/windows/tests/test-pread.c index 02a0487effd..e8de68158e9 100644 --- a/windows/tests/test-pread.c +++ b/windows/tests/test-pread.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "toku_os.h" int verbose; @@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) { printf("close %s %"PRIu64"\n", fname, r); } -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; for (i=1; i +#include #include #include #include @@ -68,7 +68,7 @@ static void *reader(void *arg) { return arg; } -int main(void) { +int test_main(int argc, char *argv[]) { int i; void *ret; toku_pthread_t t[2]; diff --git a/windows/tests/test-pthread-create.c b/windows/tests/test-pthread-create.c index 6f1b9be6192..52a7953fe8b 100644 --- a/windows/tests/test-pthread-create.c +++ b/windows/tests/test-pthread-create.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -20,7 +20,7 @@ static void *myfunc2(void *arg) { return arg; } -int main(void) { +int test_main(int argc, char *argv[]) { #define N 10 toku_pthread_t t[N]; int i; diff --git a/windows/tests/test-pthread-handle-leak.c b/windows/tests/test-pthread-handle-leak.c index 75de6a7b933..52b756fa3b8 100644 --- a/windows/tests/test-pthread-handle-leak.c +++ b/windows/tests/test-pthread-handle-leak.c @@ -1,6 +1,6 @@ // test for a pthread handle leak -#include +#include #include #include #include @@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) { return arg; } -int main(void) { +int test_main(int argc, char *argv[]) { #define N 1000000 int i; diff --git a/windows/tests/test-pwrite4g.c b/windows/tests/test-pwrite4g.c index e3a320170f5..38d562d429f 100644 --- a/windows/tests/test-pwrite4g.c +++ b/windows/tests/test-pwrite4g.c @@ -1,9 +1,9 @@ /* Verify that toku_os_pwrite does the right thing when writing beyond 4GB. */ #include -#include +#include #include -int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) { +int test_main(int argc, char *argv[]) { char fname[] = "pwrite4g.data"; int r; unlink(fname); diff --git a/windows/tests/test-rss.c b/windows/tests/test-rss.c index 54759bc36ee..b43de2fc41f 100644 --- a/windows/tests/test-rss.c +++ b/windows/tests/test-rss.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include 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; toku_os_get_max_rss(&rss); diff --git a/windows/tests/test-sleep.c b/windows/tests/test-sleep.c index 86ad34e020f..6fe30373818 100644 --- a/windows/tests/test-sleep.c +++ b/windows/tests/test-sleep.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,7 +7,7 @@ int verbose; -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; for (i=1; i +#include #include #include #include @@ -36,7 +36,7 @@ check_snprintf(int i) { } -int main(void) { +int test_main(int argc, char *argv[]) { int i; for (i = 0; i < 8; i++) { check_snprintf(i); diff --git a/windows/tests/test-stat.c b/windows/tests/test-stat.c index bef9de594b8..d7a257c163b 100644 --- a/windows/tests/test-stat.c +++ b/windows/tests/test-stat.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) { if (r!=0) assert(errno == ex_errno); } -int main(void) { +int test_main(int argc, char *argv[]) { int r; test_stat(".", 0, 0); diff --git a/windows/tests/test-strtoll.c b/windows/tests/test-strtoll.c index f9e9f75e088..cbebc8e4c45 100644 --- a/windows/tests/test-strtoll.c +++ b/windows/tests/test-strtoll.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "toku_os.h" int verbose; @@ -17,7 +17,7 @@ void testit(int64_t i, int base) { assert(i == o); } -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; int64_t n; int64_t o; diff --git a/windows/tests/test-unique-fileid.c b/windows/tests/test-unique-fileid.c index 526440e2a22..998e87908fb 100644 --- a/windows/tests/test-unique-fileid.c +++ b/windows/tests/test-unique-fileid.c @@ -2,9 +2,9 @@ #include #include #include -#include +#include -int main(void) { +int test_main(int argc, char *argv[]) { int r; int fd; struct fileid fid; diff --git a/windows/tests/test-usleep-ws.c b/windows/tests/test-usleep-ws.c index a93d29d4e26..7cd40b82c1b 100644 --- a/windows/tests/test-usleep-ws.c +++ b/windows/tests/test-usleep-ws.c @@ -4,7 +4,6 @@ #include #include #include -int verbose; int usleep(SOCKET s, unsigned int useconds) { fd_set dummy; @@ -16,7 +15,10 @@ int usleep(SOCKET s, unsigned int useconds) { return select(0, 0, 0, &dummy, &tv); } -int main(int argc, char *argv[]) { +#include +int verbose; + +int test_main(int argc, char *argv[]) { int i; int n = 1; WSADATA wsadata; diff --git a/windows/tests/test-usleep.c b/windows/tests/test-usleep.c index 92c8a38682e..dea157a7d17 100644 --- a/windows/tests/test-usleep.c +++ b/windows/tests/test-usleep.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,7 +7,7 @@ int verbose; -int main(int argc, char *argv[]) { +int test_main(int argc, char *argv[]) { int i; int n = 1; diff --git a/windows/tests/test.h b/windows/tests/test.h new file mode 100644 index 00000000000..e63b82af9b3 --- /dev/null +++ b/windows/tests/test.h @@ -0,0 +1,12 @@ +#include + +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; +} + diff --git a/windows/toku_pthread.c b/windows/toku_pthread.c index 2012ab6705f..7e23ae4fe74 100644 --- a/windows/toku_pthread.c +++ b/windows/toku_pthread.c @@ -1,6 +1,7 @@ #include #include #include +#include "toku_assert.h" int toku_pthread_yield(void) { @@ -8,3 +9,67 @@ toku_pthread_yield(void) { 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; +} + + diff --git a/windows/toku_pthread.h b/windows/toku_pthread.h index cb7f0349f93..cf658a16497 100644 --- a/windows/toku_pthread.h +++ b/windows/toku_pthread.h @@ -8,137 +8,204 @@ extern "C" { #include "pthread.h" #include -typedef pthread_attr_t toku_pthread_attr_t; -typedef pthread_t toku_pthread_t; -typedef pthread_mutexattr_t toku_pthread_mutexattr_t; -typedef pthread_mutex_t toku_pthread_mutex_t; -typedef pthread_condattr_t toku_pthread_condattr_t; -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 +int toku_pthread_win32_init(void); +int toku_pthread_win32_destroy(void); + +typedef pthread_attr_t toku_pthread_attr_t; +typedef pthread_t toku_pthread_t; +typedef pthread_mutexattr_t toku_pthread_mutexattr_t; +typedef pthread_mutex_t toku_pthread_mutex_t; +typedef pthread_condattr_t toku_pthread_condattr_t; +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 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 toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) { - return pthread_rwlock_destroy(rwlock); + return pthread_win32.pthread_rwlock_destroy(rwlock); } static inline int toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) { - return pthread_rwlock_rdlock(rwlock); + return pthread_win32.pthread_rwlock_rdlock(rwlock); } static inline int toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) { - return pthread_rwlock_unlock(rwlock); + return pthread_win32.pthread_rwlock_unlock(rwlock); } static inline int toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) { - return pthread_rwlock_wrlock(rwlock); + return pthread_win32.pthread_rwlock_wrlock(rwlock); } static inline int 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); + static inline int toku_pthread_attr_init(toku_pthread_attr_t *attr) { - return pthread_attr_init(attr); + return pthread_win32.pthread_attr_init(attr); } static inline int toku_pthread_attr_destroy(toku_pthread_attr_t *attr) { - return pthread_attr_destroy(attr); + return pthread_win32.pthread_attr_destroy(attr); } static inline 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 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 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 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 toku_pthread_t toku_pthread_self(void) { - return pthread_self(); + return pthread_win32.pthread_self(); } #define TOKU_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER static inline 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 int toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex) { - return pthread_mutex_destroy(mutex); + return pthread_win32.pthread_mutex_destroy(mutex); } static inline 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); static inline int toku_pthread_mutex_unlock(toku_pthread_mutex_t *mutex) { - return pthread_mutex_unlock(mutex); + return pthread_win32.pthread_mutex_unlock(mutex); } static inline 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 int toku_pthread_cond_destroy(toku_pthread_cond_t *cond) { - return pthread_cond_destroy(cond); + return pthread_win32.pthread_cond_destroy(cond); } static inline 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 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 int toku_pthread_cond_signal(toku_pthread_cond_t *cond) { - return pthread_cond_signal(cond); + return pthread_win32.pthread_cond_signal(cond); } static inline 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) diff --git a/windows/windows.c b/windows/windows.c index d5fbd3e38de..e516dd26a9b 100644 --- a/windows/windows.c +++ b/windows/windows.c @@ -20,6 +20,40 @@ #include #include +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 toku_os_get_file_size(int fildes, int64_t *sizep) {