merge some tokudb.1032 into 1032b. addresses #1032

git-svn-id: file:///svn/toku/tokudb.1032b@7778 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
Rich Prohaska 2013-04-16 23:57:27 -04:00 committed by Yoni Fogel
parent ef43452992
commit 0d44815bf5
63 changed files with 4615 additions and 654 deletions

385
include/Makefile.include Normal file
View file

@ -0,0 +1,385 @@
# -*- Mode: Makefile -*-
# TODO: Find a way to point out directories (i.e. current dir, or root dir)
# TODO: Find the names of the icc windows library includes.. i.e. dlls/etc.
# TODO: Find icc equivalents for W64 (warn about 32 vs 64 bit incompatibility
# TODO: Add (linux) icc warning about windows porting issues.
# TODO: There is an icc option for short 1-liner diagnostics.. see if there is
# an opposite! (i.e. long diagnostics which maybe will give us a stack trace
# for warnings)
# TODO: Learn how the hell to use idb.
#
# Default include makefile.
# Before (or after?) including this makefile, define the following variables
# INCLUDES = -I $(TOKUROOT)/.. -I . -I $(TOKUROOT)/... #Whatever include directories
# List of directories to include for search paths.
# TOKUROOT = absolute path of the root of this branch.
# TODO: find alternative way to do this.
# BINS = base names for bins
# SUBDIRS = Subdirs to make/clean
#
# On cygwin do:
# make CYGWIN=cygwin check
#
# For default=debug (no optimization) do
# make DEBUG=1
# For verbose output do
# make VERBOSE=1
# For very verbose output do
# make VERBOSE=2
# For CIL do
# make CIL=1
# For coverage do
# make GCOV=1
# For profiling do
# make PROF=1
# To make warnings be warnngs instead of errors do
# make WERROR=
.DELETE_ON_ERROR:
ifneq ($(GCOV),)
GCOV_FLAGS = -fprofile-arcs -ftest-coverage
endif
ifneq ($(PROF),)
PROF_FLAGS = -pg
endif
OPT_OPTFLAGS = -O3 -finline-functions
DBG_OPTFLAGS = -O0
ifeq ($(VERBOSE),2)
VERBVERBOSE=-v
MAYBEATSIGN=
else ifeq ($(VERBOSE),1)
VERBVERBOSE=-q
MAYBEATSIGN=
else
VERBVERBOSE=-q
MAYBEATSIGN=@
endif
CPPFLAGS = $(INCLUDEDIRS) -I$(PORTABILITY_HEADERS) -I$(TOKUROOT)include
#CFLAG default options
# Add -Wconversion #DISABLED for now.
WERROR = -Werror
WALL = -Wall -Wextra -Wcast-align -Wbad-function-cast
ifeq ($(SKIP_NORETURN),)
WALL += -Wmissing-noreturn
endif
FORMAT = -Wmissing-format-attribute
VISIBILITY= -fvisibility=hidden
FPICFLAGS = -fPIC
SHADOW = -Wshadow
SYMBOLS = -g3 -ggdb3
PORTABILITY=
SKIP_WARNING=
COMBINE_C = -combine -c
LIBPORTABILITY = $(TOKUROOT)lib/libportability.$(AEXT)
PORTABILITY_HEADERS= $(TOKUROOT)linux
ALWAYS_LINK= $(LIBPORTABILITY) -lz -lpthread
C99 = -std=c99
W64 = #-Wshorten-64-to-32
BINOUTPUT = -o
OOUTPUT = -o
AROUTPUT =#empty
BINSUF=#none
WRONGBINSUF=.exe
OEXT=o
WRONGOEXT=obj
AEXT=a
WRONGAEXT=lib
SOEXT=so
WRONGSOEXT=dll
AR=ar
DBG_ARFLAGS=r
OPT_ARFLAGS=r
LINK=-l
DEPEND_COMPILE += \
$(TOKUROOT)include/db.h \
$(TOKUROOT)include/os.h \
$(TOKUROOT)include/portability.h \
$(TOKUROOT)include/rdtsc.h \
# keep this line so I can have a \ on the previous line
CCQUIET=
comma:=,
empty:=#
space:=$(empty) $(empty)
LINK_LPATH=$(patsubst %,-Wl$(comma)-rpath$(comma)%,$(RPATH_DIRS))
LINK_RPATH=$(patsubst %,-L%$(space),$(RPATH_DIRS))
DLINK_FILES_PREPROCESS_1=$(patsubst %.$(SOEXT),%,$(DLINK_FILES))
DLINK_FILES_PREPROCESS_2=$(patsubst lib%,%,$(notdir $(DLINK_FILES_PREPROCESS_1)))
LINK_DLINK_FILES=$(patsubst %,$(LINK)%,$(notdir $(DLINK_FILES_PREPROCESS_2)))
CRUNTIME=
DEPEND_LINK += \
$(LIBPORTABILITY) \
$(LINK_FILES) \
# keep this line so I can have a \ on the previous line
ifeq ($(CYGWIN),)
OS_CHOICE=linux
else ifneq ($(CC),icc)
OS_CHOICE=linux
else
OS_CHOICE=windows
endif
DEPEND_COMPILE += $(wildcard $(TOKUROOT)$(OS_CHOICE)/*.h)
#Tools
VGRIND=valgrind --quiet --error-exitcode=1 --leak-check=full --show-reachable=yes \
--suppressions=$(TOKUROOT)newbrt/valgrind.suppressions \
--suppressions=$(TOKUROOT)src/tests/bdb.suppressions
HGRIND=valgrind --quiet --tool=helgrind
# When debugging, try: valgrind --show-reachable=yes --leak-check=full ./brt-test
# When debugging, try: valgrind --show-reachable=yes --leak-check=full ./brt-test
ifeq ($(CC),icc)
#icc only:
OPT_OPTFLAGS = -O3 -ip -ipo1
DBG_OPTFLAGS = -O0
COMBINE_C = -ipo-c
FORMAT= #No argument for extra format warnings.
WALL = -Wall -Wcheck # '-Wextra' becomes '-Wcheck' in icc
SYMBOLS= -g -debug all -inline-debug-info
PORTABILITY=-diag-enable port-win
AR=xiar
ifneq ($(CYGWIN),)
#Cygwin
ICC_NOWARN=-Qdiag-disable:
SKIP_WARNING += $(ICC_NOWARN)869 # Don't complain about unused variables (since we defined __attribute__ to be nothing.)
else
#Linux
ICC_NOWARN=-diag-disable #Need the space
endif
SKIP_WARNING += $(ICC_NOWARN)177 # Don't complain about static variables that are not used.
#SKIP_WARNING += $(ICC_NOWARN)188 # Don't complain about enumerated type mixed with another type.
SKIP_WARNING += $(ICC_NOWARN)589 # Don't complain about goto into a block that skips initializing variables. GCC catches the actual uninitialized variables.
SKIP_WARNING += $(ICC_NOWARN)981 # Don't complain about "operands are evaluated in unspecified order". This seems to be generated whenever more than one argument to a function or operand is computed by function call.
SKIP_WARNING += $(ICC_NOWARN)1324 # Don't complain about rdtsc clobbering its registers more than once.
endif
ifneq ($(CYGWIN),)
#Cygwin (Windows) Must override some settings
BINSUF=.exe
WRONGBINSUF=#empty
ALWAYS_LINK=$(LIBPORTABILITY) /usr/lib/libz.a
VGRIND =#No Valgrind in cygwin
HGRIND =#No Hgrind in cygwin
FPICFLAGS=#FPIC is default and not allowed as an option.
VISIBILITY=#Not supported
SHADOW=#Not supported
ifeq ($(CC),icc)
#Cygwin icc only
ifeq ($(CRUNTIME),)
ifneq ($(DEBUG),)
CRUNTIME=MDd
else
CRUNTIME=MD
endif
endif
ALWAYS_LINK=$(LIBPORTABILITY) $(TOKUROOT)windows/lib/$(CRUNTIME)/zlib.lib Ws2_32.lib psapi.lib
LINK=#Empty
BINOUTPUT=-Fe
OOUTPUT=-Fo
AROUTPUT=/out:
OEXT=obj
WRONGOEXT=o
AEXT=lib
WRONGAEXT=a
SOEXT=dll
WRONGSOEXT=so
C99 = -Qstd=c99
OPT_OPTFLAGS = -Ox -Qip -Qipo1
DBG_OPTFLAGS = -Od
COMBINE_C = -Qipo-c
WERROR = -WX # Windows icc version of -Werror
SYMBOLS= -Zi -debug:all -Qinline-debug-info
PORTABILITY=
SKIP_WARNING += $(ICC_NOWARN)1786 # Don't complain about 'read/write/other standards' being deprecated
PORTABILITY_HEADERS = $(TOKUROOT)windows
AR=xilib
DBG_AROPT=-qnoipo
OPT_AROPT=-qipo
DBG_ARFLAGS=$(DBG_AROPT) -lib /VERBOSE /WX /NOLOGO
OPT_ARFLAGS=$(OPT_AROPT) -lib /VERBOSE /WX /NOLOGO
CCQUIET=-nologo
LINK_DLINK_FILES=$(patsubst %.$(SOEXT),%.$(AEXT),$(DLINK_FILES))
LINK_RPATH=
LINK_LPATH=
DEPEND_LINK += $(LINK_DLINK_FILES)
W64 = -Wport #-Wp64
else
#Cygwin gcc only
FORMAT = -Wno-format
endif
endif
ifneq ($(DEBUG),)
OPTFLAGS = $(DBG_OPTFLAGS)
ARFLAGS = $(DBG_ARFLAGS)
else
OPTFLAGS = $(OPT_OPTFLAGS)
ARFLAGS = $(OPT_ARFLAGS)
endif
CFLAGS = $(WALL) $(W64) $(WERROR) $(FORMAT) $(VISIBILITY) $(FPICFLAGS) $(SHADOW)
CFLAGS += $(OPTFLAGS) $(GCOV_FLAGS) $(PROF_FLAGS)
CFLAGS += $(SYMBOLS) $(SKIP_WARNING) $(C99) $(CCQUIET)
LDFLAGS_NOLIB = $(OPTFLAGS) $(SYMBOLS) $(GCOV_FLAGS) $(PROF_FLAGS)
LDFLAGS = $(LDFLAGS_NOLIB) $(LINK_FILES) $(ALWAYS_LINK) $(LINK_DLINK_FILES) $(LINK_RPATH) $(LINK_LPATH)
ifneq ($(CRUNTIME),)
LDFLAGS += -$(CRUNTIME)
CFLAGS += -$(CRUNTIME)
endif
# Need XOPEN_SOURCE=600 to get strtoll()
CPPFLAGS += -D_SVID_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_XOPEN_SOURCE=600
#TODO: Fix this up if we want to keep using CIL.
#ifeq ($(CIL),1)
# CC=../../cil/cil-1.3.6/bin/cilly --merge --keepmerged
#endif
# When debugging, try: valgrind --show-reachable=yes --leak-check=full ./brt-test
ifneq ($(CYGWIN),)
CSCOPE=mlcscope
else
CSCOPE=cscope
endif
.PHONY: tags
tags: cscope.out TAGS
TAGS: $(TOKUROOT)*/*.[ch] $(TOKUROOT)*/*/*.[ch] $(TOKUROOT)*/*/*/*.[ch]
$(MAYBEATSIGN)etags $(TOKUROOT)*/*.[ch] $(TOKUROOT)*/*/*.[ch] $(TOKUROOT)*/*/*/*.[ch]
cscope.files: $(TOKUROOT)*/*.[ch] $(TOKUROOT)*/*/*.[ch] $(TOKUROOT)*/*/*/*.[ch]
$(MAYBEATSIGN)(echo $(TOKUROOT)*/*.[ch] $(TOKUROOT)*/*/*.[ch] $(TOKUROOT)*/*/*/*.[ch] | tr " " "\n") > $@ # Very long command line quieted.
cscope.out: cscope.files $(TOKUROOT)*/*.[ch] $(TOKUROOT)*/*/*.[ch] $(TOKUROOT)*/*/*/*.[ch]
$(MAYBEATSIGN)$(CSCOPE) -b
.PHONY: clean clean-default
clean: clean-default
clean-default:
$(MAYBEATSIGN)rm -f $(BINS) *.$(AEXT) *.$(SOEXT) *.$(OEXT)
$(MAYBEATSIGN)rm -f *.bb *.bbg *.da *.gcov *.gcno *.gcda
$(MAYBEATSIGN)rm -f *.exe *.obj *.pdb *.ilk TAGS cscope.out cscope.files
#Prevent using the wrong extensions/target types (Otherwise prereqs get confused).
%$(WRONGBINSUF): %.c
$(MAYBEATSIGN)echo "Wrong target type: $@ should be $*$(BINSUF)" && false
%$(WRONGBINSUF): %.$(WRONGOEXT)
$(MAYBEATSIGN)echo "Wrong target type: $@ should be $*$(BINSUF)" && false
%.$(WRONGOEXT): %.c
$(MAYBEATSIGN)echo "Wrong target type: $@ should be $*.$(OEXT)" && false
%.$(WRONGAEXT):
$(MAYBEATSIGN)echo "Wrong target type: $@ should be $*.$(AEXT)" && false
%.$(WRONGSOEXT):
$(MAYBEATSIGN)echo "Wrong target type: $@ should be $*.$(SOEXT)" && false
ifeq ($(SKIP_LIBPORTABILITYRULE),)
ifeq ($(CYGWIN),)
$(LIBPORTABILITY): $(TOKUROOT)linux/*.[ch]
$(MAYBEATSIGN)cd $(TOKUROOT)linux && $(MAKE) -s install
else ifneq ($(CC),icc)
$(LIBPORTABILITY): $(TOKUROOT)linux/*.[ch]
$(MAYBEATSIGN)cd $(TOKUROOT)linux && $(MAKE) -s install
else
$(LIBPORTABILITY): $(TOKUROOT)windows/*.[ch]
$(MAYBEATSIGN)cd $(TOKUROOT)windows && $(MAKE) -s install
endif
endif
ifeq ($(SKIP_LOCKTREERULE),)
LOCKTREE = $(TOKUROOT)src/lock_tree/locktree.$(AEXT)
LOCKTREE_LINEAR = $(TOKUROOT)src/lock_tree/locktree_linear.$(AEXT)
LOCKTREE_TLOG = $(TOKUROOT)src/lock_tree/locktree_tlog.$(AEXT)
LOCKTREE_LOG = $(TOKUROOT)src/lock_tree/locktree_log.$(AEXT)
$(LOCKTREE) $(LOCKTREE_LINEAR) $(LOCKTREE_TLOG) $(LOCKTREE_LOG): $(@D)*.[ch]
$(MAYBEATSIGN)cd $(@D) && $(MAKE) -s $(@F)
endif
ifeq ($(SKIP_RANGETREERULE),)
RANGETREE = $(TOKUROOT)src/range_tree/rangetree.$(AEXT)
RANGETREE_LINEAR = $(TOKUROOT)src/range_tree/rangetree_linear.$(AEXT)
RANGETREE_TLOG = $(TOKUROOT)src/range_tree/rangetree_tlog.$(AEXT)
RANGETREE_LOG = $(TOKUROOT)src/range_tree/rangetree_log.$(AEXT)
$(RANGETREE) $(RANGETREE_LINEAR) $(RANGETREE_TLOG) $(RANGETREE_LOG): $(@D)*.[ch]
$(MAYBEATSIGN)cd $(@D) && $(MAKE) -s $(@F)
endif
ifeq ($(SKIP_NEWBRTRULE),)
NEWBRT = $(TOKUROOT)newbrt/newbrt.$(AEXT)
$(NEWBRT): $(@D)*.[ch]
$(MAYBEATSIGN)cd $(@D) && $(MAKE) -s $(@F)
endif
BIN_FROM_C_FLAGS =$(CFLAGS) $(CPPFLAGS) $(BINOUTPUT)$@ $(LDFLAGS)
BIN_FROM_C_FLAGS_NOLIB=$(CFLAGS) $(CPPFLAGS) $(BINOUTPUT)$@ $(LDFLAGS_NOLIB)
%$(BINSUF):%.c $(DEPEND_COMPILE) $(DEPEND_LINK)
$(MAYBEATSIGN)$(CC) $< $(BIN_FROM_C_FLAGS)
BIN_FROM_O_FLAGS =$(CFLAGS) $(CPPFLAGS) $(BINOUTPUT)$@ $(LDFLAGS)
BIN_FROM_O_FLAGS_NOLIB=$(CFLAGS) $(CPPFLAGS) $(BINOUTPUT)$@ $(LDFLAGS_NOLIB)
%$(BINSUF):%.$(OEXT) $(DEPEND_COMPILE) $(DEPEND_LINK)
$(MAYBEATSIGN)$(CC) $< $(BIN_FROM_O_FLAGS)
O_FROM_C_FLAGS= $(CFLAGS) $(CPPFLAGS) -c $(OOUTPUT)$@
%.$(OEXT):%.c $(DEPEND_COMPILE)
$(MAYBEATSIGN)$(CC) $< $(O_FROM_C_FLAGS)
%.$(AEXT):
$(MAYBEATSIGN)$(AR) $(ARFLAGS) $(AROUTPUT)$@ $^
ifeq ($(SOEXT),so)
EXPORTMAPFILE=export.map
EXPORTMAP = -Wl,--version-script=$(EXPORTMAPFILE)
SHARED=-shared
endif
ifeq ($(SOEXT),dll)
ifeq ($(DEBUG),)
SHARED=/LD
else
SHARED=/LDd
endif
EXPORTMAPFILE=export.def
EXPORTMAP=/link /def:$(EXPORTMAPFILE)
endif
SO_FLAGS=$(SHARED) $(BIN_FROM_O_FLAGS) $(EXPORTMAP)
%.$(SOEXT): $(EXPORTMAPFILE)
$(MAYBEATSIGN)$(CC) $(SO_FLAGS)
#Testing tools
ifeq ($(SUMMARIZE),1)
SUMMARIZE_CMD = ;if test $$? = 0; then printf "%-60sPASS\n" $(HERE)/$@; else printf "%-60sFAIL\n" $(HERE)/$@ ; test 0 = 1; fi
SUMMARIZE_SHOULD_FAIL= ;if test $$? = 0; then printf "%-60sXFAIL\n" $(HERE)/$@; else printf "%-60sXPASS\n" $(HERE)/$@ ; test 0 = 1; fi
INVERTER=;test $$? -ne 0
else
SUMMARIZE_CMD =
endif
#Auto change variables from raw to include .exe if necessary.
BINS = $(patsubst %,%$(BINSUF),$(BINS_RAW))
OBJS = $(patsubst %,%.$(OEXT),$(OBJS_RAW))
REGRESSION_TESTS = $(patsubst %,%$(BINSUF),$(REGRESSION_TESTS_RAW))

61
include/os.h Normal file
View file

@ -0,0 +1,61 @@
#if !defined(TOKU_OS_INTERFACE_H)
#define TOKU_OS_INTERFACE_H
#if defined __cplusplus
extern "C" {
#endif
#include "os-types.h"
// Returns: the current process id
int os_getpid(void);
// Returns: the current thread id
int os_gettid(void);
// Returns: the number of processors in the system
int os_get_number_processors(void);
// Returns: the number of active processors in the system
int os_get_number_active_processors(void);
// Returns: the system page size
int os_get_pagesize(void);
// Returns: the total number of bytes of physical memory
uint64_t os_get_phys_memory_size(void);
// Returns: 0 on success
// sets fsize to the number of bytes in a file
int os_get_file_size(int fildes, int64_t *fsize);
// Returns: 0 on success
// Initializes id as a unique fileid for fildes on success.
int os_get_unique_file_id(int fildes, struct fileid *id);
//Locks a file (should not be open to begin with).
//Returns: file descriptor (or -1 on error)
int os_lock_file(char *name);
//Unlocks and closes a file locked by os_lock_on_file
int os_unlock_file(int fildes);
int os_mkdir(const char *pathname, mode_t mode);
// Get the current process user and kernel use times
int os_get_process_times(struct timeval *usertime, struct timeval *kerneltime);
// Get the current in memory size (in bytes) of the current process
int os_get_rss(int64_t *rss);
// Get the maximum in memory size (in bytes) of the current process
int os_get_max_rss(int64_t *maxrss);
int os_initialize_settings(int verbosity);
#if defined __cplusplus
};
#endif
#endif

86
include/portability.h Normal file
View file

@ -0,0 +1,86 @@
#ifndef TOKU_PORTABILITY_H
#define TOKU_PORTABILITY_H
#if defined __cplusplus
extern "C" {
#endif
// Portability layer
#define DEV_NULL_FILE "/dev/null"
#if defined(_MSC_VER)
// Microsoft compiler
#define TOKU_WINDOWS 1
#endif
#if defined(__INTEL_COMPILER)
// Intel compiler
#if defined(__ICL)
#define TOKU_WINDOWS 1
#endif
#undef DEV_NULL_FILE
#define DEV_NULL_FILE "NUL"
#endif
#if defined(TOKU_WINDOWS)
// Windows
// ntohl and htonl are defined in winsock.h
#include <winsock.h>
#include <direct.h>
#include <sys/types.h>
#include "stdint.h"
#include "inttypes.h"
#include "toku_pthread.h"
#include "unistd.h"
#include "misc.h"
#define UNUSED_WARNING(a) a=a /* To make up for missing attributes */
#if defined(__ICL)
#define __attribute__(x) /* Nothing */
#endif
#elif defined(__INTEL_COMPILER)
#if defined(__ICC)
// Intel linux
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/time.h>
#endif
#elif defined(__GNUC__)
// GCC linux
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/types.h>
// Define ntohl using arpa/inet.h
#include <arpa/inet.h>
#include <sys/time.h>
#else
#error Not ICC and not GNUC. What compiler?
#endif
#include "os.h"
#define UU(x) x __attribute__((__unused__))
#if defined __cplusplus
};
#endif
#endif

21
linux/Makefile Normal file
View file

@ -0,0 +1,21 @@
# -*- Mode: Makefile -*-
.DEFAULT_GOAL=install
TOKUROOT=../
INCLUDEDIRS=-I$(TOKUROOT)include/linux -I$(TOKUROOT)newbrt
include $(TOKUROOT)include/Makefile.include
OPT_AROPT=-qnoipo #Disable ipo for lib creation even when optimization is on.
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.$(OEXT),$(SRCS))
TARGET = tokulinux.$(AEXT)
install: $(TARGET)
$(MAYBEATSIGN)cp $(TARGET) $(LIBPORTABILITY)
$(TARGET): $(OBJS)
clean:
$(MAYBEATSIGN)rm -rf $(TARGET) $(LIBPORTABILITY)

165
linux/linux.c Normal file
View file

@ -0,0 +1,165 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <assert.h>
#include "portability.h"
#include "os.h"
int
os_getpid(void) {
return getpid();
}
int
os_gettid(void) {
return syscall(__NR_gettid);
}
int
os_get_number_processors(void) {
return sysconf(_SC_NPROCESSORS_CONF);
}
int
os_get_number_active_processors(void) {
return sysconf(_SC_NPROCESSORS_ONLN);
}
int
os_get_pagesize(void) {
return sysconf(_SC_PAGESIZE);
}
uint64_t
os_get_phys_memory_size(void) {
uint64_t npages = sysconf(_SC_PHYS_PAGES);
uint64_t pagesize = sysconf(_SC_PAGESIZE);
return npages*pagesize;
}
int
os_get_file_size(int fildes, int64_t *fsize) {
struct stat sbuf;
int r = fstat(fildes, &sbuf);
if (r==0) {
*fsize = sbuf.st_size;
}
return r;
}
int
os_get_unique_file_id(int fildes, struct fileid *id) {
struct stat statbuf;
memset(id, 0, sizeof(*id));
int r=fstat(fildes, &statbuf);
if (r==0) {
memset(id, 0, sizeof(*id));
id->st_dev = statbuf.st_dev;
id->st_ino = statbuf.st_ino;
}
return r;
}
int
os_lock_file(char *name) {
int r;
int fd = open(name, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
if (fd>=0) {
r = flock(fd, LOCK_EX | LOCK_NB);
if (r!=0) {
r = errno; //Save errno from flock.
close(fd);
fd = -1; //Disable fd.
errno = r;
}
}
return fd;
}
int
os_unlock_file(int fildes) {
int r = flock(fildes, LOCK_UN);
if (r==0) r = close(fildes);
return r;
}
int
os_mkdir(const char *pathname, mode_t mode) {
int r = mkdir(pathname, mode);
return r;
}
int
os_get_process_times(struct timeval *usertime, struct timeval *kerneltime) {
int r;
struct rusage rusage;
r = getrusage(RUSAGE_SELF, &rusage);
if (r == -1)
return errno;
if (usertime)
*usertime = rusage.ru_utime;
if (kerneltime)
*kerneltime = rusage.ru_stime;
return 0;
}
int
os_initialize_settings(int UU(verbosity)) {
int r = 0;
static int initialized = 0;
assert(initialized==0);
initialized=1;
return r;
}
int
os_get_max_rss(int64_t *maxrss) {
char statusname[100];
sprintf(statusname, "/proc/%d/status", getpid());
FILE *f = fopen(statusname, "r");
if (f == NULL)
return errno;
int r = ENOENT;
char line[100];
while (fgets(line, sizeof line, f)) {
r = sscanf(line, "VmHWM:\t%lld kB\n", (long long *) maxrss);
if (r == 1) {
*maxrss *= 1<<10;
r = 0;
break;
}
}
fclose(f);
return r;
}
int
os_get_rss(int64_t *rss) {
char statusname[100];
sprintf(statusname, "/proc/%d/status", getpid());
FILE *f = fopen(statusname, "r");
if (f == NULL)
return errno;
int r = ENOENT;
char line[100];
while (fgets(line, sizeof line, f)) {
r = sscanf(line, "VmRSS:\t%lld kB\n", (long long *) rss);
if (r == 1) {
*rss *= 1<<10;
r = 0;
break;
}
}
fclose(f);
return r;
}

16
linux/os-types.h Normal file
View file

@ -0,0 +1,16 @@
#if !defined(OS_INTERFACE_LINUX_H)
#define OS_INTERFACE_LINUX_H
#include <sys/types.h>
typedef int os_handle_t;
struct fileid {
dev_t st_dev; /* device and inode are enough to uniquely identify a file in unix. */
ino_t st_ino;
};
#if !defined(O_BINARY)
#define O_BINARY 0
#endif
#endif

13
linux/tests/Makefile Normal file
View file

@ -0,0 +1,13 @@
CPPFLAGS = -I../../include
CFLAGS = -Wall -Werror -g -O0
LDFLAGS = ../tokulinux.a
SRCS = $(wildcard test-*.c)
TARGETS = $(patsubst %.c,%,$(SRCS))
all: $(TARGETS)
%: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS)
clean:
rm -rf $(TARGETS)

View file

@ -0,0 +1,11 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include "os.h"
int main(void) {
assert(os_get_pagesize() == getpagesize());
return 0;
}

30
linux/tests/test-wss.c Normal file
View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <os.h>
static void do_mallocs(void) {
int i;
for (i=0; i<1000; i++) {
int nbytes = 1024*1024;
void *vp = malloc(nbytes);
memset(vp, 0, nbytes);
}
}
int main(void) {
int64_t rss;
os_get_max_rss(&rss);
printf("%"PRId64"\n", rss);
do_mallocs();
os_get_max_rss(&rss);
printf("%"PRId64"\n", rss);
return 0;
}

19
linux/tests/test-xid.c Normal file
View file

@ -0,0 +1,19 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include "os.h"
#include <syscall.h>
int os_getpid(void);
static int gettid(void) {
return syscall(__NR_gettid);
}
int main(void) {
assert(os_getpid() == getpid());
assert(os_gettid() == gettid());
return 0;
}

6
linux/toku_pthread.c Normal file
View file

@ -0,0 +1,6 @@
#define _GNU_SOURCE 1
#include <toku_pthread.h>
int toku_pthread_yield(void) {
return pthread_yield();
}

107
linux/toku_pthread.h Normal file
View file

@ -0,0 +1,107 @@
#ifndef _TOKU_PTHREAD_H
#define _TOKU_PTHREAD_H
#if defined __cplusplus
extern "C" {
#endif
#include <pthread.h>
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;
int toku_pthread_yield(void);
static inline
int toku_pthread_attr_init(toku_pthread_attr_t *attr) {
return pthread_attr_init(attr);
}
static inline
int toku_pthread_attr_destroy(toku_pthread_attr_t *attr) {
return 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);
}
static inline
int toku_pthread_attr_setstacksize(toku_pthread_attr_t *attr, size_t stacksize) {
return 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);
}
static inline
int toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
return pthread_join(thread, value_ptr);
}
static inline
toku_pthread_t toku_pthread_self(void) {
return 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);
}
static inline
int toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex) {
return pthread_mutex_destroy(mutex);
}
static inline
int toku_pthread_mutex_lock(toku_pthread_mutex_t *mutex) {
return 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);
}
static inline
int toku_pthread_cond_init(toku_pthread_cond_t *cond, const toku_pthread_condattr_t *attr) {
return pthread_cond_init(cond, attr);
}
static inline
int toku_pthread_cond_destroy(toku_pthread_cond_t *cond) {
return 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);
}
static inline
int toku_pthread_cond_signal(toku_pthread_cond_t *cond) {
return pthread_cond_signal(cond);
}
static inline
int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) {
return pthread_cond_broadcast(cond);
}
#if defined __cplusplus
};
#endif
#endif

View file

@ -1,120 +1,38 @@
# On cygwin do:
# make CYGWIN=cygwin check
# -*- Mode: Makefile -*-
# For verbose output do
# make VERBOSE=1
# For very verbose output do
# make VERBOSE=2
.DEFAULT_GOAL= build
TOKUROOT=../
INCLUDEDIRS=-I.
COMBINE=1
#TODO: Replace DEPEND_COMPILE with auto-dependancy generation.
DEPEND_COMPILE += \
$(wildcard *.h) \
log_header.h \
# keep this line so I can have a \ on the previous line
# For CIL do
# make CIL=1
NEWBRT = newbrt.$(AEXT)
#All executables need to statically link to newbrt
LINK_FILES += $(NEWBRT)
# GCOV_FLAGS = -fprofile-arcs -ftest-coverage
# PROF_FLAGS = -pg
OPTFLAGS = -O3
ifeq ($(VERBOSE),2)
VERBVERBOSE=-v
MAYBEATSIGN=
else
ifeq ($(VERBOSE),1)
VERBVERBOSE=-q
MAYBEATSIGN=
else
VERBVERBOSE=-q
MAYBEATSIGN=@
endif
endif
#CFLAG default options
WERROR = -Werror
WALL = -Wall -Wextra -Wcast-align -Wbad-function-cast
FORMAT = -Wmissing-format-attribute
VISIBILITY= -fvisibility=hidden
FPICFLAGS = -fPIC
SHADOW = -Wshadow
SYMBOLS = -g3 -ggdb3
PORTABILITY=
SKIP_WARNING=
COMBINE_C = -combine -c
LINK_FILES= -lz -lpthread
C99 = -std=c99
#Tools
VGRIND = valgrind --quiet --error-exitcode=1 --leak-check=yes
ifeq ($(CC),icc)
#icc only:
OPTFLAGS = -O3 -ip
COMBINE_C = -ipo-c
FORMAT= #No argument for extra format warnings.
WALL = -Wall -Wcheck # '-Wextra' becomes '-Wcheck' in icc
SYMBOLS= -g -debug all -inline-debug-info
PORTABILITY=-diag-enable port-win
ifneq ($(CYGWIN),)
#Cygwin
ICC_NOWARN=-Qdiag-disable:
else
#Linux
ICC_NOWARN=-diag-disable #Need the space
endif
SKIP_WARNING += $(ICC_NOWARN)177 # Don't complain about static variables that are not used.
#SKIP_WARNING += $(ICC_NOWARN)188 # Don't complain about enumerated type mixed with another type.
SKIP_WARNING += $(ICC_NOWARN)589 # Don't complain about goto into a block that skips initializing variables. GCC catches the actual uninitialized variables.
SKIP_WARNING += $(ICC_NOWARN)869 # Don't complain about unused variables (since we defined __attribute__ to be nothing.)
SKIP_WARNING += $(ICC_NOWARN)981 # Don't complain about "operands are evaluated in unspecified order". This seems to be generated whenever more than one argument to a function or operand is computed by function call.
SKIP_WARNING += $(ICC_NOWARN)1324 # Don't complain about rdtsc clobbering its registers more than once.
endif
ifneq ($(CYGWIN),)
#Cygwin (Windows) Must override some settings
CYG_ADD_LIBZ=/usr/lib/libz.a
VGRIND =#No Valgrind in cygwin
FPICFLAGS=#FPIC is default and not allowed as an option.
VISIBILITY=#Not supported
SHADOW=#Not supported
ifeq ($(CC),icc)
#Cygwin icc only
C99 = -Qstd=c99
OPTFLAGS = -Ox -Qip -Qipo2
COMBINE_C = -Qipo-c
WERROR = -WX # Windows icc version of -Werror
SYMBOLS= -Zi -debug:all -Qinline-debug-info
PORTABILITY=
LINK_FILES=#Not supported
SKIP_WARNING += $(ICC_NOWARN)1786 # Don't complain about 'read/write/other standards' being deprecated
else
#Cygwin gcc only
FORMAT = -Wno-format
endif
endif
CFLAGS = $(WALL) $(WERROR) $(FORMAT) $(VISIBILITY) $(FPICFLAGS) $(SHADOW)
CFLAGS += $(OPTFLAGS) $(GCOV_FLAGS) $(PROF_FLAGS)
CFLAGS += $(SYMBOLS) $(SKIP_WARNING) $(C99)
LDFLAGS = $(OPTFLAGS) $(SYMBOLS) $(GCOV_FLAGS) $(PROF_FLAGS) $(LINK_FILES)
# Need XOPEN_SOURCE=600 to get strtoll()
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_XOPEN_SOURCE=600
# Add -Wconversion
ifdef BRT_FANOUT
CPPFLAGS += -DBRT_FANOUT=$(BRT_FANOUT)
endif
ifeq ($(CIL),1)
CC=../../cil/cil-1.3.6/bin/cilly --merge --keepmerged
endif
SKIP_NEWBRTRULE=1
include $(TOKUROOT)include/Makefile.include
# When debugging, try: valgrind --show-reachable=yes --leak-check=full ./brt-test
BINS= brtdump \
tdb_logprint \
BINS_RAW= \
brtdump \
tdb_logprint \
tdb-recover \
# Intentionally left blank
# BINS will be defined automatically.
build default: bins libs tdb-recover tdb_logprint $(TEST_OFILES)
cd tests;$(MAKE) build
BINS_O = $(patsubst %,%.$(OEXT),$(BINS_RAW))
.PHONY: build default bins libs
build default: bins libs $(TEST_NEWBRT)
$(MAYBEATSIGN)cd tests;$(MAKE) build
BRT_SOURCES = \
block_allocator \
@ -122,6 +40,7 @@ BRT_SOURCES = \
brt-serialize \
brt-verify \
brt \
brt-test-helpers \
cachetable \
fifo \
fingerprint \
@ -135,82 +54,52 @@ BRT_SOURCES = \
omt \
recover \
roll \
toku_assert \
ybt \
x1764 \
trace_mem \
threadpool \
# keep this line so I can ha vea \ on the previous line
toku_assert \
trace_mem \
x1764 \
ybt \
# keep this line so I can have a \ on the previous line
ifeq ($(CIL),1)
OFILES = $(patsubst %,%.o,$(BRT_SOURCES))
else
OFILES = newbrt.o
endif
TEST_OFILES = brt-test-helpers.o
HFILES = $(wildcard *.h)
TEST_NEWBRT = brt-test-helpers.$(OEXT)
BRT_C_FILES = $(patsubst %,%.c,$(BRT_SOURCES))
BRT_O_FILES = $(patsubst %,%.$(OEXT),$(BRT_SOURCES))
ifeq ($(CIL),1)
newbrt.o: $(BRT_C_FILES) $(DEPEND_COMPILE)
$(MAYBEATSIGN)$(CC) $(BRT_C_FILES) $(COMBINE_C) $(O_FROM_C_FLAGS)
ifneq ($(CYGWIN),)
$(NEWBRT): $(BRT_O_FILES)
else ifeq ($(CC),icc)
$(NEWBRT): $(BRT_O_FILES)
else ifeq ($(COMBINE),0)
$(NEWBRT): $(BRT_O_FILES)
else
newbrt.o: $(BRT_C_FILES) $(HFILES)
$(CC) $(COMBINE_C) $(CFLAGS) $(CPPFLAGS) $(BRT_C_FILES) -o $@
$(NEWBRT): newbrt.o
endif
tdb_logprint.o: log-internal.h brttypes.h log.h kv-pair.h log_header.h
tdb_logprint: $(OFILES) $(CYG_ADD_LIBZ)
recover.o: log_header.h log-internal.h log.h brttypes.h kv-pair.h memory.h key.h cachetable.h
tdb-recover: $(OFILES) $(CYG_ADD_LIBZ)
roll.o: log_header.h log-internal.h log.h brttypes.h kv-pair.h memory.h key.h cachetable.h omt.h bread.h
log_code.o: log_header.h wbuf.h log-internal.h rbuf.h
log_code.$(OEXT): log_header.h wbuf.h log-internal.h rbuf.h
log_header.h: log_code.c
@echo generated log_code.c so log_header.c was also generated
log_code.c: logformat
./logformat
log_code.c: logformat$(BINSUF)
$(MAYBEATSIGN)./logformat
#Needs to be done manually since it does not include newbrt.
logformat$(BINSUF): logformat.c $(LIBPORTABILITY)
$(MAYBEATSIGN)$(CC) $< $(BIN_FROM_O_FLAGS_NOLIB) $(LIBPORTABILITY)
libs: $(OFILES) $(CYG_ADD_LIBZ)
libs: $(NEWBRT)
bins: $(BINS)
# Put the benchmarktest_256 first since it takes the longest (and we want to use parallelism in the make)
# Put check_benchmarktest_256 first because it is long-running (and therefore on the critical path, so get it started)
check: bins
cd tests;$(MAKE) check
check-fanout:
let BRT_FANOUT=4; \
while [ $$BRT_FANOUT -le 16 ] ;do \
$(MAKE) clean; $(MAKE) check BRT_FANOUT=$$BRT_FANOUT; \
let BRT_FANOUT=BRT_FANOUT+1; \
done
BRT_INTERNAL_H_INCLUDES = brt-internal.h cachetable.h fifo.h omt.h brt.h brt-search.h brttypes.h ybt.h log.h ../include/db.h kv-pair.h memory.h mempool.h leafentry.h log_header.h
brt-test-helpers.o: $(BRT_INTERNAL_H_INCLUDES) toku_assert.h
logformat: logformat.c
brt-serialize-test.o: $(BRT_INTERNAL_H_INCLUDES)
$(OFILES): $(BRT_INTERNAL_H_INCLUDES)
test_toku_malloc_plain_free: newbrt.o
cachetable-test.o: cachetable.h memory.h
cachetable-test: $(OFILES) $(CYG_ADD_LIBZ)
cachetable-test2.o: cachetable.h memory.h
cachetable-test2: $(OFILES) $(CYG_ADD_LIBZ)
test-assert: newbrt.o
brtdump: $(OFILES) $(CYG_ADD_LIBZ)
test_oexcl: test_oexcl.o newbrt.o
$(MAYBEATSIGN)cd tests;$(MAKE) check
%$(BINSUF): $(NEWBRT) $(LIBPORTABILITY)
checko2:
ifeq ($(OPTFLAGS),-O3)
@ -221,17 +110,13 @@ endif
clean: clean-local clean-tests
clean-tests:
cd tests;$(MAKE) clean
$(MAYBEATSIGN)cd tests;$(MAKE) clean
clean-local:
rm -rf $(BINS) *.o *.bb *.bbg *.da *.gcov *.gcno *.gcda
rm -rf test_oexcl.c.tmp *.brt
rm -rf *.obj *.pdb *.ilk *.exe
rm -rf log_code.c log_header.h logformat
$(MAYBEATSIGN)rm -rf $(NEWBRT)
$(MAYBEATSIGN)rm -rf test_oexcl.c.tmp *.brt
$(MAYBEATSIGN)rm -rf log_code.c log_header.h logformat
# After doing (cd ../src/tests;make test_log5.recover), run these. The files should have no differences.
testdump: brtdump
./brtdump ../src/tests/dir.test_log5.c.tdb.recover/foo.db > dump.r && ./brtdump ../src/tests/dir.test_log5.c.tdb/foo.db > dump.o && diff dump.o dump.r
testdump: brtdump$(BINSUF)
$(MAYBEATSIGN)./brtdump ../src/tests/dir.test_log5.c.tdb.recover/foo.db > dump.r && ./brtdump ../src/tests/dir.test_log5.c.tdb/foo.db > dump.$(OEXT) && diff dump.$(OEXT) dump.r
TAGS: ../*/*.c ../*/*.h
etags ../*/*.c ../*/*.h
ofiles: $(OFILES)

View file

@ -43,13 +43,13 @@ static void maybe_preallocate_in_file (int fd, u_int64_t size) {
}
// This mutex protects pwrite from running in parallel, and also protects modifications to the block allocator.
static pthread_mutex_t pwrite_mutex = PTHREAD_MUTEX_INITIALIZER;
static toku_pthread_mutex_t pwrite_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
static int pwrite_is_locked=0;
static inline void
lock_for_pwrite (void) {
// Locks the pwrite_mutex.
int r = pthread_mutex_lock(&pwrite_mutex);
int r = toku_pthread_mutex_lock(&pwrite_mutex);
assert(r==0);
pwrite_is_locked = 1;
}
@ -57,7 +57,7 @@ lock_for_pwrite (void) {
static inline void
unlock_for_pwrite (void) {
pwrite_is_locked = 0;
int r = pthread_mutex_unlock(&pwrite_mutex);
int r = toku_pthread_mutex_unlock(&pwrite_mutex);
assert(r==0);
}

View file

@ -16,10 +16,10 @@ typedef struct ctpair_rwlock *CTPAIR_RWLOCK;
struct ctpair_rwlock {
int pinned; // the number of readers
int want_pin; // the number of blocked readers
pthread_cond_t wait_pin;
toku_pthread_cond_t wait_pin;
int writer; // the number of writers
int want_write; // the number of blocked writers
pthread_cond_t wait_write;
toku_pthread_cond_t wait_write;
};
// initialize a read write lock
@ -29,9 +29,9 @@ void
ctpair_rwlock_init(CTPAIR_RWLOCK rwlock) {
int r;
rwlock->pinned = rwlock->want_pin = 0;
r = pthread_cond_init(&rwlock->wait_pin, 0); assert(r == 0);
r = toku_pthread_cond_init(&rwlock->wait_pin, 0); assert(r == 0);
rwlock->writer = rwlock->want_write = 0;
r = pthread_cond_init(&rwlock->wait_write, 0); assert(r == 0);
r = toku_pthread_cond_init(&rwlock->wait_write, 0); assert(r == 0);
}
// destroy a read write lock
@ -42,18 +42,18 @@ ctpair_rwlock_destroy(CTPAIR_RWLOCK rwlock) {
int r;
assert(rwlock->pinned == 0 && rwlock->want_pin == 0);
assert(rwlock->writer == 0 && rwlock->want_write == 0);
r = pthread_cond_destroy(&rwlock->wait_pin); assert(r == 0);
r = pthread_cond_destroy(&rwlock->wait_write); assert(r == 0);
r = toku_pthread_cond_destroy(&rwlock->wait_pin); assert(r == 0);
r = toku_pthread_cond_destroy(&rwlock->wait_write); assert(r == 0);
}
// obtain a read lock
// expects: mutex is locked
static inline void ctpair_read_lock(CTPAIR_RWLOCK rwlock, pthread_mutex_t *mutex) {
static inline void ctpair_read_lock(CTPAIR_RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
if (rwlock->writer || rwlock->want_write) {
rwlock->want_pin++;
while (rwlock->writer || rwlock->want_write) {
int r = pthread_cond_wait(&rwlock->wait_pin, mutex); assert(r == 0);
int r = toku_pthread_cond_wait(&rwlock->wait_pin, mutex); assert(r == 0);
}
rwlock->want_pin--;
}
@ -66,18 +66,18 @@ static inline void ctpair_read_lock(CTPAIR_RWLOCK rwlock, pthread_mutex_t *mutex
static inline void ctpair_read_unlock(CTPAIR_RWLOCK rwlock) {
rwlock->pinned--;
if (rwlock->pinned == 0 && rwlock->want_write) {
int r = pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
int r = toku_pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
}
}
// obtain a write lock
// expects: mutex is locked
static inline void ctpair_write_lock(CTPAIR_RWLOCK rwlock, pthread_mutex_t *mutex) {
static inline void ctpair_write_lock(CTPAIR_RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
if (rwlock->pinned || rwlock->writer) {
rwlock->want_write++;
while (rwlock->pinned || rwlock->writer) {
int r = pthread_cond_wait(&rwlock->wait_write, mutex); assert(r == 0);
int r = toku_pthread_cond_wait(&rwlock->wait_write, mutex); assert(r == 0);
}
rwlock->want_write--;
}
@ -91,9 +91,9 @@ static inline void ctpair_write_unlock(CTPAIR_RWLOCK rwlock) {
rwlock->writer--;
if (rwlock->writer == 0) {
if (rwlock->want_write) {
int r = pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
int r = toku_pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
} else if (rwlock->want_pin) {
int r = pthread_cond_broadcast(&rwlock->wait_pin); assert(r == 0);
int r = toku_pthread_cond_broadcast(&rwlock->wait_pin); assert(r == 0);
}
}
}

View file

@ -6,9 +6,9 @@
typedef struct writequeue *WRITEQUEUE;
struct writequeue {
PAIR head, tail; // head and tail of the linked list of pair's
pthread_cond_t wait_read; // wait for read
toku_pthread_cond_t wait_read; // wait for read
int want_read; // number of threads waiting to read
pthread_cond_t wait_write; // wait for write
toku_pthread_cond_t wait_write; // wait for write
int want_write; // number of threads waiting to write
int ninq; // number of pairs in the queue
char closed; // kicks waiting threads off of the write queue
@ -21,9 +21,9 @@ struct writequeue {
static void writequeue_init(WRITEQUEUE wq) {
wq->head = wq->tail = 0;
int r;
r = pthread_cond_init(&wq->wait_read, 0); assert(r == 0);
r = toku_pthread_cond_init(&wq->wait_read, 0); assert(r == 0);
wq->want_read = 0;
r = pthread_cond_init(&wq->wait_write, 0); assert(r == 0);
r = toku_pthread_cond_init(&wq->wait_write, 0); assert(r == 0);
wq->want_write = 0;
wq->ninq = 0;
wq->closed = 0;
@ -35,8 +35,8 @@ static void writequeue_init(WRITEQUEUE wq) {
static void writequeue_destroy(WRITEQUEUE wq) {
assert(wq->head == 0 && wq->tail == 0);
int r;
r = pthread_cond_destroy(&wq->wait_read); assert(r == 0);
r = pthread_cond_destroy(&wq->wait_write); assert(r == 0);
r = toku_pthread_cond_destroy(&wq->wait_read); assert(r == 0);
r = toku_pthread_cond_destroy(&wq->wait_write); assert(r == 0);
}
// close the writequeue
@ -45,8 +45,8 @@ static void writequeue_destroy(WRITEQUEUE wq) {
static void writequeue_set_closed(WRITEQUEUE wq) {
wq->closed = 1;
int r;
r = pthread_cond_broadcast(&wq->wait_read); assert(r == 0);
r = pthread_cond_broadcast(&wq->wait_write); assert(r == 0);
r = toku_pthread_cond_broadcast(&wq->wait_read); assert(r == 0);
r = toku_pthread_cond_broadcast(&wq->wait_write); assert(r == 0);
}
// determine whether or not the write queue is empty
@ -70,7 +70,7 @@ static void writequeue_enq(WRITEQUEUE wq, PAIR pair) {
wq->tail = pair;
wq->ninq++;
if (wq->want_read) {
int r = pthread_cond_signal(&wq->wait_read); assert(r == 0);
int r = toku_pthread_cond_signal(&wq->wait_read); assert(r == 0);
}
}
@ -80,12 +80,12 @@ static void writequeue_enq(WRITEQUEUE wq, PAIR pair) {
// write queue and return it
// returns: 0 if success, otherwise an error
static int writequeue_deq(WRITEQUEUE wq, pthread_mutex_t *mutex, PAIR *pairptr) {
static int writequeue_deq(WRITEQUEUE wq, toku_pthread_mutex_t *mutex, PAIR *pairptr) {
while (writequeue_empty(wq)) {
if (wq->closed)
return EINVAL;
wq->want_read++;
int r = pthread_cond_wait(&wq->wait_read, mutex); assert(r == 0);
int r = toku_pthread_cond_wait(&wq->wait_read, mutex); assert(r == 0);
wq->want_read--;
}
PAIR pair = wq->head;
@ -101,9 +101,9 @@ static int writequeue_deq(WRITEQUEUE wq, pthread_mutex_t *mutex, PAIR *pairptr)
// suspend the writer thread
// expects: the mutex is locked
static void writequeue_wait_write(WRITEQUEUE wq, pthread_mutex_t *mutex) {
static void writequeue_wait_write(WRITEQUEUE wq, toku_pthread_mutex_t *mutex) {
wq->want_write++;
int r = pthread_cond_wait(&wq->wait_write, mutex); assert(r == 0);
int r = toku_pthread_cond_wait(&wq->wait_write, mutex); assert(r == 0);
wq->want_write--;
}
@ -112,7 +112,7 @@ static void writequeue_wait_write(WRITEQUEUE wq, pthread_mutex_t *mutex) {
static void writequeue_wakeup_write(WRITEQUEUE wq) {
if (wq->want_write) {
int r = pthread_cond_broadcast(&wq->wait_write); assert(r == 0);
int r = toku_pthread_cond_broadcast(&wq->wait_write); assert(r == 0);
}
}

View file

@ -74,7 +74,7 @@ struct cachetable {
long size_writing; // the sum of the sizes of the pairs being written
LSN lsn_of_checkpoint; // the most recent checkpoint in the log.
TOKULOGGER logger;
pthread_mutex_t mutex; // coarse lock that protects the cachetable, the cachefiles, and the pair's
toku_pthread_mutex_t mutex; // coarse lock that protects the cachetable, the cachefiles, and the pair's
struct writequeue wq; // write queue for the writer threads
THREADPOOL threadpool; // pool of writer threads
char checkpointing; // checkpoint in progress
@ -84,7 +84,7 @@ struct cachetable {
static inline void cachetable_lock(CACHETABLE ct __attribute__((unused))) {
#if DO_CACHETABLE_LOCK
int r = pthread_mutex_lock(&ct->mutex); assert(r == 0);
int r = toku_pthread_mutex_lock(&ct->mutex); assert(r == 0);
#endif
}
@ -92,7 +92,7 @@ static inline void cachetable_lock(CACHETABLE ct __attribute__((unused))) {
static inline void cachetable_unlock(CACHETABLE ct __attribute__((unused))) {
#if DO_CACHETABLE_LOCK
int r = pthread_mutex_unlock(&ct->mutex); assert(r == 0);
int r = toku_pthread_mutex_unlock(&ct->mutex); assert(r == 0);
#endif
}
@ -105,11 +105,6 @@ static inline void cachetable_wait_write(CACHETABLE ct) {
}
}
struct fileid {
dev_t st_dev; /* device and inode are enough to uniquely identify a file in unix. */
ino_t st_ino;
};
struct cachefile {
CACHEFILE next;
u_int64_t refcount; /* CACHEFILEs are shared. Use a refcount to decide when to really close it.
@ -156,7 +151,7 @@ int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN initial_lsn,
t->checkpointing = 0;
int r;
writequeue_init(&t->wq);
r = pthread_mutex_init(&t->mutex, 0); assert(r == 0);
r = toku_pthread_mutex_init(&t->mutex, 0); assert(r == 0);
// set the max number of writeback threads to min(MAX_WRITER_THREADS,nprocs_online)
int nprocs = sysconf(_SC_NPROCESSORS_ONLN);
@ -969,7 +964,7 @@ int toku_cachetable_close (CACHETABLE *tp) {
cachetable_unlock(t);
threadpool_destroy(&t->threadpool);
writequeue_destroy(&t->wq);
r = pthread_mutex_destroy(&t->mutex); assert(r == 0);
r = toku_pthread_mutex_destroy(&t->mutex); assert(r == 0);
toku_free(t->table);
toku_free(t);
*tp = 0;
@ -1118,7 +1113,7 @@ FILENUM toku_cachefile_filenum (CACHEFILE cf) {
// The writer thread waits for work in the write queue and writes the pair
static void *cachetable_writer(void *arg) {
// printf("%lu:%s:start %p\n", pthread_self(), __FUNCTION__, arg);
// printf("%lu:%s:start %p\n", toku_pthread_self(), __FUNCTION__, arg);
CACHETABLE ct = arg;
int r;
cachetable_lock(ct);
@ -1132,7 +1127,7 @@ static void *cachetable_writer(void *arg) {
cachetable_write_pair(ct, p);
}
cachetable_unlock(ct);
// printf("%lu:%s:exit %p\n", pthread_self(), __FUNCTION__, arg);
// printf("%lu:%s:exit %p\n", toku_pthread_self(), __FUNCTION__, arg);
return arg;
}

View file

@ -12,7 +12,7 @@
#if !defined(TOKU_WINDOWS)
#include <dirent.h>
#include <inttypes.h>
#include <pthread.h>
#include <toku_pthread.h>
#include <sys/file.h>
#include <sys/resource.h>
#include <sys/time.h>

View file

@ -271,164 +271,164 @@ void toku_free_LEAFENTRY(LEAFENTRY le) {
}
inline int le_is_provdel(LEAFENTRY le) {
int le_is_provdel(LEAFENTRY le) {
return get_le_state(le)==LE_PROVDEL;
}
inline void* latest_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
void* latest_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
return key;
}
inline void* latest_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
void* latest_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
return kval;
}
inline void* latest_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
void* latest_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return 0; // for provisional delete, there is no *latest* key, so return NULL
}
inline void* latest_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
void* latest_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
return kval;
}
inline void* le_latest_key (LEAFENTRY le) {
void* le_latest_key (LEAFENTRY le) {
LESWITCHCALL(le, latest_key);
abort(); return 0; // make certain compilers happy
}
inline u_int32_t latest_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
u_int32_t latest_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
return keylen;
}
inline u_int32_t latest_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
u_int32_t latest_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
return klen;
}
inline u_int32_t latest_keylen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
u_int32_t latest_keylen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return 0; // for provisional delete, there is no *latest* key, so return 0. What else can we do?
}
inline u_int32_t latest_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
u_int32_t latest_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
return klen;
}
inline u_int32_t le_latest_keylen (LEAFENTRY le) {
u_int32_t le_latest_keylen (LEAFENTRY le) {
LESWITCHCALL(le, latest_keylen);
abort(); return 0; // make certain compilers happy
}
inline void* latest_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
void* latest_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
return val;
}
inline void* latest_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *pval) {
void* latest_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *pval) {
return pval;
}
inline void* latest_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
void* latest_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return 0; // for provisional delete, there is no *latest* key, so return NULL
}
inline void* latest_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
void* latest_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
return pval;
}
inline void* le_latest_val (LEAFENTRY le) {
void* le_latest_val (LEAFENTRY le) {
LESWITCHCALL(le, latest_val);
abort(); return 0; // make certain compilers happy
}
inline u_int32_t latest_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
u_int32_t latest_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
return vallen;
}
inline u_int32_t latest_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
u_int32_t latest_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
return plen;
}
inline u_int32_t latest_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
u_int32_t latest_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return 0; // for provisional delete, there is no *latest* key, so return 0. What else can we do?
}
inline u_int32_t latest_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
u_int32_t latest_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
return plen;
}
inline u_int32_t le_latest_vallen (LEAFENTRY le) {
u_int32_t le_latest_vallen (LEAFENTRY le) {
LESWITCHCALL(le, latest_vallen);
abort(); return 0; // make certain compilers happy
}
inline void* any_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
void* any_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
return key;
}
inline void* any_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
void* any_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
return kval;
}
inline void* any_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval)) {
void* any_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval)) {
return kval;
}
inline void* any_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
void* any_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
return kval;
}
inline void* le_any_key (LEAFENTRY le) {
void* le_any_key (LEAFENTRY le) {
LESWITCHCALL(le, any_key);
abort(); return 0; // make certain compilers happy
}
inline u_int32_t any_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
u_int32_t any_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
return keylen;
}
inline u_int32_t any_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
u_int32_t any_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
return klen;
}
inline u_int32_t any_keylen_le_provdel (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
u_int32_t any_keylen_le_provdel (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return klen;
}
inline u_int32_t any_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
u_int32_t any_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
return klen;
}
inline u_int32_t le_any_keylen (LEAFENTRY le) {
u_int32_t le_any_keylen (LEAFENTRY le) {
LESWITCHCALL(le, any_keylen);
abort(); return 0; // make certain compilers happy
}
inline void* any_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
void* any_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
return val;
}
inline void* any_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval, u_int32_t UU(plen), void *UU(pval)) {
void* any_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval, u_int32_t UU(plen), void *UU(pval)) {
return cval;
}
inline void* any_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval) {
void* any_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval) {
return cval;
}
inline void* any_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
void* any_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
return pval;
}
inline void* le_any_val (LEAFENTRY le) {
void* le_any_val (LEAFENTRY le) {
LESWITCHCALL(le, any_val);
abort(); return 0; // make certain compilers happy
}
inline u_int32_t any_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
u_int32_t any_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
return vallen;
}
inline u_int32_t any_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
u_int32_t any_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
return plen;
}
inline u_int32_t any_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t clen, void *UU(cval)) {
u_int32_t any_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t clen, void *UU(cval)) {
return clen; // for provisional delete, there is no *any* key, so return 0. What else can we do?
}
inline u_int32_t any_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
u_int32_t any_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
return plen;
}
inline u_int32_t le_any_vallen (LEAFENTRY le) {
u_int32_t le_any_vallen (LEAFENTRY le) {
LESWITCHCALL(le, any_vallen);
abort(); return 0; // make certain compilers happy
}
inline u_int64_t any_xid_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
u_int64_t any_xid_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
return 0;
}
inline u_int64_t any_xid_le_both (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
u_int64_t any_xid_le_both (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
return xid;
}
inline u_int64_t any_xid_le_provdel (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
u_int64_t any_xid_le_provdel (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
return xid;
}
inline u_int64_t any_xid_le_provpair (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
u_int64_t any_xid_le_provpair (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
return xid;
}
inline u_int64_t le_any_xid (LEAFENTRY le) {
u_int64_t le_any_xid (LEAFENTRY le) {
LESWITCHCALL(le, any_xid);
abort(); return 0; // make certain compilers happy
}

View file

@ -156,5 +156,57 @@ void* le_any_val (LEAFENTRY le);
u_int32_t le_any_vallen (LEAFENTRY le);
u_int64_t le_any_xid (LEAFENTRY le);
void *latest_key_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
void *latest_key_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
void *latest_key_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
void *latest_key_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int32_t latest_keylen_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int32_t latest_keylen_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int32_t latest_keylen_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int32_t latest_keylen_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
void *latest_val_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
void *latest_val_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
void *latest_val_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
void *latest_val_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int32_t latest_vallen_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int32_t latest_vallen_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int32_t latest_vallen_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int32_t latest_vallen_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int64_t latest_xid_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int64_t latest_xid_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int64_t latest_xid_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int64_t latest_xid_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
//
void *any_key_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
void *any_key_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
void *any_key_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
void *any_key_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int32_t any_keylen_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int32_t any_keylen_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int32_t any_keylen_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int32_t any_keylen_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
void *any_val_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
void *any_val_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
void *any_val_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
void *any_val_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int32_t any_vallen_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int32_t any_vallen_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int32_t any_vallen_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int32_t any_vallen_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
u_int64_t any_xid_le_committed(u_int32_t klen, void *kval, u_int32_t vallen, void *val);
u_int64_t any_xid_le_both(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval);
u_int64_t any_xid_le_provdel(TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval);
u_int64_t any_xid_le_provpair(TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval);
#endif

View file

@ -10,7 +10,7 @@
#include "memarena.h"
#include <stdio.h>
#if !defined(TOKU_WINDOWS)
#include <pthread.h>
#include <toku_pthread.h>
#endif
#include <sys/types.h>
#include <string.h>
@ -24,16 +24,16 @@
#define LOGGER_BUF_SIZE (1<<24)
struct mylock {
pthread_mutex_t lock;
toku_pthread_mutex_t lock;
int is_locked;
};
static inline int ml_init(struct mylock *l) {
l->is_locked=0;
return pthread_mutex_init(&l->lock, 0);
return toku_pthread_mutex_init(&l->lock, 0);
}
static inline int ml_lock(struct mylock *l) {
int r = pthread_mutex_lock(&l->lock);
int r = toku_pthread_mutex_lock(&l->lock);
assert(l->is_locked==0);
l->is_locked=1;
return r;
@ -41,11 +41,11 @@ static inline int ml_lock(struct mylock *l) {
static inline int ml_unlock(struct mylock *l) {
assert(l->is_locked==1);
l->is_locked=0;
return pthread_mutex_unlock(&l->lock);
return toku_pthread_mutex_unlock(&l->lock);
}
static inline int ml_destroy(struct mylock *l) {
assert(l->is_locked==0);
return pthread_mutex_destroy(&l->lock);
return toku_pthread_mutex_destroy(&l->lock);
}

View file

@ -1,122 +0,0 @@
#ifndef PORTABILITY_H
#define PORTABILITY_H
// Portability layer
#if defined(__INTEL_COMPILER)
#if !defined(__ICL) && !defined(__ICC)
#error Which intel compiler?
#endif
#if defined(__ICL) && defined(__ICC)
#error Cannot distinguish between windows and linux intel compiler
#endif
#if defined(__ICL)
//Windows Intel Compiler
#define TOKU_WINDOWS
//Define standard integer types.
typedef __int8 int8_t;
typedef unsigned __int8 u_int8_t;
typedef __int16 int16_t;
typedef unsigned __int16 u_int16_t;
typedef __int32 int32_t;
typedef unsigned __int32 u_int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 u_int64_t;
//Define printf types.
#define PRId64 "I64d"
#define PRIu64 "I64u"
#define PRId32 "d"
#define PRIu32 "u"
//Limits
#define INT8_MIN _I8_MIN
#define INT8_MAX _I8_MAX
#define UINT8_MAX _UI8_MAX
#define INT16_MIN _I16_MIN
#define INT16_MAX _I16_MAX
#define UINT16_MAX _UI16_MAX
#define INT32_MIN _I32_MIN
#define INT32_MAX _I32_MAX
#define UINT32_MAX _UI32_MAX
#define INT64_MIN _I64_MIN
#define INT64_MAX _I64_MAX
#define UINT64_MAX _UI64_MAX
#define srandom srand
#define random rand
#define FAKE_WINDOWS_STUBS 0 // Disable these fakes.
#if FAKE_WINDOWS_STUBS == 1
//#define chmod(a,b) (void)0 /* Remove temporarily till compatibility layer exists */
//Define chmod
typedef int mode_t;
static inline
int
chmod(const char *path, mode_t mode) {
//TODO: Write API to support what we really need.
//Linux version supports WRITE/EXECUTE/READ bits separately for user/group/world
//windows _chmod supports WRITE/READ bits separately for ?? one type (user? world?)
//See _chmod in sys/stat.h
//Supports setting read/write mode (not separately for user/group/world)
return 0;
}
#define S_IRUSR 0
#define S_IRGRP 0
#define S_IROTH 0
//Fake typedefs to skip warnings.
typedef size_t ssize_t;
typedef int pthread_cond_t;
typedef void* pthread_mutex_t;
struct timeval {
int tv_sec;
int tv_usec;
};
#endif //FAKE_WINDOWS_STUBS
#endif //Windows Intel Compiler
// Intel compiler.
// Define ntohl using bswap.
// Define __attribute__ to be null
#include <sys/types.h>
static inline
u_int32_t
ntohl(u_int32_t x) {
return _bswap(x);
}
static inline
u_int32_t
htonl(u_int32_t x) {
return _bswap(x);
}
#define __attribute__(x)
#elif defined __GNUC__
// Gcc:
// Define ntohl using arpa/inet.h
#include <arpa/inet.h>
#else
#error Not ICC and not GNUC. What compiler?
#endif
// This hack is to avoid initializing variables that gcc can figure out are not used in an undefined way.
// But some compiler cannot figure it out, so we initialize the value to zero.
#if defined __INTEL_COMPILER
#define MAYBE_INIT(n) = n
#elif defined __GNUC__
#define MAYBE_INIT(n)
#endif
#endif

View file

@ -8,7 +8,7 @@
*****************************************
*
* TokuDB employs readers/writers locks for the ephemeral locks (e.g.,
* on BRT nodes) Why not just use the pthread_rwlock API?
* on BRT nodes) Why not just use the toku_pthread_rwlock API?
*
* 1) we need multiprocess rwlocks (not just multithreaded)
*

View file

@ -1,3 +1,13 @@
.DEFAULT_GOAL=build
TOKUROOT=../../
INCLUDEDIRS=-I. -I..
include $(TOKUROOT)include/Makefile.include
CPPFLAGS += -D_GNU_SOURCE
ifeq ($(CC),icc)
SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes.
endif
# On cygwin do:
# make CYGWIN=cygwin check
@ -6,108 +16,10 @@
# For very verbose output do
# make VERBOSE=2
# GCOV_FLAGS = -fprofile-arcs -ftest-coverage
# PROF_FLAGS = -pg
OPTFLAGS = -O3
ifeq ($(VERBOSE),2)
VERBVERBOSE=-v
else
ifeq ($(VERBOSE),1)
VERBVERBOSE=-q
else
VERBVERBOSE=-q
endif
endif
#CFLAG default options
WERROR = -Werror
WALL = -Wall -Wextra -Wcast-align -Wbad-function-cast -Wmissing-noreturn
FORMAT = -Wmissing-format-attribute
VISIBILITY= -fvisibility=hidden
FPICFLAGS = -fPIC
SHADOW = -Wshadow
SYMBOLS = -g3 -ggdb3
PORTABILITY=
SKIP_WARNING=
COMBINE_C = -combine -c
LINK_FILES= -lz -lpthread
C99 = -std=c99
#Tools
VGRIND = valgrind --quiet --error-exitcode=1 --leak-check=yes --suppressions=../valgrind.suppressions
ifeq ($(CC),icc)
#icc only:
OPTFLAGS = -O3 -ip -ipo2
COMBINE_C = -ipo-c
FORMAT= #No argument for extra format warnings.
WALL = -Wall -Wcheck # '-Wextra' becomes '-Wcheck' in icc
SYMBOLS= -g -debug all -inline-debug-info
PORTABILITY=-diag-enable port-win
ifneq ($(CYGWIN),)
#Cygwin
ICC_NOWARN=-Qdiag-disable:
else
#Linux
ICC_NOWARN=-diag-disable #Need the space
endif
SKIP_WARNING += $(ICC_NOWARN)177 # Don't complain about static variables that are not used.
#SKIP_WARNING += $(ICC_NOWARN)188 # Don't complain about enumerated type mixed with another type.
SKIP_WARNING += $(ICC_NOWARN)589 # Don't complain about goto into a block that skips initializing variables. GCC catches the actual uninitialized variables.
SKIP_WARNING += $(ICC_NOWARN)869 # Don't complain about unused variables (since we defined __attribute__ to be nothing.)
SKIP_WARNING += $(ICC_NOWARN)981 # Don't complain about "operands are evaluated in unspecified order". This seems to be generated whenever more than one argument to a function or operand is computed by function call.
SKIP_WARNING += $(ICC_NOWARN)1324 # Don't complain about rdtsc clobbering its registers more than once.
endif
ifneq ($(CYGWIN),)
#Cygwin (Windows) Must override some settings
CYG_ADD_LIBZ=/usr/lib/libz.a
VGRIND =#No Valgrind in cygwin
FPICFLAGS=#FPIC is default and not allowed as an option.
VISIBILITY=#Not supported
SHADOW=#Not supported
ifeq ($(CC),icc)
#Cygwin icc only
C99 = -Qstd=c99
OPTFLAGS = -Ox -Qip -Qipo2
COMBINE_C = -Qipo-c
WERROR = -WX # Windows icc version of -Werror
SYMBOLS= -Zi -debug:all -Qinline-debug-info
PORTABILITY=
LINK_FILES=#Not supported
SKIP_WARNING += $(ICC_NOWARN)1786 # Don't complain about 'read/write/other standards' being deprecated
else
#Cygwin gcc only
FORMAT = -Wno-format
endif
endif
CFLAGS = $(WALL) $(WERROR) $(FORMAT) $(VISIBILITY) $(FPICFLAGS) $(SHADOW)
CFLAGS += $(OPTFLAGS) $(GCOV_FLAGS) $(PROF_FLAGS)
CFLAGS += $(SYMBOLS) $(SKIP_WARNING) $(C99)
LDFLAGS = $(OPTFLAGS) $(SYMBOLS) $(GCOV_FLAGS) $(PROF_FLAGS) $(LINK_FILES)
# Need XOPEN_SOURCE=600 to get strtoll()
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_XOPEN_SOURCE=600
CPPFLAGS += -D_GNU_SOURCE -I..
# Add -Wconversion
HERE=newbrt/tests
ifeq ($(SUMMARIZE),1)
SUMMARIZE_CMD = ;if test $$? = 0; then printf "%-60sPASS\n" $(HERE)/$@; else printf "%-60sFAIL\n" $(HERE)/$@ ; test 0 = 1; fi
else
SUMMARIZE_CMD =
endif
# Put these one-per-line so that if we insert a new one the svn diff can understand it better.
# Also keep them sorted.
REGRESSION_TESTS = \
REGRESSION_TESTS_RAW = \
block_allocator_test \
bread-test \
brt-serialize-test \
@ -121,7 +33,6 @@ REGRESSION_TESTS = \
brt-test3 \
brt-test4 \
brt-test5 \
test-dump-brt \
cachetable-rwlock-test \
cachetable-writequeue-test \
threadpool-test \
@ -136,8 +47,6 @@ REGRESSION_TESTS = \
cachetable-count-pinned-test \
cachetable-debug-test \
cachetable-debug-test \
cachetable-unpin-and-remove-test \
dup-delete-all \
fifo-test \
list-test \
keyrange \
@ -167,89 +76,55 @@ REGRESSION_TESTS = \
# This line intentially kept commented so I can have a \ on the end of the previous line
# Add in the binaries that must be run in various ways.
BINS = $(REGRESSION_TESTS) \
BINS_RAW = $(REGRESSION_TESTS_RAW) \
benchmark-test \
cachetable-scan \
# This line intentially kept commented so I can have a \ on the end of the previous line
# BINS will be defined by adding .exe if appropriate.
CHECKS = \
benchmarktest_256 \
test-assertA test-assertB \
$(REGRESSION_TESTS) \
benchmarktest_256 \
test-assertA \
test-assertB \
$(REGRESSION_TESTS) \
# This line intentially kept commented so I can have a \ on the previous line
ifeq ($(CIL),1)
CC=../../../cil/cil-1.3.6/bin/cilly --merge --keepmerged
endif
#CHECKS will be defined automatically.
build: $(BINS)
check: $(patsubst %,check_%,$(CHECKS))
check_fail:
test 0 = 1 $(SUMMARIZE_CMD)
$(MAYBEATSIGN)test 0 = 1 $(SUMMARIZE_CMD)
check_ok:
test 0 = 0 $(SUMMARIZE_CMD)
$(MAYBEATSIGN)test 0 = 0 $(SUMMARIZE_CMD)
check_benchmarktest_256: benchmark-test
$(VGRIND) ./benchmark-test $(VERBVERBOSE) --valsize 256 --verify 1 $(SUMMARIZE_CMD)
check_benchmarktest_256: benchmark-test$(BINSUF)
$(MAYBEATSIGN)$(VGRIND) ./$< $(VERBVERBOSE) --valsize 256 --verify 1 $(SUMMARIZE_CMD)
check_test-assertA: test-assert
check_test-assertA: test-assert$(BINSUF)
@# no arguments, should err
$(VGRIND) ./test-assert > /dev/null 2>&1 ; test $$? = 1 $(SUMMARIZE_CMD)
check_test-assertB: test-assert
$(MAYBEATSIGN)$(VGRIND) ./$< > /dev/null 2>&1 ; test $$? = 1 $(SUMMARIZE_CMD)
check_test-assertB: test-assert$(BINSUF)
@# one argument, not "ok" should err
@rm -f test-assert.out
($(VGRIND) ./test-assert notok) > test-assert.out 2>&1 ; test $$? = 1 && fgrep failed test-assert.out > /dev/null $(SUMMARIZE_CMD)
check_test-assertC: tst-assert
$(MAYBEATSIGN)($(VGRIND) ./$< notok) > test-assert.out 2>&1 ; test $$? = 1 && fgrep failed test-assert.out > /dev/null $(SUMMARIZE_CMD)
check_test-assertC: test-assert$(BINSUF)
check_test-assert: test-assert
check_test-assert$(BINSUF): test-assert$(BINSUF)
@# one argument, "ok" should not error
$(DVGRIND) ./test-assert ok $(SUMMARIZE_CMD)
$(MAYBEATSIGN)$(VGRIND) ./$< ok $(SUMMARIZE_CMD)
check_%: %
$(VGRIND) ./$< $(VERBVERBOSE) $(SUMMARIZE_CMD)
check_%$(BINSUF): %$(BINSUF)
$(MAYBEATSIGN)$(VGRIND) ./$< $(VERBVERBOSE) $(SUMMARIZE_CMD)
benchmark-test.o: ../brt.h ../brt-search.h ../../include/db.h
ifeq ($(CIL),1)
benchmark-test.$(OEXT): ../brt.h ../brt-search.h ../../include/db.h
BRT_SOURCES = \
block_allocator \
bread \
brt-serialize \
brt-verify \
brt \
cachetable \
fifo \
fingerprint \
key \
leafentry \
log \
log_code \
memory \
memarena \
mempool \
omt \
recover \
roll \
toku_assert \
ybt \
x1764 \
trace_mem \
threadpool \
# keep this line so I can ha vea \ on the previous line
$(BINS): $(patsubst %,../%.o,$(BRT_SOURCES)) $(CYG_ADD_LIBZ)
else
$(BINS): ../newbrt.o $(CYG_ADD_LIBZ)
endif
test-inc-split test-del-inorder: ../brt-test-helpers.o
LINK_FILES += ../newbrt.$(AEXT)
clean:
rm -rf $(BINS) *.o *.bb *.bbg *.da *.gcov *.gcno *.gcda
rm -rf test_oexcl.c.tmp *.brt *.dir *.tdb *.dat *.out
rm -rf *.exe *.pdb *.ilk *.obj
rm -f cachetable-fd-test.ctest2.data
$(MAYBEATSIGN)rm -rf *.dir
$(MAYBEATSIGN)rm -f cachetable-fd-test.ctest2.data test_oexcl.c.tmp
$(MAYBEATSIGN)rm -f *.brt *.tdb *.dat *.data *.out
foo: ../cachetable.$(OEXT) ../fifo.$(OEXT) ../fingerprint.$(OEXT) ../key.$(OEXT) ../memory.$(OEXT) ../memarena.$(OEXT) ../mempool.$(OEXT) ../omt.$(OEXT) ../toku_assert.$(OEXT) ../ybt.$(OEXT) ../x1764.$(OEXT) ../trace_mem.$(OEXT) ../threadpool.$(OEXT)
foo: ../cachetable.o ../fifo.o ../fingerprint.o ../key.o ../memory.o ../memarena.o ../mempool.o ../omt.o ../toku_assert.o ../ybt.o ../x1764.o ../trace_mem.o ../threadpool.o

View file

@ -1,4 +1,4 @@
#include "../portability.h"
#include "portability.h"
#include <assert.h>
#include <fcntl.h>

View file

@ -8,22 +8,22 @@
// global data, especially between the test thread and the cachetable
// writeback threads
pthread_mutex_t test_mutex;
toku_pthread_mutex_t test_mutex;
static inline void test_mutex_init() {
int r = pthread_mutex_init(&test_mutex, 0); assert(r == 0);
int r = toku_pthread_mutex_init(&test_mutex, 0); assert(r == 0);
}
static inline void test_mutex_destroy() {
int r = pthread_mutex_destroy(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_destroy(&test_mutex); assert(r == 0);
}
static inline void test_mutex_lock() {
int r = pthread_mutex_lock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_lock(&test_mutex); assert(r == 0);
}
static inline void test_mutex_unlock() {
int r = pthread_mutex_unlock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_unlock(&test_mutex); assert(r == 0);
}
enum { KEYLIMIT = 4, TRIALLIMIT=256000 };
@ -100,7 +100,7 @@ static void test_rename (void) {
test_mutex_lock();
while (n_keys >= KEYLIMIT) {
test_mutex_unlock();
pthread_yield();
toku_pthread_yield();
test_mutex_lock();
}
assert(n_keys<KEYLIMIT);

View file

@ -53,20 +53,20 @@ test_simple_write_lock (void) {
struct rw_event {
int e;
struct ctpair_rwlock the_rwlock;
pthread_mutex_t mutex;
toku_pthread_mutex_t mutex;
};
static void
rw_event_init (struct rw_event *rwe) {
rwe->e = 0;
ctpair_rwlock_init(&rwe->the_rwlock);
int r = pthread_mutex_init(&rwe->mutex, 0); assert(r == 0);
int r = toku_pthread_mutex_init(&rwe->mutex, 0); assert(r == 0);
}
static void
rw_event_destroy (struct rw_event *rwe) {
ctpair_rwlock_destroy(&rwe->the_rwlock);
int r = pthread_mutex_destroy(&rwe->mutex); assert(r == 0);
int r = toku_pthread_mutex_destroy(&rwe->mutex); assert(r == 0);
}
static void *
@ -74,15 +74,15 @@ test_writer_priority_thread (void *arg) {
struct rw_event *rwe = arg;
int r;
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 3);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
rwe->e++; assert(rwe->e == 4);
ctpair_write_unlock(&rwe->the_rwlock);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
return arg;
}
@ -95,35 +95,35 @@ test_writer_priority (void) {
int r;
rw_event_init(rwe);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex);
sleep(1);
rwe->e++; assert(rwe->e == 1);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
pthread_t tid;
r = pthread_create(&tid, 0, test_writer_priority_thread, rwe);
toku_pthread_t tid;
r = toku_pthread_create(&tid, 0, test_writer_priority_thread, rwe);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
rwe->e++; assert(rwe->e == 2);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_unlock(&rwe->the_rwlock);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 5);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_unlock(&rwe->the_rwlock);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
void *ret;
r = pthread_join(tid, &ret); assert(r == 0);
r = toku_pthread_join(tid, &ret); assert(r == 0);
rw_event_destroy(rwe);
}
@ -135,12 +135,12 @@ test_single_writer_thread (void *arg) {
struct rw_event *rwe = arg;
int r;
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 3);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
ctpair_write_unlock(&rwe->the_rwlock);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
return arg;
}
@ -152,25 +152,25 @@ test_single_writer (void) {
rw_event_init(rwe);
assert(ctpair_writers(&rwe->the_rwlock) == 0);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
sleep(1);
rwe->e++; assert(rwe->e == 1);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
pthread_t tid;
r = pthread_create(&tid, 0, test_single_writer_thread, rwe);
toku_pthread_t tid;
r = toku_pthread_create(&tid, 0, test_single_writer_thread, rwe);
sleep(1);
r = pthread_mutex_lock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
rwe->e++; assert(rwe->e == 2);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
assert(ctpair_users(&rwe->the_rwlock) == 2);
ctpair_write_unlock(&rwe->the_rwlock);
r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
void *ret;
r = pthread_join(tid, &ret); assert(r == 0);
r = toku_pthread_join(tid, &ret); assert(r == 0);
assert(ctpair_writers(&rwe->the_rwlock) == 0);
rw_event_destroy(rwe);

View file

@ -9,22 +9,22 @@
// global data, especially between the test thread and the cachetable
// writeback threads
pthread_mutex_t test_mutex;
toku_pthread_mutex_t test_mutex;
static inline void test_mutex_init() {
int r = pthread_mutex_init(&test_mutex, 0); assert(r == 0);
int r = toku_pthread_mutex_init(&test_mutex, 0); assert(r == 0);
}
static inline void test_mutex_destroy() {
int r = pthread_mutex_destroy(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_destroy(&test_mutex); assert(r == 0);
}
static inline void test_mutex_lock() {
int r = pthread_mutex_lock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_lock(&test_mutex); assert(r == 0);
}
static inline void test_mutex_unlock() {
int r = pthread_mutex_unlock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_unlock(&test_mutex); assert(r == 0);
}
#endif
@ -198,14 +198,14 @@ static void test0 (void) {
expect1(2); /* 2 is the oldest unpinned item. */
r=toku_cachetable_put(f, make_blocknum(6), h6, make_item(6), test_object_size, flush, fetch, t3); /* 6P 5U 4P 3U 1P */
assert(r==0);
while (expect_n_flushes != 0) pthread_yield();
while (expect_n_flushes != 0) toku_pthread_yield();
assert(expect_n_flushes==0);
expect1(3);
r=toku_cachetable_put(f, make_blocknum(7), h7, make_item(7), test_object_size, flush, fetch, t3);
assert(r==0);
while (expect_n_flushes != 0) pthread_yield();
while (expect_n_flushes != 0) toku_pthread_yield();
assert(expect_n_flushes==0);
r=toku_cachetable_unpin(f, make_blocknum(7), h7, CACHETABLE_DIRTY, test_object_size); /* 7U 6P 5U 4P 1P */
assert(r==0);
@ -231,7 +231,7 @@ static void test0 (void) {
assert(did_fetch.b==2); /* Expect that 2 is fetched in. */
assert(((struct item *)item_v)->key.b==2);
assert(strcmp(((struct item *)item_v)->something,"something")==0);
while (expect_n_flushes != 0) pthread_yield();
while (expect_n_flushes != 0) toku_pthread_yield();
assert(expect_n_flushes==0);
}
@ -624,7 +624,7 @@ static void test_size_flush() {
int n_entries, hash_size; long size_current, size_limit;
toku_cachetable_get_state(t, &n_entries, &hash_size, &size_current, &size_limit);
while (n_entries != min2(i+1, n)) {
pthread_yield();
toku_pthread_yield();
toku_cachetable_get_state(t, &n_entries, 0, 0, 0);
}
assert(n_entries == min2(i+1, n));

View file

@ -8,22 +8,22 @@
// global data, especially between the test thread and the cachetable
// writeback threads
pthread_mutex_t test_mutex;
toku_pthread_mutex_t test_mutex;
static inline void test_mutex_init() {
int r = pthread_mutex_init(&test_mutex, 0); assert(r == 0);
int r = toku_pthread_mutex_init(&test_mutex, 0); assert(r == 0);
}
static inline void test_mutex_destroy() {
int r = pthread_mutex_destroy(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_destroy(&test_mutex); assert(r == 0);
}
static inline void test_mutex_lock() {
int r = pthread_mutex_lock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_lock(&test_mutex); assert(r == 0);
}
static inline void test_mutex_unlock() {
int r = pthread_mutex_unlock(&test_mutex); assert(r == 0);
int r = toku_pthread_mutex_unlock(&test_mutex); assert(r == 0);
}
static const int test_object_size = 1;
@ -48,7 +48,7 @@ static void print_ints(void) {
}
static void item_becomes_present(CACHEFILE cf, CACHEKEY key) {
while (n_present >= N_PRESENT_LIMIT) pthread_yield();
while (n_present >= N_PRESENT_LIMIT) toku_pthread_yield();
test_mutex_lock();
assert(n_present<N_PRESENT_LIMIT);
present_items[n_present].cf = cf;

View file

@ -36,9 +36,9 @@ static void
test_simple_enq_deq (int n) {
struct writequeue writequeue, *wq = &writequeue;
int r;
pthread_mutex_t mutex;
toku_pthread_mutex_t mutex;
r = pthread_mutex_init(&mutex, 0); assert(r == 0);
r = toku_pthread_mutex_init(&mutex, 0); assert(r == 0);
writequeue_init(wq);
assert(writequeue_empty(wq));
PAIR pairs[n];
@ -56,7 +56,7 @@ test_simple_enq_deq (int n) {
}
assert(writequeue_empty(wq));
writequeue_destroy(wq);
r = pthread_mutex_destroy(&mutex); assert(r == 0);
r = toku_pthread_mutex_destroy(&mutex); assert(r == 0);
}
// setting the wq closed should cause deq to return EINVAL
@ -75,19 +75,19 @@ test_set_closed (void) {
struct writequeue_with_mutex {
struct writequeue writequeue;
pthread_mutex_t mutex;
toku_pthread_mutex_t mutex;
};
static void
writequeue_with_mutex_init (struct writequeue_with_mutex *wqm) {
writequeue_init(&wqm->writequeue);
int r = pthread_mutex_init(&wqm->mutex, 0); assert(r == 0);
int r = toku_pthread_mutex_init(&wqm->mutex, 0); assert(r == 0);
}
static void
writequeue_with_mutex_destroy (struct writequeue_with_mutex *wqm) {
writequeue_destroy(&wqm->writequeue);
int r = pthread_mutex_destroy(&wqm->mutex); assert(r == 0);
int r = toku_pthread_mutex_destroy(&wqm->mutex); assert(r == 0);
}
static void *
@ -95,11 +95,11 @@ test_set_closed_waiter(void *arg) {
struct writequeue_with_mutex *wqm = arg;
int r;
r = pthread_mutex_lock(&wqm->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&wqm->mutex); assert(r == 0);
PAIR p;
r = writequeue_deq(&wqm->writequeue, &wqm->mutex, &p);
assert(r == EINVAL);
r = pthread_mutex_unlock(&wqm->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&wqm->mutex); assert(r == 0);
return arg;
}
@ -109,12 +109,12 @@ test_set_closed_thread (void) {
int r;
writequeue_with_mutex_init(wqm);
pthread_t tid;
r = pthread_create(&tid, 0, test_set_closed_waiter, wqm); assert(r == 0);
toku_pthread_t tid;
r = toku_pthread_create(&tid, 0, test_set_closed_waiter, wqm); assert(r == 0);
sleep(1);
writequeue_set_closed(&wqm->writequeue);
void *ret;
r = pthread_join(tid, &ret);
r = toku_pthread_join(tid, &ret);
assert(r == 0 && ret == wqm);
writequeue_with_mutex_destroy(wqm);
}
@ -126,14 +126,14 @@ test_set_closed_thread (void) {
// writers when the wq size <= 1/2 of the wq limit
struct rwfc {
pthread_mutex_t mutex;
toku_pthread_mutex_t mutex;
struct writequeue writequeue;
int current, limit;
};
static void rwfc_init (struct rwfc *rwfc, int limit) {
int r;
r = pthread_mutex_init(&rwfc->mutex, 0); assert(r == 0);
r = toku_pthread_mutex_init(&rwfc->mutex, 0); assert(r == 0);
writequeue_init(&rwfc->writequeue);
rwfc->current = 0; rwfc->limit = limit;
}
@ -142,7 +142,7 @@ static void
rwfc_destroy (struct rwfc *rwfc) {
int r;
writequeue_destroy(&rwfc->writequeue);
r = pthread_mutex_destroy(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_destroy(&rwfc->mutex); assert(r == 0);
}
static void *
@ -151,16 +151,16 @@ rwfc_reader (void *arg) {
int r;
while (1) {
PAIR ctpair;
r = pthread_mutex_lock(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwfc->mutex); assert(r == 0);
r = writequeue_deq(&rwfc->writequeue, &rwfc->mutex, &ctpair);
if (r == EINVAL) {
r = pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
break;
}
if (2*rwfc->current-- > rwfc->limit && 2*rwfc->current <= rwfc->limit) {
writequeue_wakeup_write(&rwfc->writequeue);
}
r = pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
destroy_pair(ctpair);
usleep(random() % 100);
}
@ -172,25 +172,25 @@ test_flow_control (int limit, int n) {
struct rwfc my_rwfc, *rwfc = &my_rwfc;
int r;
rwfc_init(rwfc, limit);
pthread_t tid;
r = pthread_create(&tid, 0, rwfc_reader, rwfc); assert(r == 0);
toku_pthread_t tid;
r = toku_pthread_create(&tid, 0, rwfc_reader, rwfc); assert(r == 0);
sleep(1); // this is here to block the reader on the first deq
int i;
for (i=0; i<n; i++) {
PAIR ctpair = new_pair();
r = pthread_mutex_lock(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&rwfc->mutex); assert(r == 0);
writequeue_enq(&rwfc->writequeue, ctpair);
rwfc->current++;
while (rwfc->current >= rwfc->limit) {
// printf("%d - %d %d\n", i, rwfc->current, rwfc->limit);
writequeue_wait_write(&rwfc->writequeue, &rwfc->mutex);
}
r = pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
r = toku_pthread_mutex_unlock(&rwfc->mutex); assert(r == 0);
// usleep(random() % 1);
}
writequeue_set_closed(&rwfc->writequeue);
void *ret;
r = pthread_join(tid, &ret); assert(r == 0);
r = toku_pthread_join(tid, &ret); assert(r == 0);
rwfc_destroy(rwfc);
}

View file

@ -5,15 +5,15 @@
#include <string.h>
#include <errno.h>
#include <malloc.h>
#include <pthread.h>
#include <toku_pthread.h>
#include "threadpool.h"
int verbose = 0;
struct my_threadpool {
THREADPOOL threadpool;
pthread_mutex_t mutex;
pthread_cond_t wait;
toku_pthread_mutex_t mutex;
toku_pthread_cond_t wait;
int closed;
};
@ -22,23 +22,23 @@ my_threadpool_init (struct my_threadpool *my_threadpool, int max_threads) {
int r;
r = threadpool_create(&my_threadpool->threadpool, max_threads); assert(r == 0);
assert(my_threadpool != 0);
r = pthread_mutex_init(&my_threadpool->mutex, 0); assert(r == 0);
r = pthread_cond_init(&my_threadpool->wait, 0); assert(r == 0);
r = toku_pthread_mutex_init(&my_threadpool->mutex, 0); assert(r == 0);
r = toku_pthread_cond_init(&my_threadpool->wait, 0); assert(r == 0);
my_threadpool->closed = 0;
}
static void
my_threadpool_destroy (struct my_threadpool *my_threadpool) {
int r;
r = pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
my_threadpool->closed = 1;
r = pthread_cond_broadcast(&my_threadpool->wait); assert(r == 0);
r = pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
r = toku_pthread_cond_broadcast(&my_threadpool->wait); assert(r == 0);
r = toku_pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
if (verbose) printf("current %d\n", threadpool_get_current_threads(my_threadpool->threadpool));
threadpool_destroy(&my_threadpool->threadpool); assert(my_threadpool->threadpool == 0);
r = pthread_mutex_destroy(&my_threadpool->mutex); assert(r == 0);
r = pthread_cond_destroy(&my_threadpool->wait); assert(r == 0);
r = toku_pthread_mutex_destroy(&my_threadpool->mutex); assert(r == 0);
r = toku_pthread_cond_destroy(&my_threadpool->wait); assert(r == 0);
}
static void *
@ -46,12 +46,12 @@ fbusy (void *arg) {
struct my_threadpool *my_threadpool = arg;
int r;
r = pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
while (!my_threadpool->closed) {
r = pthread_cond_wait(&my_threadpool->wait, &my_threadpool->mutex); assert(r == 0);
r = toku_pthread_cond_wait(&my_threadpool->wait, &my_threadpool->mutex); assert(r == 0);
}
r = pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
if (verbose) printf("%lu:%s:exit\n", pthread_self(), __FUNCTION__);
r = toku_pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
if (verbose) printf("%lu:%s:exit\n", toku_pthread_self(), __FUNCTION__);
return arg;
}
@ -60,13 +60,13 @@ fidle (void *arg) {
struct my_threadpool *my_threadpool = arg;
int r;
r = pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
r = toku_pthread_mutex_lock(&my_threadpool->mutex); assert(r == 0);
threadpool_set_thread_idle(my_threadpool->threadpool);
while (!my_threadpool->closed) {
r = pthread_cond_wait(&my_threadpool->wait, &my_threadpool->mutex); assert(r == 0);
r = toku_pthread_cond_wait(&my_threadpool->wait, &my_threadpool->mutex); assert(r == 0);
}
r = pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
if (verbose) printf("%lu:%s:exit\n", pthread_self(), __FUNCTION__);
r = toku_pthread_mutex_unlock(&my_threadpool->mutex); assert(r == 0);
if (verbose) printf("%lu:%s:exit\n", toku_pthread_self(), __FUNCTION__);
return arg;
}

View file

@ -7,11 +7,11 @@ struct threadpool {
int max_threads;
int current_threads;
int busy_threads;
pthread_t pids[];
toku_pthread_t pids[];
};
int threadpool_create(THREADPOOL *threadpoolptr, int max_threads) {
size_t size = sizeof (struct threadpool) + max_threads*sizeof (pthread_t);
size_t size = sizeof (struct threadpool) + max_threads*sizeof (toku_pthread_t);
struct threadpool *threadpool = malloc(size);
if (threadpool == 0)
return ENOMEM;
@ -30,7 +30,7 @@ void threadpool_destroy(THREADPOOL *threadpoolptr) {
int i;
for (i=0; i<threadpool->current_threads; i++) {
int r; void *ret;
r = pthread_join(threadpool->pids[i], &ret);
r = toku_pthread_join(threadpool->pids[i], &ret);
assert(r == 0);
}
*threadpoolptr = 0;
@ -39,7 +39,7 @@ void threadpool_destroy(THREADPOOL *threadpoolptr) {
void threadpool_maybe_add(THREADPOOL threadpool, void *(*f)(void *), void *arg) {
if ((threadpool->current_threads == 0 || threadpool->busy_threads < threadpool->current_threads) && threadpool->current_threads < threadpool->max_threads) {
int r = pthread_create(&threadpool->pids[threadpool->current_threads], 0, f, arg);
int r = toku_pthread_create(&threadpool->pids[threadpool->current_threads], 0, f, arg);
if (r == 0) {
threadpool->current_threads++;
threadpool_set_thread_busy(threadpool);

24
windows/Makefile Normal file
View file

@ -0,0 +1,24 @@
# -*- Mode: Makefile -*-
.DEFAULT_GOAL=install
TOKUROOT=../
INCLUDEDIRS=-I.
SKIP_LIBPORTABILITYRULE=1
include $(TOKUROOT)include/Makefile.include
OPT_AROPT=-qnoipo #Disable ipo for lib creation even when optimization is on.
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.$(OEXT),$(SRCS))
TARGET = tokuwindows.$(AEXT)
install: $(LIBPORTABILITY)
$(LIBPORTABILITY): $(TARGET)
$(MAYBEATSIGN)cp $< $@
$(TARGET): $(OBJS)
clean:
$(MAYBEATSIGN)rm -rf $(TARGET) $(LIBPORTABILITY)

18
windows/dirent.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef _TOKU_DIRENT_H
#define _TOKU_DIRENT_H
//The DIR functions do not exist in windows, but the Linux API ends up
//just using a wrapper. We might convert these into an os_* type api.
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir);
int closedir(DIR *dir);
#ifndef NAME_MAX
#define NAME_MAX 255
#endif
#endif

13
windows/inttypes.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
//Define printf types.
#define PRId64 "I64d"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRId32 "d"
#define PRIu32 "u"
#endif

72
windows/misc.h Normal file
View file

@ -0,0 +1,72 @@
#ifndef _MISC_H
#define _MISC_H
#include "os.h"
#include <sys/stat.h>
//These are functions that really exist in windows but are named
//something else.
//TODO: Sort these into some .h file that makes sense.
int fsync(int fildes);
int gettimeofday(struct timeval *tv, struct timezone *tz);
long long int strtoll(const char *nptr, char **endptr, int base);
//TODO: Enforce use of these macros. Otherwise, open, creat, and chmod may fail
//os_mkdir actually ignores the permissions, so it won't fail.
//Permissions
//User permissions translate to global
//Execute bit does not exist
//TODO: Determine if we need to use BINARY mode for opening.
#define S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
//Execute bit does not exist
#define S_IXUSR (0)
//Group permissions thrown away.
#define S_IRWXG S_IRGRP | S_IWGRP | S_IXGRP
#define S_IRGRP (0)
#define S_IWGRP (0)
#define S_IXGRP (0)
//Other permissions thrown away. (Except for read)
//MySQL defines S_IROTH as S_IREAD. Avoid the warning.
#if defined(S_IROTH)
#undef S_IROTH
#endif
#define S_IRWXO S_IROTH | S_IWOTH | S_IXOTH
#define S_IROTH S_IREAD
#define S_IWOTH (0)
#define S_IXOTH (0)
long int random(void);
void srandom(unsigned int seed);
//snprintf
//TODO: Put in its own file, or define a snprintf function based on _vsnprintf
//in its own file
#define snprintf(str, size, fmt, ...) _snprintf(str, size, fmt, __VA_ARGS__)
//strtoll has a different name in windows.
#define strtoll _strtoi64
#define strtoull _strtoui64
//rmdir has a different name in windows.
#define rmdir _rmdir
#ifndef PATH_MAX
#define PATH_MAX 1
#endif
char *realpath(const char *path, char *resolved_path);
int unsetenv(const char *name);
int setenv(const char *name, const char *value, int overwrite);
#endif

32
windows/os-types.h Normal file
View file

@ -0,0 +1,32 @@
#if !defined(OS_INTERFACE_WINDOWS_H)
#define OS_INTERFACE_WINDOWS_H
#include <stdlib.h>
#include <direct.h>
// define an OS handle
typedef void *os_handle_t;
typedef int pid_t;
typedef int mode_t;
struct fileid {
uint32_t st_dev;
uint64_t st_ino;
uint64_t st_creat;
};
enum {
DT_UNKNOWN = 0,
DT_DIR = 4,
DT_REG = 8
};
struct dirent {
char d_name[_MAX_PATH];
unsigned char d_type;
};
struct __toku_windir;
typedef struct __toku_windir DIR;
#endif

54
windows/rss.c Normal file
View file

@ -0,0 +1,54 @@
#include <windows.h>
#include <stdint.h>
#include <inttypes.h>
#include <os.h>
#define DO_MEMORY_INFO 1
#if DO_MEMORY_INFO
#include <psapi.h>
static int
get_memory_info(PROCESS_MEMORY_COUNTERS *meminfo) {
int r;
r = GetProcessMemoryInfo(GetCurrentProcess(), meminfo, sizeof *meminfo);
if (r == 0)
return GetLastError();
return 0;
}
#endif
int
os_get_rss(int64_t *rss) {
int r;
#if DO_MEMORY_INFO
PROCESS_MEMORY_COUNTERS meminfo;
r = get_memory_info(&meminfo);
if (r == 0)
*rss = meminfo.WorkingSetSize;
#else
r = 0;
*rss = 0;
#endif
return r;
}
int
os_get_max_rss(int64_t *maxrss) {
int r;
#if DO_MEMORY_INFO
PROCESS_MEMORY_COUNTERS meminfo;
r = get_memory_info(&meminfo);
if (r == 0)
*maxrss = meminfo.PeakWorkingSetSize;
#else
r = 0;
*maxrss = 0;
#endif
return r;
}

37
windows/stdint.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef _STDINT_H
#define _STDINT_H
#include <basetsd.h>
#include <sys/types.h>
//Define standard integer types.
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int8 u_int8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int16 u_int16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int32 u_int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int64 u_int64_t;
typedef SSIZE_T ssize_t;
//Limits
#define INT8_MIN _I8_MIN
#define INT8_MAX _I8_MAX
#define UINT8_MAX _UI8_MAX
#define INT16_MIN _I16_MIN
#define INT16_MAX _I16_MAX
#define UINT16_MAX _UI16_MAX
#define INT32_MIN _I32_MIN
#define INT32_MAX _I32_MAX
#define UINT32_MAX _UI32_MAX
#define INT64_MIN _I64_MIN
#define INT64_MAX _I64_MAX
#define UINT64_MAX _UI64_MAX
#endif

17
windows/tests/Makefile Normal file
View file

@ -0,0 +1,17 @@
# -*- Mode: Makefile -*-
.DEFAULT_GOAL=all
TOKUROOT=../../
INCLUDEDIRS=-I$(TOKUROOT)include/windows -I$(TOKUROOT)newbrt
include $(TOKUROOT)include/Makefile.include
SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes.
SRCS = $(wildcard test-*.c)
BINS_RAW = $(patsubst %.c,%,$(SRCS))
#Bins will be generated.
$(BINS): $(LIBPORTABILITY)
$(BINS): CFLAGS+=-DTESTDIR=\"dir.$<.dir\"
all: $(BINS)

81
windows/tests/test-dirs.c Normal file
View file

@ -0,0 +1,81 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
#include "os.h"
#include <dirent.h>
int verbose;
static int walk(const char *dirname) {
DIR *d;
struct dirent *dirent;
int dotfound = 0, dotdotfound = 0, otherfound = 0;
d = opendir(dirname);
if (d == NULL)
return -1;
while ((dirent = readdir(d))) {
if (verbose)
printf("%p %s\n", dirent, dirent->d_name);
if (strcmp(dirent->d_name, ".") == 0)
dotfound++;
else if (strcmp(dirent->d_name, "..") == 0)
dotdotfound++;
else
otherfound++;
}
closedir(d);
assert(dotfound == 1 && dotdotfound == 1);
return otherfound;
}
int main(int argc, char *argv[]) {
int i;
int found;
int fd;
int r;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
}
system("rm -rf " TESTDIR);
// try to walk a directory that does not exist
found = walk(TESTDIR);
assert(found == -1);
// try to walk an empty directory
r = os_mkdir(TESTDIR, 0777); assert(r==0);
found = walk(TESTDIR);
assert(found == 0);
//Try to delete the empty directory
system("rm -rf " TESTDIR);
r = os_mkdir(TESTDIR, 0777); assert(r==0);
// walk a directory with a bunch of files in it
#define N 100
for (i=0; i<N; i++) {
char fname[256];
sprintf(fname, TESTDIR "/%d", i);
if (verbose)
printf("%s\n", fname);
// fd = creat(fname, 0777);
fd = open(fname, O_CREAT+O_RDWR, 0777);
assert(fd >= 0);
close(fd);
}
found = walk(TESTDIR);
assert(found == N);
// walk and remove files
return 0;
}

View file

View file

@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
#include "os.h"
int verbose=0;
//TODO: Test that different files are different,
// other stuff
static void test_handles(const char *fname) {
unlink(fname);
int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
assert(fd!=-1);
int i;
struct fileid id_base;
struct fileid id;
int r = os_get_unique_file_id(fd, &id_base);
assert(r==0);
for (i=0; i < 1<<16; i++) {
r = os_get_unique_file_id(fd, &id);
assert(r==0);
assert(memcmp(&id, &id_base, sizeof(id))==0);
}
r = close(fd);
assert(r==0);
}
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
}
test_handles("junk");
return 0;
}

View file

@ -0,0 +1,60 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#if 0 && defined _WIN32
#include <windows.h>
static int ftruncate(int fd, uint64_t offset) {
HANDLE h = (HANDLE) _get_osfhandle(fd);
printf("%s:%d %p\n", __FILE__, __LINE__, h); fflush(stdout);
if (h == INVALID_HANDLE_VALUE)
return -1;
int r = _lseeki64(fd, 0, SEEK_SET);
printf("%s:%d %d\n", __FILE__, __LINE__, r); fflush(stdout);
if (r != 0)
return -2;
BOOL b = SetEndOfFile(h);
printf("%s:%d %d\n", __FILE__, __LINE__, b); fflush(stdout);
if (!b)
return -3;
return 0;
}
#endif
int main(void) {
int r;
int fd;
fd = open("test-file-truncate", O_CREAT+O_RDWR+O_TRUNC, S_IREAD+S_IWRITE);
assert(fd != -1);
int i;
for (i=0; i<32; i++) {
char junk[4096];
memset(junk, 0, sizeof junk);
r = write(fd, junk, sizeof junk);
assert(r == sizeof junk);
}
struct stat filestat;
r = fstat(fd, &filestat);
assert(r == 0);
printf("orig size %lu\n", (unsigned long) filestat.st_size); fflush(stdout);
r = ftruncate(fd, 0);
assert(r == 0);
r = fstat(fd, &filestat);
assert(r == 0);
printf("truncated size %lu\n", (unsigned long) filestat.st_size); fflush(stdout);
assert(filestat.st_size == 0);
return 0;
}

View file

@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
int fd = open(argv[i], O_RDONLY);
printf("%s: %d %d\n", argv[i], fd, errno);
if (fd >= 0) close(fd);
}
return 0;
}

View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <sys/stat.h>
#ifndef S_IRUSR
#define S_IRUSR S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR S_IWRITE
#endif
#define TESTFILE "test-open-unlink-file"
#define NEWNAME TESTFILE ".junk"
int main(void) {
int r;
int fd;
system("rm -rf test-open-unlink-file");
fd = open(TESTFILE, O_CREAT+O_RDWR, S_IRUSR+S_IWUSR);
assert(fd != -1);
r = rename(TESTFILE, NEWNAME);
printf("%s:%d rename %d %d\n", __FILE__, __LINE__, r, errno); fflush(stdout);
#if defined(__linux__)
assert(r == 0);
r = close(fd);
assert(r == 0);
#endif
#if defined(_WIN32)
assert(r == -1);
r = close(fd);
assert(r == 0);
r = rename(TESTFILE, NEWNAME);
printf("%s:%d rename %d %d\n", __FILE__, __LINE__, r, errno); fflush(stdout);
assert(r == 0);
#endif
return 0;
}

View file

@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <sys/stat.h>
#ifndef S_IRUSR
#define S_IRUSR S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR S_IWRITE
#endif
const char TESTFILE[] = "test-open-unlink-file";
int main(void) {
int r;
int fd;
system("rm -rf test-open-unlink-file");
fd = open(TESTFILE, O_CREAT+O_RDWR, S_IRUSR+S_IWUSR);
assert(fd != -1);
r = unlink(TESTFILE);
printf("%s:%d unlink %d %d\n", __FILE__, __LINE__, r, errno); fflush(stdout);
#if defined(__linux__)
assert(r == 0);
r = close(fd);
assert(r == 0);
#endif
#if defined(_WIN32)
assert(r == -1);
r = close(fd);
assert(r == 0);
r = unlink(TESTFILE);
printf("%s:%d unlink %d %d\n", __FILE__, __LINE__, r, errno); fflush(stdout);
assert(r == 0);
#endif
return 0;
}

View file

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
#include "os.h"
int verbose;
static void test_pread_empty(const char *fname) {
int fd;
char c[12];
uint64_t r;
unlink(fname);
fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
if (verbose)
printf("open %s fd %d\n", fname, fd);
assert(fd != -1);
r = pread(fd, c, sizeof c, 0);
assert(r == 0);
r = close(fd);
if (verbose)
printf("close %s %"PRIu64"\n", fname, r);
}
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
}
test_pread_empty("junk");
return 0;
}

View file

@ -0,0 +1,85 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <windows.h>
#include "toku_pthread.h"
struct q {
toku_pthread_mutex_t m;
toku_pthread_cond_t r;
toku_pthread_cond_t w;
void *item;
};
static void q_init(struct q *q) {
toku_pthread_mutex_init(&q->m, NULL);
toku_pthread_cond_init(&q->r, NULL);
toku_pthread_cond_init(&q->w, NULL);
q->item = NULL;
}
static void q_destroy(struct q *q) {
toku_pthread_cond_destroy(&q->w);
toku_pthread_cond_destroy(&q->r);
toku_pthread_mutex_destroy(&q->m);
}
static void *q_get(struct q *q) {
void *item;
toku_pthread_mutex_lock(&q->m);
while (q->item == NULL)
toku_pthread_cond_wait(&q->r, &q->m);
item = q->item; q->item = NULL;
toku_pthread_mutex_unlock(&q->m);
toku_pthread_cond_signal(&q->w);
return item;
}
static void q_put(struct q *q, void *item) {
toku_pthread_mutex_lock(&q->m);
while (q->item != NULL)
toku_pthread_cond_wait(&q->w, &q->m);
q->item = item;
toku_pthread_mutex_unlock(&q->m);
toku_pthread_cond_signal(&q->r);
}
static void *writer(void *arg) {
struct q *q = arg;
int i;
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
for (i=0; i<100; i++)
q_put(q, (void*)(i+1));
return arg;
}
static void *reader(void *arg) {
struct q *q = arg;
int i;
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
for (i=0; i<100; i++) {
void *item = q_get(q);
printf("%p\n", item); fflush(stdout);
Sleep(i);
}
return arg;
}
int main(void) {
int i;
void *ret;
toku_pthread_t t[2];
struct q q;
q_init(&q);
toku_pthread_create(&t[0], NULL, reader, &q);
toku_pthread_create(&t[1], NULL, writer, &q);
for (i=0; i<2; i++)
toku_pthread_join(t[i], &ret);
q_destroy(&q);
return 0;
}

View file

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <windows.h>
#include "toku_pthread.h"
static void *myfunc1(void *arg) {
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
fflush(stdout);
Sleep(10*1000);
return arg;
}
static void *myfunc2(void *arg) {
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
fflush(stdout);
Sleep(10*1000);
return arg;
}
int main(void) {
#define N 10
toku_pthread_t t[N];
int i;
for (i=0; i<N; i++) {
toku_pthread_create(&t[i], NULL, i & 1 ? myfunc1 : myfunc2, (void *)i);
}
for (i=0; i<N; i++) {
void *ret;
toku_pthread_join(t[i], &ret);
assert(ret == (void*)i);
}
return 0;
}

30
windows/tests/test-rss.c Normal file
View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <os.h>
static void do_mallocs(void) {
int i;
for (i=0; i<1000; i++) {
int nbytes = 1024*1024;
void *vp = malloc(nbytes);
memset(vp, 0, nbytes);
}
}
int main(void) {
int64_t rss;
os_get_max_rss(&rss);
printf("%I64d\n", rss);
do_mallocs();
os_get_max_rss(&rss);
printf("%I64d\n", rss);
return 0;
}

View file

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
#include "os.h"
int verbose;
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
}
for (i=0; i<10; i++) {
if (verbose) {
printf("sleep %d\n", i); fflush(stdout);
}
sleep(i);
}
for (i=0; i<10*1000000; i += 1000000) {
if (verbose) {
printf("usleep %d\n", i); fflush(stdout);
}
usleep(i);
}
return 0;
}

30
windows/tests/test-stat.c Normal file
View file

@ -0,0 +1,30 @@
#include <portability.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>
void test_stat(char *dirname) {
int r;
struct stat s;
r = stat(dirname, &s);
printf("stat %s %d\n", dirname, r);
}
int main(void) {
int r;
test_stat(".");
r = os_mkdir("testdir", S_IRWXU);
assert(r == 0);
test_stat("testdir");
test_stat("./testdir");
test_stat("./testdir/");
return 0;
}

View file

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "portability.h"
#include "os.h"
int verbose;
void testit(int64_t i, int base) {
int64_t o;
#define SN 32
char s[SN];
sprintf(s, "%I64d", i);
o = strtoll(s, NULL, base);
if (verbose)
printf("%s: %I64d %I64d %s\n", __FUNCTION__, i, o, s);
assert(i == o);
}
int main(int argc, char *argv[]) {
int i;
int64_t n;
int64_t o;
#define SN 32
char s[SN];
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
}
for (n=0; n<1000; n++) {
testit(n, 10);
}
testit(1I64 << 31, 10);
testit((1I64 << 32) - 1, 10);
testit(1I64 << 32, 10);
return 0;
}

View file

@ -0,0 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
int main(void) {
int r;
int fd;
struct fileid fid;
fd = open(DEV_NULL_FILE, O_RDWR);
assert(fd != -1);
r = os_get_unique_file_id(fd, &fid);
printf("%s:%d %d\n", __FILE__, __LINE__, r);
r = close(fd);
assert(r != -1);
return 0;
}

View file

@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include <windows.h>
#include <winsock.h>
int verbose;
int usleep(SOCKET s, unsigned int useconds) {
fd_set dummy;
struct timeval tv;
FD_ZERO(&dummy);
FD_SET(s, &dummy);
tv.tv_sec = useconds / 1000000;
tv.tv_usec = useconds % 1000000;
return select(0, 0, 0, &dummy, &tv);
}
int main(int argc, char *argv[]) {
int i;
int n = 1;
WSADATA wsadata;
SOCKET s;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
n = atoi(arg);
}
WSAStartup(MAKEWORD(1, 0), &wsadata);
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("s=%u\n", s);
for (i=0; i<1000; i++) {
if (verbose) {
printf("usleep %d\n", i); fflush(stdout);
}
usleep(s, n);
}
return 0;
}

View file

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include "portability.h"
#include "os.h"
int verbose;
int main(int argc, char *argv[]) {
int i;
int n = 1;
for (i=1; i<argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0)
verbose++;
n = atoi(arg);
}
for (i=0; i<1000; i++) {
if (verbose) {
printf("usleep %d\n", i); fflush(stdout);
}
usleep(n);
}
return 0;
}

181
windows/toku_pthread.c Normal file
View file

@ -0,0 +1,181 @@
#include <windows.h>
#include <assert.h>
#include <errno.h>
#include <toku_pthread.h>
int
toku_pthread_mutex_init(toku_pthread_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) {
assert(attr == NULL);
// assert(!mutex->initialized);
InitializeCriticalSection(&mutex->section);
mutex->initialized = TRUE;
return 0;
}
int
toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex) {
assert(mutex->initialized);
DeleteCriticalSection(&mutex->section);
mutex->initialized = FALSE;
return 0;
}
int
toku_pthread_mutex_lock(toku_pthread_mutex_t *mutex) {
if (!mutex->initialized) {
int r = toku_pthread_mutex_init(mutex, NULL);
assert(r==0);
}
assert(mutex->initialized);
EnterCriticalSection(&mutex->section);
return 0;
}
#if 0
int
toku_pthread_mutex_trylock(toku_pthread_mutex_t *mutex) {
int r = 0;
if (!TryEnterCriticalSection(&mutex->section))
r = EBUSY;
return r;
}
#endif
int
toku_pthread_mutex_unlock(toku_pthread_mutex_t *mutex) {
assert(mutex->initialized);
LeaveCriticalSection(&mutex->section);
return 0;
}
int
toku_pthread_attr_init(toku_pthread_attr_t *attr) {
attr->stacksize = 0;
return 0;
}
int
toku_pthread_attr_destroy(toku_pthread_attr_t *attr) {
attr = attr;
return 0;
}
int
toku_pthread_attr_setstacksize(toku_pthread_attr_t *attr, size_t stacksize) {
attr->stacksize = stacksize;
return 0;
}
int
toku_pthread_attr_getstacksize(toku_pthread_attr_t *attr, size_t *stacksize) {
*stacksize = attr->stacksize;
return 0;
}
static DWORD WINAPI
toku_pthread_start(LPVOID a) {
toku_pthread_t thread = (toku_pthread_t) a;
thread->ret = thread->f(thread->arg);
return 0;
}
int
toku_pthread_create(toku_pthread_t *threadptr, const toku_pthread_attr_t *attr, void *(*f)(void *), void *arg) {
size_t stacksize = 0;
toku_pthread_t thread = malloc(sizeof (struct toku_pthread));
if (thread == 0)
return ENOMEM;
if (attr)
stacksize = attr->stacksize;
thread->f = f;
thread->arg = arg;
// _beginthread or CreateThread
thread->handle = CreateThread(NULL, stacksize, toku_pthread_start, thread, 0, &thread->id);
*threadptr = thread;
return 0;
}
int
toku_pthread_join(toku_pthread_t thread, void **ret) {
WaitForSingleObject(thread->handle, INFINITE);
if (ret)
*ret = thread->ret;
free(thread);
return 0;
}
toku_pthread_t
toku_pthread_self(void) {
// lookup a pthread by thread id and return it
return 0;
}
#if 0
void
toku_pthread_exit(void *ret) {
toku_pthread_t self = toku_pthread_self();
thread->ret = ret;
// _endthread or ExitThread
ExitThread(0);
}
#endif
int
toku_pthread_cond_init(toku_pthread_cond_t *cond, const toku_pthread_condattr_t *attr) {
int r;
assert(attr == 0);
cond->events[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (cond->events[0] == NULL)
return GetLastError();
cond->events[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (cond->events[1] == NULL) {
r = GetLastError();
CloseHandle(cond->events[0]);
return r;
}
cond->waiters = 0;
return 0;
}
int
toku_pthread_cond_destroy(toku_pthread_cond_t *cond) {
int i;
for (i=0; i<TOKU_PTHREAD_COND_NEVENTS; i++)
CloseHandle(cond->events[i]);
return 0;
}
int
toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex) {
DWORD r;
cond->waiters++;
toku_pthread_mutex_unlock(mutex);
r = WaitForMultipleObjects(TOKU_PTHREAD_COND_NEVENTS, cond->events, FALSE, INFINITE);
toku_pthread_mutex_lock(mutex);
cond->waiters--;
if (cond->waiters == 0 && r == WAIT_OBJECT_0 + 1)
ResetEvent(cond->events[1]);
return 0;
}
int
toku_pthread_cond_broadcast(toku_pthread_cond_t *cond) {
if (cond->waiters > 0)
SetEvent(cond->events[1]);
return 0;
}
int
toku_pthread_cond_signal(toku_pthread_cond_t *cond) {
if (cond->waiters > 0)
SetEvent(cond->events[0]);
return 0;
}
int
toku_pthread_yield(void) {
Sleep(0);
return 0;
}

87
windows/toku_pthread.h Normal file
View file

@ -0,0 +1,87 @@
#ifndef _TOKU_PTHREAD_H
#define _TOKU_PTHREAD_H
#if defined __cplusplus
extern "C" {
#endif
// pthread types
typedef struct toku_pthread_attr {
SIZE_T stacksize;
} toku_pthread_attr_t;
typedef struct toku_pthread {
HANDLE handle;
DWORD id;
void *(*f)(void *);
void *arg;
void *ret;
} *toku_pthread_t;
typedef struct toku_pthread_mutexattr *toku_pthread_mutexattr_t;
typedef struct toku_pthread_mutex {
CRITICAL_SECTION section;
BOOL initialized;
} toku_pthread_mutex_t;
#define TOKU_PTHREAD_MUTEX_INITIALIZER { 0, 0 }
typedef struct toku_pthread_condattr *toku_pthread_condattr_t;
// WINNT >= 6 supports condition variables. For now, we use a couple of events.
#define TOKU_PTHREAD_COND_NEVENTS 2
typedef struct toku_pthread_cond {
#if 0
CONDITION_VARIABLE wcv;
#else
HANDLE events[TOKU_PTHREAD_COND_NEVENTS];
int waiters;
#endif
} toku_pthread_cond_t;
// pthread interface
int toku_pthread_yield(void);
int toku_pthread_attr_init(toku_pthread_attr_t *);
int toku_pthread_attr_destroy(toku_pthread_attr_t *);
int toku_pthread_attr_getstacksize(toku_pthread_attr_t *, size_t *stacksize);
int toku_pthread_attr_setstacksize(toku_pthread_attr_t *, size_t stacksize);
int toku_pthread_create(toku_pthread_t *thread, const toku_pthread_attr_t *attr, void *(*start_function)(void *), void *arg);
int toku_pthread_join(toku_pthread_t thread, void **value_ptr);
toku_pthread_t toku_pthread_self(void);
int toku_pthread_mutex_init(toku_pthread_mutex_t *mutex, const toku_pthread_mutexattr_t *attr);
int toku_pthread_mutex_destroy(toku_pthread_mutex_t *mutex);
int toku_pthread_mutex_lock(toku_pthread_mutex_t *mutex);
int toku_pthread_mutex_trylock(toku_pthread_mutex_t *mutex);
int toku_pthread_mutex_unlock(toku_pthread_mutex_t *mutex);
int toku_pthread_cond_init(toku_pthread_cond_t *cond, const toku_pthread_condattr_t *attr);
int toku_pthread_cond_destroy(toku_pthread_cond_t *cond);
int toku_pthread_cond_wait(toku_pthread_cond_t *cond, toku_pthread_mutex_t *mutex);
int toku_pthread_cond_signal(toku_pthread_cond_t *cond);
int toku_pthread_cond_broadcast(toku_pthread_cond_t *cond);
#if defined __cplusplus
};
#endif
#endif

22
windows/unistd.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef _TOKUWIN_UNISTD_H
#define _TOKUWIN_UNISTD_H
#include <io.h>
#include <stdio.h>
int
ftruncate(int fildes, int64_t offset);
int64_t
pwrite(int fildes, const void *buf, size_t nbyte, int64_t offset);
int64_t
pread(int fildes, void *buf, size_t nbyte, int64_t offset);
unsigned int
sleep(unsigned int);
int
usleep(unsigned int);
#endif

420
windows/windows.c Normal file
View file

@ -0,0 +1,420 @@
#define _CRT_SECURE_NO_DEPRECATE
//rand_s requires _CRT_RAND_S be defined before including stdlib
#define _CRT_RAND_S
#include <stdlib.h>
#include <windows.h>
#include "portability.h"
#include <dirent.h>
#include <assert.h>
#include <direct.h>
#include <errno.h>
#include <io.h>
#include <malloc.h>
#include <process.h>
#include <share.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <Crtdbg.h>
struct __toku_windir {
struct dirent ent;
struct _finddatai64_t data;
intptr_t handle;
BOOL finished;
};
DIR*
opendir(const char *name) {
char *format = NULL;
DIR *result = malloc(sizeof(*result));
int r;
if (!result) {
r = ENOMEM;
goto cleanup;
}
format = malloc(strlen(name)+2+1); //2 for /*, 1 for '\0'
if (!format) {
r = ENOMEM;
goto cleanup;
}
strcpy(format, name);
if (format[strlen(format)-1]=='/') format[strlen(format)-1]='\0';
strcat(format, "/*");
result->handle = _findfirsti64(format, &result->data);
// printf("%s:%d %p %d\n", __FILE__, __LINE__, result->handle, errno); fflush(stdout);
if (result->handle==-1L) {
if (errno==ENOENT) {
int64_t r_stat;
//ENOENT can mean a good directory with no files, OR
//a directory that does not exist.
struct _stat64 buffer;
format[strlen(format)-3] = '\0'; //Strip the "/*"
r_stat = _stati64(format, &buffer);
if (r_stat==0) {
//Empty directory.
result->finished = TRUE;
r = 0;
goto cleanup;
}
}
r = errno;
assert(r!=0);
goto cleanup;
}
result->finished = FALSE;
r = 0;
cleanup:
if (r!=0) {
if (result) free(result);
result = NULL;
}
if (format) free(format);
return result;
}
struct dirent*
readdir(DIR *dir) {
struct dirent *result;
int r;
if (dir->finished) {
errno = ENOENT;
result = NULL;
goto cleanup;
}
assert(dir->handle!=-1L);
strcpy(dir->ent.d_name, dir->data.name);
if (dir->data.attrib&_A_SUBDIR) dir->ent.d_type=DT_DIR;
else dir->ent.d_type=DT_REG;
r = _findnexti64(dir->handle, &dir->data);
if (r==-1L) dir->finished = TRUE;
result = &dir->ent;
cleanup:
return result;
}
int
closedir(DIR *dir) {
int r;
if (dir->handle==-1L) r = 0;
else r = _findclose(dir->handle);
free(dir);
return r;
}
int
fsync(int fildes) {
int r = _commit(fildes);
return r;
}
int
os_get_file_size(int fildes, int64_t *size) {
struct _stat64 sbuf;
int r = _fstati64(fildes, &sbuf);
if (r==0) {
*size = sbuf.st_size;
}
return r;
}
uint64_t
os_get_phys_memory_size(void) {
MEMORYSTATUS memory_status;
GlobalMemoryStatus(&memory_status);
return memory_status.dwTotalPhys;
}
int
os_get_number_processors(void) {
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwNumberOfProcessors;
}
int
os_get_number_active_processors(void) {
SYSTEM_INFO system_info;
DWORD mask, n;
GetSystemInfo(&system_info);
mask = system_info.dwActiveProcessorMask;
for (n=0; mask; mask >>= 1)
n += mask & 1;
return n;
}
int
os_get_pagesize(void) {
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwPageSize;
}
int
os_get_unique_file_id(int fildes, struct fileid *id) {
int r;
BY_HANDLE_FILE_INFORMATION info;
HANDLE filehandle;
memset(id, 0, sizeof(*id));
filehandle = (HANDLE)_get_osfhandle(fildes);
if (filehandle==INVALID_HANDLE_VALUE) {
r = errno; assert(r!=0);
goto cleanup;
}
r = GetFileInformationByHandle(filehandle, &info);
if (r==0) { //0 is error here.
r = GetLastError(); assert(r!=0);
goto cleanup;
}
id->st_dev = info.dwVolumeSerialNumber;
id->st_ino = info.nFileIndexHigh;
id->st_ino <<= 32;
id->st_ino |= info.nFileIndexLow;
id->st_creat = info.ftCreationTime.dwHighDateTime;
id->st_creat <<= 32;
id->st_creat |= info.ftCreationTime.dwLowDateTime;
r = 0;
cleanup:
return r;
}
static void
convert_filetime_timeval(FILETIME ft, struct timeval *tv) {
ULARGE_INTEGER t;
t.u.HighPart = ft.dwHighDateTime;
t.u.LowPart = ft.dwLowDateTime;
t.QuadPart /= 10;
if (tv) {
tv->tv_sec = t.QuadPart / 1000000;
tv->tv_usec = t.QuadPart % 1000000;
}
}
int
os_get_process_times(struct timeval *usertime, struct timeval *kerneltime) {
FILETIME w_createtime, w_exittime, w_usertime, w_kerneltime;
if (GetProcessTimes(GetCurrentProcess(), &w_createtime, &w_exittime, &w_kerneltime, &w_usertime)) {
convert_filetime_timeval(w_usertime, usertime);
convert_filetime_timeval(w_kerneltime, kerneltime);
return 0;
}
return GetLastError();
}
int
os_getpid(void) {
#if 0
return _getpid();
#else
return GetCurrentProcessId();
#endif
}
int
os_gettid(void) {
return GetCurrentThreadId();
}
int
gettimeofday(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
ULARGE_INTEGER t;
GetSystemTimeAsFileTime(&ft);
t.u.LowPart = ft.dwLowDateTime;
t.u.HighPart = ft.dwHighDateTime;
t.QuadPart -= 116444736000000000i64;
t.QuadPart /= 10;
if (tv) {
tv->tv_sec = t.QuadPart / 1000000;
tv->tv_usec = t.QuadPart % 1000000;
}
if (tz) {
assert(0);
}
return 0;
}
int
os_lock_file(char *name) {
int fd = _sopen(name, O_CREAT, _SH_DENYRW, S_IREAD|S_IWRITE);
return fd;
}
int
os_unlock_file(int fildes) {
int r = close(fildes);
return r;
}
int64_t
pread(int fildes, void *buf, size_t nbyte, int64_t offset) {
int64_t r = _lseeki64(fildes, offset, SEEK_SET);
if (r>=0) {
assert(r==offset);
r = read(fildes, buf, nbyte);
}
// printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout);
return r;
}
int64_t
pwrite(int fildes, const void *buf, size_t nbyte, int64_t offset) {
int64_t r = _lseeki64(fildes, offset, SEEK_SET);
if (r>=0) {
assert(r==offset);
r = write(fildes, buf, nbyte);
}
// printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout);
return r;
}
int
os_mkdir(const char *pathname, mode_t mode) {
int r = mkdir(pathname);
UNUSED_WARNING(mode);
if (r!=0) r = errno;
return r;
}
unsigned int
sleep(unsigned int seconds) {
unsigned int m = seconds / 1000000;
unsigned int n = seconds % 1000000;
unsigned int i;
for (i=0; i<m; i++)
Sleep(1000000*1000);
Sleep(n*1000);
return 0;
}
int
usleep(unsigned int useconds) {
unsigned int m = useconds / 1000;
unsigned int n = useconds % 1000;
if (m == 0 && n > 0)
m = 1;
Sleep(m);
return 0;
}
static void printfParameterHandler(const wchar_t* expression,
const wchar_t* function, const wchar_t* file,
unsigned int line, uintptr_t pReserved) {
fwprintf(stderr, L"Invalid parameter detected in function %s."
L" File: %s Line: %d\n"
L"Expression: %s\n", function, file, line, expression);
}
static void ignoreParameterHandler(const wchar_t* expression,
const wchar_t* function, const wchar_t* file,
unsigned int line, uintptr_t pReserved) {
UNUSED_WARNING(expression);
UNUSED_WARNING(function);
UNUSED_WARNING(file);
UNUSED_WARNING(line);
UNUSED_WARNING(pReserved);
}
int
os_initialize_settings(int verbosity) {
int r;
static int initialized = 0;
assert(initialized==0);
initialized=1;
if (verbosity>0)
_set_invalid_parameter_handler(printfParameterHandler);
else
_set_invalid_parameter_handler(ignoreParameterHandler);
#if defined(_DEBUG)
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif
r = 0;
return r;
}
long int
random(void) {
u_int32_t r;
errno_t r_error = rand_s(&r);
assert(r_error==0);
//Should return 0 to 2**31-1 instead of 2**32-1
r >>= 1;
return r;
}
//TODO: Implement srandom to modify the way rand_s works (IF POSSIBLE).. or
//reimplement random.
void
srandom(unsigned int seed) {
UNUSED_WARNING(seed);
}
int
setenv(const char *name, const char *value, int overwrite) {
char buf[2]; //Need a dummy buffer
BOOL exists = TRUE;
int r = GetEnvironmentVariable(name, buf, sizeof(buf));
if (r==0) {
r = GetLastError();
if (r==ERROR_ENVVAR_NOT_FOUND) exists = FALSE;
else {
errno = r;
r = -1;
goto cleanup;
}
}
if (overwrite || !exists) {
r = SetEnvironmentVariable(name, value);
if (r==0) {
errno = GetLastError();
r = -1;
goto cleanup;
}
}
r = 0;
cleanup:
return r;
}
int
unsetenv(const char *name) {
int r = SetEnvironmentVariable(name, NULL);
if (r==0) { //0 is failure
r = -1;
errno = GetLastError();
}
else r = 0;
return r;
}
int
ftruncate(int fd, int64_t offset) {
HANDLE h;
BOOL b;
int r;
h = (HANDLE) _get_osfhandle(fd);
if (h == INVALID_HANDLE_VALUE)
return -1;
r = _lseeki64(fd, 0, SEEK_SET);
if (r != 0)
return -2;
b = SetEndOfFile(h);
if (!b)
return -3;
return 0;
}

332
windows/zconf.h Normal file
View file

@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

1357
windows/zlib.h Normal file

File diff suppressed because it is too large Load diff