Commit bf70bbb8 authored by Leif Walsh's avatar Leif Walsh Committed by Yoni Fogel

refs #5418 merge promotion to main

git-svn-id: file:///svn/toku/tokudb@49697 c7de825b-a66e-492c-adef-691d508d4ae1
parent 609d0dca
...@@ -8,6 +8,7 @@ list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE ...@@ -8,6 +8,7 @@ list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
ft/ft_loader-test-extractor-2 ft/ft_loader-test-extractor-2
ft/ft_loader-test-extractor-3 ft/ft_loader-test-extractor-3
ft/upgrade_test_simple ft/upgrade_test_simple
portability/test-cache-line-boundary-fails
portability/try-leak-lost portability/try-leak-lost
portability/try-leak-reachable portability/try-leak-reachable
portability/try-leak-uninit portability/try-leak-uninit
......
...@@ -7,7 +7,12 @@ if(USE_BDB) ...@@ -7,7 +7,12 @@ if(USE_BDB)
find_package(BDB REQUIRED) find_package(BDB REQUIRED)
endif() endif()
find_package(Valgrind REQUIRED) option(USE_VALGRIND "Build to run safely under valgrind (often slower)." ON)
if(USE_VALGRIND)
find_package(Valgrind REQUIRED)
endif()
option(TOKU_DEBUG_PARANOID "Enable paranoid asserts." ON)
include(CheckIncludeFiles) include(CheckIncludeFiles)
......
...@@ -100,6 +100,9 @@ endif () ...@@ -100,6 +100,9 @@ endif ()
## this hits with optimized builds somewhere in ftleaf_split, we don't ## this hits with optimized builds somewhere in ftleaf_split, we don't
## know why but we don't think it's a big deal ## know why but we don't think it's a big deal
set_cflags_if_supported(
-Wno-error=strict-overflow
)
set_ldflags_if_supported( set_ldflags_if_supported(
-Wno-error=strict-overflow -Wno-error=strict-overflow
) )
...@@ -122,11 +125,6 @@ else () ...@@ -122,11 +125,6 @@ else ()
set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
endif () endif ()
option(USE_VALGRIND "Do not pass NVALGRIND to the compiler, because valgrind will be run on the generated executables." ON)
if (NOT USE_VALGRIND)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE NVALGRIND=1)
endif ()
## set warnings ## set warnings
set_cflags_if_supported( set_cflags_if_supported(
-Wextra -Wextra
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "tokudb_common_funcs.h" #include "tokudb_common_funcs.h"
#include <toku_pthread.h> #include <toku_pthread.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <portability/toku_atomic.h>
#include <db.h> #include <db.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -102,7 +103,7 @@ static void test_begin_commit(int _nqueries) { ...@@ -102,7 +103,7 @@ static void test_begin_commit(int _nqueries) {
r = c->c_get(c, &key, &val, DB_SET); r = c->c_get(c, &key, &val, DB_SET);
#endif #endif
assert_zero(r); assert_zero(r);
(void) __sync_fetch_and_add(&set_count, 1); (void) toku_sync_fetch_and_add(&set_count, 1);
r = c->c_close(c); assert_zero(r); r = c->c_close(c); assert_zero(r);
r = txn->commit(txn, 0); assert_zero(r); r = txn->commit(txn, 0); assert_zero(r);
} }
......
This diff is collapsed.
...@@ -134,6 +134,7 @@ struct ctpair { ...@@ -134,6 +134,7 @@ struct ctpair {
CACHETABLE_PARTIAL_EVICTION_CALLBACK pe_callback; CACHETABLE_PARTIAL_EVICTION_CALLBACK pe_callback;
CACHETABLE_CLEANER_CALLBACK cleaner_callback; CACHETABLE_CLEANER_CALLBACK cleaner_callback;
CACHETABLE_CLONE_CALLBACK clone_callback; CACHETABLE_CLONE_CALLBACK clone_callback;
CACHETABLE_CHECKPOINT_COMPLETE_CALLBACK checkpoint_complete_callback;
void *write_extraargs; void *write_extraargs;
// access to these fields are protected by disk_nb_mutex // access to these fields are protected by disk_nb_mutex
...@@ -384,7 +385,7 @@ class evictor { ...@@ -384,7 +385,7 @@ class evictor {
uint64_t reserve_memory(double fraction); uint64_t reserve_memory(double fraction);
void release_reserved_memory(uint64_t reserved_memory); void release_reserved_memory(uint64_t reserved_memory);
void run_eviction_thread(); void run_eviction_thread();
void do_partial_eviction(PAIR p); void do_partial_eviction(PAIR p, bool pair_mutex_held);
void evict_pair(PAIR p, bool checkpoint_pending); void evict_pair(PAIR p, bool checkpoint_pending);
void wait_for_cache_pressure_to_subside(); void wait_for_cache_pressure_to_subside();
void signal_eviction_thread(); void signal_eviction_thread();
......
This diff is collapsed.
...@@ -173,12 +173,15 @@ typedef int (*CACHETABLE_CLEANER_CALLBACK)(void *ftnode_pv, BLOCKNUM blocknum, u ...@@ -173,12 +173,15 @@ typedef int (*CACHETABLE_CLEANER_CALLBACK)(void *ftnode_pv, BLOCKNUM blocknum, u
typedef void (*CACHETABLE_CLONE_CALLBACK)(void* value_data, void** cloned_value_data, PAIR_ATTR* new_attr, bool for_checkpoint, void* write_extraargs); typedef void (*CACHETABLE_CLONE_CALLBACK)(void* value_data, void** cloned_value_data, PAIR_ATTR* new_attr, bool for_checkpoint, void* write_extraargs);
typedef void (*CACHETABLE_CHECKPOINT_COMPLETE_CALLBACK)(void *value_data);
typedef struct { typedef struct {
CACHETABLE_FLUSH_CALLBACK flush_callback; CACHETABLE_FLUSH_CALLBACK flush_callback;
CACHETABLE_PARTIAL_EVICTION_EST_CALLBACK pe_est_callback; CACHETABLE_PARTIAL_EVICTION_EST_CALLBACK pe_est_callback;
CACHETABLE_PARTIAL_EVICTION_CALLBACK pe_callback; CACHETABLE_PARTIAL_EVICTION_CALLBACK pe_callback;
CACHETABLE_CLEANER_CALLBACK cleaner_callback; CACHETABLE_CLEANER_CALLBACK cleaner_callback;
CACHETABLE_CLONE_CALLBACK clone_callback; CACHETABLE_CLONE_CALLBACK clone_callback;
CACHETABLE_CHECKPOINT_COMPLETE_CALLBACK checkpoint_complete_callback;
void* write_extraargs; // parameter for flush_callback, pe_est_callback, pe_callback, and cleaner_callback void* write_extraargs; // parameter for flush_callback, pe_est_callback, pe_callback, and cleaner_callback
} CACHETABLE_WRITE_CALLBACK; } CACHETABLE_WRITE_CALLBACK;
...@@ -366,14 +369,14 @@ int toku_cachetable_get_and_pin_nonblocking ( ...@@ -366,14 +369,14 @@ int toku_cachetable_get_and_pin_nonblocking (
UNLOCKERS unlockers UNLOCKERS unlockers
); );
int toku_cachetable_maybe_get_and_pin (CACHEFILE, CACHEKEY, uint32_t /*fullhash*/, void**); int toku_cachetable_maybe_get_and_pin (CACHEFILE, CACHEKEY, uint32_t /*fullhash*/, pair_lock_type, void**);
// Effect: Maybe get and pin a memory object. // Effect: Maybe get and pin a memory object.
// This function is similar to the get_and_pin function except that it // This function is similar to the get_and_pin function except that it
// will not attempt to fetch a memory object that is not in the cachetable or requires any kind of blocking to get it. // will not attempt to fetch a memory object that is not in the cachetable or requires any kind of blocking to get it.
// Returns: If the the item is already in memory, then return 0 and store it in the // Returns: If the the item is already in memory, then return 0 and store it in the
// void**. If the item is not in memory, then return a nonzero error number. // void**. If the item is not in memory, then return a nonzero error number.
int toku_cachetable_maybe_get_and_pin_clean (CACHEFILE, CACHEKEY, uint32_t /*fullhash*/, void**); int toku_cachetable_maybe_get_and_pin_clean (CACHEFILE, CACHEKEY, uint32_t /*fullhash*/, pair_lock_type, void**);
// Effect: Like maybe get and pin, but may pin a clean pair. // Effect: Like maybe get and pin, but may pin a clean pair.
int toku_cachetable_unpin(CACHEFILE, PAIR, enum cachetable_dirty dirty, PAIR_ATTR size); int toku_cachetable_unpin(CACHEFILE, PAIR, enum cachetable_dirty dirty, PAIR_ATTR size);
...@@ -556,5 +559,10 @@ int toku_cleaner_thread(void *cleaner_v); ...@@ -556,5 +559,10 @@ int toku_cleaner_thread(void *cleaner_v);
// The default of 1M is too high for drd tests, so this is a mechanism to set a smaller number. // The default of 1M is too high for drd tests, so this is a mechanism to set a smaller number.
void toku_pair_list_set_lock_size(uint32_t num_locks); void toku_pair_list_set_lock_size(uint32_t num_locks);
// Used by ft-ops.cc to figure out if it has the write lock on a pair.
// Pretty hacky and not accurate enough, should be improved at the frwlock
// layer.
__attribute__((const,nonnull))
bool toku_ctpair_is_write_locked(PAIR pair);
#endif /* CACHETABLE_H */ #endif /* CACHETABLE_H */
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "log-internal.h" #include "log-internal.h"
#include "logger.h" #include "logger.h"
#include "checkpoint.h" #include "checkpoint.h"
#include <portability/toku_atomic.h>
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Engine status // Engine status
...@@ -173,7 +174,7 @@ checkpoint_safe_checkpoint_unlock(void) { ...@@ -173,7 +174,7 @@ checkpoint_safe_checkpoint_unlock(void) {
void void
toku_multi_operation_client_lock(void) { toku_multi_operation_client_lock(void) {
if (locked_mo) if (locked_mo)
(void) __sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_MO), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_MO), 1);
toku_pthread_rwlock_rdlock(&multi_operation_lock); toku_pthread_rwlock_rdlock(&multi_operation_lock);
} }
...@@ -185,7 +186,7 @@ toku_multi_operation_client_unlock(void) { ...@@ -185,7 +186,7 @@ toku_multi_operation_client_unlock(void) {
void void
toku_checkpoint_safe_client_lock(void) { toku_checkpoint_safe_client_lock(void) {
if (locked_cs) if (locked_cs)
(void) __sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_CS), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_CS), 1);
toku_pthread_rwlock_rdlock(&checkpoint_safe_lock); toku_pthread_rwlock_rdlock(&checkpoint_safe_lock);
toku_multi_operation_client_lock(); toku_multi_operation_client_lock();
} }
...@@ -227,9 +228,9 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger, ...@@ -227,9 +228,9 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
assert(initialized); assert(initialized);
(void) __sync_fetch_and_add(&STATUS_VALUE(CP_WAITERS_NOW), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(CP_WAITERS_NOW), 1);
checkpoint_safe_checkpoint_lock(); checkpoint_safe_checkpoint_lock();
(void) __sync_fetch_and_sub(&STATUS_VALUE(CP_WAITERS_NOW), 1); (void) toku_sync_fetch_and_sub(&STATUS_VALUE(CP_WAITERS_NOW), 1);
if (STATUS_VALUE(CP_WAITERS_NOW) > STATUS_VALUE(CP_WAITERS_MAX)) if (STATUS_VALUE(CP_WAITERS_NOW) > STATUS_VALUE(CP_WAITERS_MAX))
STATUS_VALUE(CP_WAITERS_MAX) = STATUS_VALUE(CP_WAITERS_NOW); // threadsafe, within checkpoint_safe lock STATUS_VALUE(CP_WAITERS_MAX) = STATUS_VALUE(CP_WAITERS_NOW); // threadsafe, within checkpoint_safe lock
......
...@@ -25,12 +25,23 @@ static void fifo_init(struct fifo *fifo) { ...@@ -25,12 +25,23 @@ static void fifo_init(struct fifo *fifo) {
fifo->memory_used = 0; fifo->memory_used = 0;
} }
__attribute__((const,nonnull))
static int fifo_entry_size(struct fifo_entry *entry) { static int fifo_entry_size(struct fifo_entry *entry) {
return sizeof (struct fifo_entry) + entry->keylen + entry->vallen return sizeof (struct fifo_entry) + entry->keylen + entry->vallen
+ xids_get_size(&entry->xids_s) + xids_get_size(&entry->xids_s)
- sizeof(XIDS_S); //Prevent double counting from fifo_entry+xids_get_size - sizeof(XIDS_S); //Prevent double counting from fifo_entry+xids_get_size
} }
__attribute__((const,nonnull))
size_t toku_ft_msg_memsize_in_fifo(FT_MSG cmd) {
// This must stay in sync with fifo_entry_size because that's what we
// really trust. But sometimes we only have an in-memory FT_MSG, not
// a serialized fifo_entry so we have to fake it.
return sizeof (struct fifo_entry) + cmd->u.id.key->size + cmd->u.id.val->size
+ xids_get_size(cmd->xids)
- sizeof(XIDS_S);
}
int toku_fifo_create(FIFO *ptr) { int toku_fifo_create(FIFO *ptr) {
struct fifo *XMALLOC(fifo); struct fifo *XMALLOC(fifo);
if (fifo == 0) return ENOMEM; if (fifo == 0) return ENOMEM;
...@@ -112,6 +123,9 @@ int toku_fifo_iterate_internal_next(FIFO fifo, int off) { ...@@ -112,6 +123,9 @@ int toku_fifo_iterate_internal_next(FIFO fifo, int off) {
struct fifo_entry * toku_fifo_iterate_internal_get_entry(FIFO fifo, int off) { struct fifo_entry * toku_fifo_iterate_internal_get_entry(FIFO fifo, int off) {
return (struct fifo_entry *)(fifo->memory + off); return (struct fifo_entry *)(fifo->memory + off);
} }
size_t toku_fifo_internal_entry_memsize(struct fifo_entry *e) {
return fifo_entry_size(e);
}
void toku_fifo_iterate (FIFO fifo, void(*f)(bytevec key,ITEMLEN keylen,bytevec data,ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, void*), void *arg) { void toku_fifo_iterate (FIFO fifo, void(*f)(bytevec key,ITEMLEN keylen,bytevec data,ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, void*), void *arg) {
FIFO_ITERATE(fifo, FIFO_ITERATE(fifo,
......
...@@ -68,26 +68,30 @@ unsigned long toku_fifo_memory_footprint(FIFO fifo); // return how much memory ...@@ -68,26 +68,30 @@ unsigned long toku_fifo_memory_footprint(FIFO fifo); // return how much memory
void toku_fifo_iterate(FIFO, void(*f)(bytevec key,ITEMLEN keylen,bytevec data,ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, void*), void*); void toku_fifo_iterate(FIFO, void(*f)(bytevec key,ITEMLEN keylen,bytevec data,ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, void*), void*);
#define FIFO_ITERATE(fifo,keyvar,keylenvar,datavar,datalenvar,typevar,msnvar,xidsvar,is_freshvar,body) ({ \ #define FIFO_ITERATE(fifo,keyvar,keylenvar,datavar,datalenvar,typevar,msnvar,xidsvar,is_freshvar,body) ({ \
for (int fifo_iterate_off = toku_fifo_iterate_internal_start(fifo); \ for (int fifo_iterate_off = toku_fifo_iterate_internal_start(fifo); \
toku_fifo_iterate_internal_has_more(fifo, fifo_iterate_off); \ toku_fifo_iterate_internal_has_more(fifo, fifo_iterate_off); \
fifo_iterate_off = toku_fifo_iterate_internal_next(fifo, fifo_iterate_off)) { \ fifo_iterate_off = toku_fifo_iterate_internal_next(fifo, fifo_iterate_off)) { \
struct fifo_entry *e = toku_fifo_iterate_internal_get_entry(fifo, fifo_iterate_off); \ struct fifo_entry *e = toku_fifo_iterate_internal_get_entry(fifo, fifo_iterate_off); \
ITEMLEN keylenvar = e->keylen; \ ITEMLEN keylenvar = e->keylen; \
ITEMLEN datalenvar = e->vallen; \ ITEMLEN datalenvar = e->vallen; \
enum ft_msg_type typevar = fifo_entry_get_msg_type(e); \ enum ft_msg_type typevar = fifo_entry_get_msg_type(e); \
MSN msnvar = e->msn; \ MSN msnvar = e->msn; \
XIDS xidsvar = &e->xids_s; \ XIDS xidsvar = &e->xids_s; \
bytevec keyvar = xids_get_end_of_array(xidsvar); \ bytevec keyvar = xids_get_end_of_array(xidsvar); \
bytevec datavar = (const uint8_t*)keyvar + e->keylen; \ bytevec datavar = (const uint8_t*)keyvar + e->keylen; \
bool is_freshvar = e->is_fresh; \ bool is_freshvar = e->is_fresh; \
body; \ body; \
} }) } })
#define FIFO_CURRENT_ENTRY_MEMSIZE toku_fifo_internal_entry_memsize(e)
// Internal functions for the iterator. // Internal functions for the iterator.
int toku_fifo_iterate_internal_start(FIFO fifo); int toku_fifo_iterate_internal_start(FIFO fifo);
int toku_fifo_iterate_internal_has_more(FIFO fifo, int off); int toku_fifo_iterate_internal_has_more(FIFO fifo, int off);
int toku_fifo_iterate_internal_next(FIFO fifo, int off); int toku_fifo_iterate_internal_next(FIFO fifo, int off);
struct fifo_entry * toku_fifo_iterate_internal_get_entry(FIFO fifo, int off); struct fifo_entry * toku_fifo_iterate_internal_get_entry(FIFO fifo, int off);
size_t toku_fifo_internal_entry_memsize(struct fifo_entry *e) __attribute__((const,nonnull));
size_t toku_ft_msg_memsize_in_fifo(FT_MSG cmd) __attribute__((const,nonnull));
DBT *fill_dbt_for_fifo_entry(DBT *dbt, const struct fifo_entry *entry); DBT *fill_dbt_for_fifo_entry(DBT *dbt, const struct fifo_entry *entry);
struct fifo_entry *toku_fifo_get_entry(FIFO fifo, int off); struct fifo_entry *toku_fifo_get_entry(FIFO fifo, int off);
......
...@@ -147,7 +147,7 @@ toku_pin_ftnode_batched( ...@@ -147,7 +147,7 @@ toku_pin_ftnode_batched(
if (apply_ancestor_messages && node->height == 0) { if (apply_ancestor_messages && node->height == 0) {
needs_ancestors_messages = toku_ft_leaf_needs_ancestors_messages(brt->ft, node, ancestors, bounds, &max_msn_in_path); needs_ancestors_messages = toku_ft_leaf_needs_ancestors_messages(brt->ft, node, ancestors, bounds, &max_msn_in_path);
if (needs_ancestors_messages && needed_lock_type == PL_READ) { if (needs_ancestors_messages && needed_lock_type == PL_READ) {
toku_unpin_ftnode_read_only(brt, node); toku_unpin_ftnode_read_only(brt->ft, node);
needed_lock_type = PL_WRITE_CHEAP; needed_lock_type = PL_WRITE_CHEAP;
goto try_again_for_write_lock; goto try_again_for_write_lock;
} }
...@@ -296,14 +296,14 @@ toku_pin_ftnode_off_client_thread_batched( ...@@ -296,14 +296,14 @@ toku_pin_ftnode_off_client_thread_batched(
h, blocknum, fullhash, bfe, lock_type, num_dependent_nodes, dependent_nodes, node_p, true); h, blocknum, fullhash, bfe, lock_type, num_dependent_nodes, dependent_nodes, node_p, true);
} }
int toku_maybe_pin_ftnode_clean(FT ft, BLOCKNUM blocknum, uint32_t fullhash, FTNODE *nodep) { int toku_maybe_pin_ftnode_clean(FT ft, BLOCKNUM blocknum, uint32_t fullhash, pair_lock_type lock_type, FTNODE *nodep) {
void *node_v; void *node_v;
int r = toku_cachetable_maybe_get_and_pin_clean(ft->cf, blocknum, fullhash, &node_v); int r = toku_cachetable_maybe_get_and_pin_clean(ft->cf, blocknum, fullhash, lock_type, &node_v);
if (r != 0) { if (r != 0) {
goto cleanup; goto cleanup;
} }
CAST_FROM_VOIDP(*nodep, node_v); CAST_FROM_VOIDP(*nodep, node_v);
if ((*nodep)->height > 0) { if ((*nodep)->height > 0 && lock_type != PL_READ) {
toku_move_ftnode_messages_to_stale(ft, *nodep); toku_move_ftnode_messages_to_stale(ft, *nodep);
} }
cleanup: cleanup:
...@@ -331,14 +331,13 @@ toku_unpin_ftnode(FT ft, FTNODE node) ...@@ -331,14 +331,13 @@ toku_unpin_ftnode(FT ft, FTNODE node)
} }
void void
toku_unpin_ftnode_read_only(FT_HANDLE brt, FTNODE node) toku_unpin_ftnode_read_only(FT ft, FTNODE node)
{ {
int r = toku_cachetable_unpin( int r = toku_cachetable_unpin(
brt->ft->cf, ft->cf,
node->ct_pair, node->ct_pair,
(enum cachetable_dirty) node->dirty, (enum cachetable_dirty) node->dirty,
make_invalid_pair_attr() make_invalid_pair_attr()
); );
assert(r==0); assert(r==0);
} }
...@@ -108,7 +108,7 @@ toku_pin_ftnode_off_client_thread_and_maybe_move_messages( ...@@ -108,7 +108,7 @@ toku_pin_ftnode_off_client_thread_and_maybe_move_messages(
* This function may return a pinned ftnode to the caller, if pinning is cheap. * This function may return a pinned ftnode to the caller, if pinning is cheap.
* If the node is already locked, or is pending a checkpoint, the node is not pinned and -1 is returned. * If the node is already locked, or is pending a checkpoint, the node is not pinned and -1 is returned.
*/ */
int toku_maybe_pin_ftnode_clean(FT ft, BLOCKNUM blocknum, uint32_t fullhash, FTNODE *nodep); int toku_maybe_pin_ftnode_clean(FT ft, BLOCKNUM blocknum, uint32_t fullhash, pair_lock_type lock_type, FTNODE *nodep);
/** /**
* Batched version of toku_pin_ftnode_off_client_thread, see cachetable * Batched version of toku_pin_ftnode_off_client_thread, see cachetable
...@@ -158,6 +158,6 @@ void ...@@ -158,6 +158,6 @@ void
toku_unpin_ftnode(FT h, FTNODE node); toku_unpin_ftnode(FT h, FTNODE node);
void void
toku_unpin_ftnode_read_only(FT_HANDLE brt, FTNODE node); toku_unpin_ftnode_read_only(FT ft, FTNODE node);
#endif #endif
This diff is collapsed.
...@@ -89,6 +89,7 @@ ftleaf_split( ...@@ -89,6 +89,7 @@ ftleaf_split(
FTNODE *nodeb, FTNODE *nodeb,
DBT *splitk, DBT *splitk,
bool create_new_node, bool create_new_node,
enum split_mode split_mode,
uint32_t num_dependent_nodes, uint32_t num_dependent_nodes,
FTNODE* dependent_nodes FTNODE* dependent_nodes
); );
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <ft-cachetable-wrappers.h> #include <ft-cachetable-wrappers.h>
#include <ft-internal.h> #include <ft-internal.h>
#include <ft.h> #include <ft.h>
#include <portability/toku_atomic.h>
// Member Descirption: // Member Descirption:
// 1. highest_pivot_key - this is the key that corresponds to the // 1. highest_pivot_key - this is the key that corresponds to the
...@@ -251,7 +252,7 @@ toku_ft_hot_optimize(FT_HANDLE brt, ...@@ -251,7 +252,7 @@ toku_ft_hot_optimize(FT_HANDLE brt,
uint64_t loop_count = 0; uint64_t loop_count = 0;
MSN msn_at_start_of_hot = ZERO_MSN; // capture msn from root at MSN msn_at_start_of_hot = ZERO_MSN; // capture msn from root at
// start of HOT operation // start of HOT operation
(void) __sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_STARTED), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_STARTED), 1);
{ {
toku_ft_note_hot_begin(brt); toku_ft_note_hot_begin(brt);
...@@ -353,9 +354,9 @@ toku_ft_hot_optimize(FT_HANDLE brt, ...@@ -353,9 +354,9 @@ toku_ft_hot_optimize(FT_HANDLE brt,
} }
if (success) { if (success) {
(void) __sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_COMPLETED), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_COMPLETED), 1);
} else { } else {
(void) __sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_ABORTED), 1); (void) toku_sync_fetch_and_add(&STATUS_VALUE(FT_HOT_NUM_ABORTED), 1);
} }
} }
return r; return r;
......
This diff is collapsed.
This diff is collapsed.
...@@ -134,8 +134,8 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) ...@@ -134,8 +134,8 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
{ {
int r; int r;
FT ft = NULL; FT ft = NULL;
invariant(version >= FT_LAYOUT_MIN_SUPPORTED_VERSION); paranoid_invariant(version >= FT_LAYOUT_MIN_SUPPORTED_VERSION);
invariant(version <= FT_LAYOUT_VERSION); paranoid_invariant(version <= FT_LAYOUT_VERSION);
// We already know: // We already know:
// we have an rbuf representing the header. // we have an rbuf representing the header.
// The checksum has been validated // The checksum has been validated
...@@ -290,6 +290,12 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) ...@@ -290,6 +290,12 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
} }
} }
MSN max_msn_in_ft;
max_msn_in_ft = ZERO_MSN; // We'll upgrade it from the root node later if necessary
if (ft->layout_version_read_from_disk >= FT_LAYOUT_VERSION_21) {
max_msn_in_ft = rbuf_msn(rb);
}
(void) rbuf_int(rb); //Read in checksum and ignore (already verified). (void) rbuf_int(rb); //Read in checksum and ignore (already verified).
if (rb->ndone != rb->size) { if (rb->ndone != rb->size) {
fprintf(stderr, "Header size did not match contents.\n"); fprintf(stderr, "Header size did not match contents.\n");
...@@ -317,6 +323,7 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) ...@@ -317,6 +323,7 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
.basementnodesize = basementnodesize, .basementnodesize = basementnodesize,
.compression_method = compression_method, .compression_method = compression_method,
.highest_unused_msn_for_upgrade = highest_unused_msn_for_upgrade, .highest_unused_msn_for_upgrade = highest_unused_msn_for_upgrade,
.max_msn_in_ft = max_msn_in_ft,
.time_of_last_optimize_begin = time_of_last_optimize_begin, .time_of_last_optimize_begin = time_of_last_optimize_begin,
.time_of_last_optimize_end = time_of_last_optimize_end, .time_of_last_optimize_end = time_of_last_optimize_end,
.count_of_optimize_in_progress = count_of_optimize_in_progress, .count_of_optimize_in_progress = count_of_optimize_in_progress,
...@@ -335,6 +342,12 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) ...@@ -335,6 +342,12 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
goto exit; goto exit;
} }
} }
if (ft->layout_version_read_from_disk < FT_LAYOUT_VERSION_21) {
r = toku_upgrade_msn_from_root_to_header(fd, ft);
if (r != 0) {
goto exit;
}
}
invariant((uint32_t) ft->layout_version_read_from_disk == version); invariant((uint32_t) ft->layout_version_read_from_disk == version);
r = deserialize_descriptor_from(fd, ft->blocktable, &ft->descriptor, version); r = deserialize_descriptor_from(fd, ft->blocktable, &ft->descriptor, version);
...@@ -366,10 +379,12 @@ serialize_ft_min_size (uint32_t version) { ...@@ -366,10 +379,12 @@ serialize_ft_min_size (uint32_t version) {
size_t size = 0; size_t size = 0;
switch(version) { switch(version) {
case FT_LAYOUT_VERSION_21:
size += sizeof(MSN); // max_msn_in_ft
case FT_LAYOUT_VERSION_20: case FT_LAYOUT_VERSION_20:
case FT_LAYOUT_VERSION_19: case FT_LAYOUT_VERSION_19:
size += 1; // compression method size += 1; // compression method
size += sizeof(uint64_t); // highest_unused_msn_for_upgrade size += sizeof(MSN); // highest_unused_msn_for_upgrade
case FT_LAYOUT_VERSION_18: case FT_LAYOUT_VERSION_18:
size += sizeof(uint64_t); // time_of_last_optimize_begin size += sizeof(uint64_t); // time_of_last_optimize_begin
size += sizeof(uint64_t); // time_of_last_optimize_end size += sizeof(uint64_t); // time_of_last_optimize_end
...@@ -412,9 +427,9 @@ serialize_ft_min_size (uint32_t version) { ...@@ -412,9 +427,9 @@ serialize_ft_min_size (uint32_t version) {
); );
break; break;
default: default:
lazy_assert(false); abort();
} }
lazy_assert(size <= BLOCK_ALLOCATOR_HEADER_RESERVE); lazy_assert(size <= BLOCK_ALLOCATOR_HEADER_RESERVE);
return size; return size;
} }
...@@ -637,7 +652,7 @@ toku_deserialize_ft_from(int fd, ...@@ -637,7 +652,7 @@ toku_deserialize_ft_from(int fd,
version = version_1; version = version_1;
} }
invariant(rb); paranoid_invariant(rb);
r = deserialize_ft_versioned(fd, rb, ft, version); r = deserialize_ft_versioned(fd, rb, ft, version);
exit: exit:
...@@ -694,6 +709,7 @@ void toku_serialize_ft_to_wbuf ( ...@@ -694,6 +709,7 @@ void toku_serialize_ft_to_wbuf (
wbuf_MSN(wbuf, h->msn_at_start_of_last_completed_optimize); wbuf_MSN(wbuf, h->msn_at_start_of_last_completed_optimize);
wbuf_char(wbuf, (unsigned char) h->compression_method); wbuf_char(wbuf, (unsigned char) h->compression_method);
wbuf_MSN(wbuf, h->highest_unused_msn_for_upgrade); wbuf_MSN(wbuf, h->highest_unused_msn_for_upgrade);
wbuf_MSN(wbuf, h->max_msn_in_ft);
uint32_t checksum = x1764_finish(&wbuf->checksum); uint32_t checksum = x1764_finish(&wbuf->checksum);
wbuf_int(wbuf, checksum); wbuf_int(wbuf, checksum);
lazy_assert(wbuf->ndone == wbuf->size); lazy_assert(wbuf->ndone == wbuf->size);
......
...@@ -136,15 +136,18 @@ int toku_testsetup_insert_to_leaf (FT_HANDLE brt, BLOCKNUM blocknum, const char ...@@ -136,15 +136,18 @@ int toku_testsetup_insert_to_leaf (FT_HANDLE brt, BLOCKNUM blocknum, const char
.u = { .id = { toku_fill_dbt(&keydbt, key, keylen), .u = { .id = { toku_fill_dbt(&keydbt, key, keylen),
toku_fill_dbt(&valdbt, val, vallen) } } }; toku_fill_dbt(&valdbt, val, vallen) } } };
static size_t zero_flow_deltas[] = { 0, 0 };
toku_ft_node_put_cmd ( toku_ft_node_put_cmd (
brt->ft->compare_fun, brt->ft->compare_fun,
brt->ft->update_fun, brt->ft->update_fun,
&brt->ft->cmp_descriptor, &brt->ft->cmp_descriptor,
node, node,
-1,
&cmd, &cmd,
true, true,
zero_flow_deltas,
NULL NULL
); );
toku_verify_or_set_counts(node); toku_verify_or_set_counts(node);
...@@ -215,6 +218,8 @@ int toku_testsetup_insert_to_nonleaf (FT_HANDLE brt, BLOCKNUM blocknum, enum ft_ ...@@ -215,6 +218,8 @@ int toku_testsetup_insert_to_nonleaf (FT_HANDLE brt, BLOCKNUM blocknum, enum ft_
// using brt APIs. // using brt APIs.
node->max_msn_applied_to_node_on_disk = msn; node->max_msn_applied_to_node_on_disk = msn;
node->dirty = 1; node->dirty = 1;
// Also hack max_msn_in_ft
brt->ft->h->max_msn_in_ft = msn;
toku_unpin_ftnode(brt->ft, node); toku_unpin_ftnode(brt->ft, node);
return 0; return 0;
......
...@@ -245,7 +245,7 @@ toku_get_node_for_verify( ...@@ -245,7 +245,7 @@ toku_get_node_for_verify(
static int static int
toku_verify_ftnode_internal(FT_HANDLE brt, toku_verify_ftnode_internal(FT_HANDLE brt,
MSN rootmsn, MSN parentmsn, MSN rootmsn, MSN parentmsn, bool messages_exist_above,
FTNODE node, int height, FTNODE node, int height,
const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.) const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.) const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
...@@ -258,16 +258,11 @@ toku_verify_ftnode_internal(FT_HANDLE brt, ...@@ -258,16 +258,11 @@ toku_verify_ftnode_internal(FT_HANDLE brt,
//printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); //printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v);
toku_assert_entire_node_in_memory(node); toku_assert_entire_node_in_memory(node);
this_msn = node->max_msn_applied_to_node_on_disk; this_msn = node->max_msn_applied_to_node_on_disk;
if (rootmsn.msn == ZERO_MSN.msn) {
assert(parentmsn.msn == ZERO_MSN.msn);
rootmsn = this_msn;
parentmsn = this_msn;
}
if (height >= 0) { if (height >= 0) {
invariant(height == node->height); // this is a bad failure if wrong invariant(height == node->height); // this is a bad failure if wrong
} }
if (node->height > 0) { if (node->height > 0 && messages_exist_above) {
VERIFY_ASSERTION((parentmsn.msn >= this_msn.msn), 0, "node msn must be descending down tree, newest messages at top"); VERIFY_ASSERTION((parentmsn.msn >= this_msn.msn), 0, "node msn must be descending down tree, newest messages at top");
} }
// Verify that all the pivot keys are in order. // Verify that all the pivot keys are in order.
...@@ -390,7 +385,7 @@ toku_verify_ftnode_internal(FT_HANDLE brt, ...@@ -390,7 +385,7 @@ toku_verify_ftnode_internal(FT_HANDLE brt,
// input is a pinned node, on exit, node is unpinned // input is a pinned node, on exit, node is unpinned
int int
toku_verify_ftnode (FT_HANDLE brt, toku_verify_ftnode (FT_HANDLE brt,
MSN rootmsn, MSN parentmsn, MSN rootmsn, MSN parentmsn, bool messages_exist_above,
FTNODE node, int height, FTNODE node, int height,
const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.) const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.) const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
...@@ -402,11 +397,6 @@ toku_verify_ftnode (FT_HANDLE brt, ...@@ -402,11 +397,6 @@ toku_verify_ftnode (FT_HANDLE brt,
//printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); //printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v);
toku_assert_entire_node_in_memory(node); toku_assert_entire_node_in_memory(node);
this_msn = node->max_msn_applied_to_node_on_disk; this_msn = node->max_msn_applied_to_node_on_disk;
if (rootmsn.msn == ZERO_MSN.msn) {
assert(parentmsn.msn == ZERO_MSN.msn);
rootmsn = this_msn;
parentmsn = this_msn;
}
int result = 0; int result = 0;
int result2 = 0; int result2 = 0;
...@@ -414,7 +404,7 @@ toku_verify_ftnode (FT_HANDLE brt, ...@@ -414,7 +404,7 @@ toku_verify_ftnode (FT_HANDLE brt,
// Otherwise we'll just do the next call // Otherwise we'll just do the next call
result = toku_verify_ftnode_internal( result = toku_verify_ftnode_internal(
brt, rootmsn, parentmsn, node, height, lesser_pivot, greatereq_pivot, brt, rootmsn, parentmsn, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
verbose, keep_going_on_failure, false); verbose, keep_going_on_failure, false);
if (result != 0 && (!keep_going_on_failure || result != TOKUDB_NEEDS_REPAIR)) goto done; if (result != 0 && (!keep_going_on_failure || result != TOKUDB_NEEDS_REPAIR)) goto done;
} }
...@@ -422,7 +412,7 @@ toku_verify_ftnode (FT_HANDLE brt, ...@@ -422,7 +412,7 @@ toku_verify_ftnode (FT_HANDLE brt,
toku_move_ftnode_messages_to_stale(brt->ft, node); toku_move_ftnode_messages_to_stale(brt->ft, node);
} }
result2 = toku_verify_ftnode_internal( result2 = toku_verify_ftnode_internal(
brt, rootmsn, parentmsn, node, height, lesser_pivot, greatereq_pivot, brt, rootmsn, parentmsn, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
verbose, keep_going_on_failure, true); verbose, keep_going_on_failure, true);
if (result == 0) { if (result == 0) {
result = result2; result = result2;
...@@ -434,7 +424,7 @@ toku_verify_ftnode (FT_HANDLE brt, ...@@ -434,7 +424,7 @@ toku_verify_ftnode (FT_HANDLE brt,
for (int i = 0; i < node->n_children; i++) { for (int i = 0; i < node->n_children; i++) {
FTNODE child_node; FTNODE child_node;
toku_get_node_for_verify(BP_BLOCKNUM(node, i), brt, &child_node); toku_get_node_for_verify(BP_BLOCKNUM(node, i), brt, &child_node);
int r = toku_verify_ftnode(brt, rootmsn, this_msn, int r = toku_verify_ftnode(brt, rootmsn, this_msn, messages_exist_above || toku_bnc_n_entries(BNC(node, i)) > 0,
child_node, node->height-1, child_node, node->height-1,
(i==0) ? lesser_pivot : &node->childkeys[i-1], (i==0) ? lesser_pivot : &node->childkeys[i-1],
(i==node->n_children-1) ? greatereq_pivot : &node->childkeys[i], (i==node->n_children-1) ? greatereq_pivot : &node->childkeys[i],
...@@ -465,7 +455,7 @@ toku_verify_ft_with_progress (FT_HANDLE brt, int (*progress_callback)(void *extr ...@@ -465,7 +455,7 @@ toku_verify_ft_with_progress (FT_HANDLE brt, int (*progress_callback)(void *extr
toku_calculate_root_offset_pointer(brt->ft, &root_key, &root_hash); toku_calculate_root_offset_pointer(brt->ft, &root_key, &root_hash);
toku_get_node_for_verify(root_key, brt, &root_node); toku_get_node_for_verify(root_key, brt, &root_node);
} }
int r = toku_verify_ftnode(brt, ZERO_MSN, ZERO_MSN, root_node, -1, NULL, NULL, progress_callback, progress_extra, 1, verbose, keep_on_going); int r = toku_verify_ftnode(brt, brt->ft->h->max_msn_in_ft, brt->ft->h->max_msn_in_ft, false, root_node, -1, NULL, NULL, progress_callback, progress_extra, 1, verbose, keep_on_going);
if (r == 0) { if (r == 0) {
toku_ft_lock(brt->ft); toku_ft_lock(brt->ft);
brt->ft->h->time_of_last_verification = time(NULL); brt->ft->h->time_of_last_verification = time(NULL);
...@@ -479,4 +469,3 @@ int ...@@ -479,4 +469,3 @@ int
toku_verify_ft (FT_HANDLE brt) { toku_verify_ft (FT_HANDLE brt) {
return toku_verify_ft_with_progress(brt, NULL, NULL, 0, 0); return toku_verify_ft_with_progress(brt, NULL, NULL, 0, 0);
} }
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <memory.h> #include <memory.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <portability/toku_atomic.h>
void void
toku_ft_suppress_rollbacks(FT h, TOKUTXN txn) { toku_ft_suppress_rollbacks(FT h, TOKUTXN txn) {
...@@ -365,6 +366,7 @@ ft_header_create(FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that ...@@ -365,6 +366,7 @@ ft_header_create(FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that
.basementnodesize = options->basementnodesize, .basementnodesize = options->basementnodesize,
.compression_method = options->compression_method, .compression_method = options->compression_method,
.highest_unused_msn_for_upgrade = { .msn = (MIN_MSN.msn - 1) }, .highest_unused_msn_for_upgrade = { .msn = (MIN_MSN.msn - 1) },
.max_msn_in_ft = ZERO_MSN,
.time_of_last_optimize_begin = 0, .time_of_last_optimize_begin = 0,
.time_of_last_optimize_end = 0, .time_of_last_optimize_end = 0,
.count_of_optimize_in_progress = 0, .count_of_optimize_in_progress = 0,
...@@ -850,14 +852,14 @@ toku_ft_get_cmp_descriptor(FT_HANDLE ft_handle) { ...@@ -850,14 +852,14 @@ toku_ft_get_cmp_descriptor(FT_HANDLE ft_handle) {
void void
toku_ft_update_stats(STAT64INFO headerstats, STAT64INFO_S delta) { toku_ft_update_stats(STAT64INFO headerstats, STAT64INFO_S delta) {
(void) __sync_fetch_and_add(&(headerstats->numrows), delta.numrows); (void) toku_sync_fetch_and_add(&(headerstats->numrows), delta.numrows);
(void) __sync_fetch_and_add(&(headerstats->numbytes), delta.numbytes); (void) toku_sync_fetch_and_add(&(headerstats->numbytes), delta.numbytes);
} }
void void
toku_ft_decrease_stats(STAT64INFO headerstats, STAT64INFO_S delta) { toku_ft_decrease_stats(STAT64INFO headerstats, STAT64INFO_S delta) {
(void) __sync_fetch_and_sub(&(headerstats->numrows), delta.numrows); (void) toku_sync_fetch_and_sub(&(headerstats->numrows), delta.numrows);
(void) __sync_fetch_and_sub(&(headerstats->numbytes), delta.numbytes); (void) toku_sync_fetch_and_sub(&(headerstats->numbytes), delta.numbytes);
} }
void void
......
...@@ -28,6 +28,7 @@ enum ft_layout_version_e { ...@@ -28,6 +28,7 @@ enum ft_layout_version_e {
FT_LAYOUT_VERSION_20 = 20, // Deadshot: Add compression method to log_fcreate, FT_LAYOUT_VERSION_20 = 20, // Deadshot: Add compression method to log_fcreate,
// mgr_last_xid after begin checkpoint, // mgr_last_xid after begin checkpoint,
// last_xid to shutdown // last_xid to shutdown
FT_LAYOUT_VERSION_21 = 21, // Ming: Add max_msn_in_ft to header
FT_NEXT_VERSION, // the version after the current version FT_NEXT_VERSION, // the version after the current version
FT_LAYOUT_VERSION = FT_NEXT_VERSION-1, // A hack so I don't have to change this line. FT_LAYOUT_VERSION = FT_NEXT_VERSION-1, // A hack so I don't have to change this line.
FT_LAYOUT_MIN_SUPPORTED_VERSION = FT_LAYOUT_VERSION_13, // Minimum version supported FT_LAYOUT_MIN_SUPPORTED_VERSION = FT_LAYOUT_VERSION_13, // Minimum version supported
......
This diff is collapsed.
...@@ -281,6 +281,10 @@ enum reactivity { ...@@ -281,6 +281,10 @@ enum reactivity {
RE_FISSIBLE RE_FISSIBLE
}; };
enum split_mode {
SPLIT_EVENLY,
SPLIT_LEFT_HEAVY,
SPLIT_RIGHT_HEAVY
};
#endif #endif
...@@ -175,12 +175,12 @@ int le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t * ...@@ -175,12 +175,12 @@ int le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t *
size_t size_t
leafentry_disksize_13(LEAFENTRY_13 le); leafentry_disksize_13(LEAFENTRY_13 le);
int int
toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, // NULL if there was no stored data. toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, // NULL if there was no stored data.
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY *new_leafentry_p, LEAFENTRY *new_leafentry_p,
OMT omt, OMT *omtp,
struct mempool *mp); struct mempool *mp);
......
...@@ -34,6 +34,7 @@ lfence: 12.9ns/loop (marginal cost= -0.1ns) ...@@ -34,6 +34,7 @@ lfence: 12.9ns/loop (marginal cost= -0.1ns)
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h> #include <stdio.h>
#include <portability/toku_atomic.h>
enum { COUNT = 100000000 }; enum { COUNT = 100000000 };
...@@ -67,8 +68,8 @@ static inline void sfence (void) { ...@@ -67,8 +68,8 @@ static inline void sfence (void) {
int lock_for_lock_and_unlock; int lock_for_lock_and_unlock;
static inline void lock_and_unlock (void) { static inline void lock_and_unlock (void) {
(void)__sync_lock_test_and_set(&lock_for_lock_and_unlock, 1); (void)toku_sync_lock_test_and_set(&lock_for_lock_and_unlock, 1);
__sync_lock_release(&lock_for_lock_and_unlock); toku_sync_lock_release(&lock_for_lock_and_unlock);
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <pthread.h>
#include <portability/toku_atomic.h>
float tdiff (struct timeval *start, struct timeval *end) { float tdiff (struct timeval *start, struct timeval *end) {
return 1e6*(end->tv_sec-start->tv_sec) +(end->tv_usec - start->tv_usec); return 1e6*(end->tv_sec-start->tv_sec) +(end->tv_usec - start->tv_usec);
...@@ -71,13 +72,13 @@ fetch_and_add_i (volatile int *p, int incr) ...@@ -71,13 +72,13 @@ fetch_and_add_i (volatile int *p, int incr)
static inline int static inline int
gcc_fetch_and_add_i (volatile int *p, int incr) gcc_fetch_and_add_i (volatile int *p, int incr)
{ {
return __sync_fetch_and_add(p, incr); return toku_sync_fetch_and_add(p, incr);
} }
static inline long static inline long
gcc_fetch_and_add_l (volatile long *p, long incr) gcc_fetch_and_add_l (volatile long *p, long incr)
{ {
return __sync_fetch_and_add(p, incr); return toku_sync_fetch_and_add(p, incr);
} }
// Something wrong with the compiler for longs // Something wrong with the compiler for longs
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <rdtsc.h> #include <rdtsc.h>
#include <portability/toku_atomic.h>
float tdiff (struct timeval *start, struct timeval *end) { float tdiff (struct timeval *start, struct timeval *end) {
return 1e6*(end->tv_sec-start->tv_sec) +(end->tv_usec - start->tv_usec); return 1e6*(end->tv_sec-start->tv_sec) +(end->tv_usec - start->tv_usec);
...@@ -135,12 +136,12 @@ int main(int argc __attribute__((unused)), char **argv) ...@@ -135,12 +136,12 @@ int main(int argc __attribute__((unused)), char **argv)
{ {
static int lock_for_lock_and_unlock; static int lock_for_lock_and_unlock;
t_start = rdtsc(); t_start = rdtsc();
(void)__sync_lock_test_and_set(&lock_for_lock_and_unlock, 1); (void)toku_sync_lock_test_and_set(&lock_for_lock_and_unlock, 1);
t_end = rdtsc(); t_end = rdtsc();
printf("sync_lock_test_and_set took %llu clocks\n", t_end-t_start); printf("sync_lock_test_and_set took %llu clocks\n", t_end-t_start);
t_start = rdtsc(); t_start = rdtsc();
__sync_lock_release(&lock_for_lock_and_unlock); toku_sync_lock_release(&lock_for_lock_and_unlock);
t_end = rdtsc(); t_end = rdtsc();
printf("sync_lock_release took %llu clocks\n", t_end-t_start); printf("sync_lock_release took %llu clocks\n", t_end-t_start);
} }
...@@ -148,7 +149,7 @@ int main(int argc __attribute__((unused)), char **argv) ...@@ -148,7 +149,7 @@ int main(int argc __attribute__((unused)), char **argv)
{ {
t_start = rdtsc(); t_start = rdtsc();
(void)__sync_synchronize(); (void)toku_sync_synchronize();
t_end = rdtsc(); t_end = rdtsc();
printf("sync_synchornize took %llu clocks\n", t_end-t_start); printf("sync_synchornize took %llu clocks\n", t_end-t_start);
} }
......
...@@ -44,6 +44,7 @@ static inline CACHETABLE_WRITE_CALLBACK get_write_callbacks_for_rollback_log(FT ...@@ -44,6 +44,7 @@ static inline CACHETABLE_WRITE_CALLBACK get_write_callbacks_for_rollback_log(FT
wc.pe_callback = toku_rollback_pe_callback; wc.pe_callback = toku_rollback_pe_callback;
wc.cleaner_callback = toku_rollback_cleaner_callback; wc.cleaner_callback = toku_rollback_cleaner_callback;
wc.clone_callback = toku_rollback_clone_callback; wc.clone_callback = toku_rollback_clone_callback;
wc.checkpoint_complete_callback = nullptr;
wc.write_extraargs = h; wc.write_extraargs = h;
return wc; return wc;
} }
......
...@@ -84,7 +84,7 @@ void rollback_empty_log_init(ROLLBACK_LOG_NODE log) { ...@@ -84,7 +84,7 @@ void rollback_empty_log_init(ROLLBACK_LOG_NODE log) {
log->layout_version_read_from_disk = FT_LAYOUT_VERSION; log->layout_version_read_from_disk = FT_LAYOUT_VERSION;
log->dirty = true; log->dirty = true;
log->sequence = 0; log->sequence = 0;
log->previous = {0}; log->previous = make_blocknum(0);
log->previous_hash = 0; log->previous_hash = 0;
log->oldest_logentry = NULL; log->oldest_logentry = NULL;
log->newest_logentry = NULL; log->newest_logentry = NULL;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <unistd.h> #include <unistd.h>
#include "cachetable-test.h" #include "cachetable-test.h"
#include "checkpoint.h" #include "checkpoint.h"
#include <portability/toku_atomic.h>
static int N; // how many items in the table static int N; // how many items in the table
static CACHEFILE cf; static CACHEFILE cf;
...@@ -54,9 +55,9 @@ flush ( ...@@ -54,9 +55,9 @@ flush (
int *CAST_FROM_VOIDP(v, value); int *CAST_FROM_VOIDP(v, value);
if (*v!=expect_value) printf("got %d expect %d\n", *v, expect_value); if (*v!=expect_value) printf("got %d expect %d\n", *v, expect_value);
assert(*v==expect_value); assert(*v==expect_value);
(void)__sync_fetch_and_add(&n_flush, 1); (void)toku_sync_fetch_and_add(&n_flush, 1);
if (write_me) (void)__sync_fetch_and_add(&n_write_me, 1); if (write_me) (void)toku_sync_fetch_and_add(&n_write_me, 1);
if (keep_me) (void)__sync_fetch_and_add(&n_keep_me, 1); if (keep_me) (void)toku_sync_fetch_and_add(&n_keep_me, 1);
sleep_random(); sleep_random();
} }
......
...@@ -106,7 +106,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) { ...@@ -106,7 +106,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
CACHEKEY key = make_blocknum(i); CACHEKEY key = make_blocknum(i);
uint32_t hi = toku_cachetable_hash(f1, key); uint32_t hi = toku_cachetable_hash(f1, key);
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, key, hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, key, hi, PL_WRITE_EXPENSIVE, &v);
if (r != 0) if (r != 0)
continue; continue;
r = toku_test_cachetable_unpin(f1, key, hi, CACHETABLE_CLEAN, make_pair_attr(item_size)); r = toku_test_cachetable_unpin(f1, key, hi, CACHETABLE_CLEAN, make_pair_attr(item_size));
......
...@@ -193,6 +193,7 @@ void checkpointer_test::add_pairs(struct cachefile *cf, ...@@ -193,6 +193,7 @@ void checkpointer_test::add_pairs(struct cachefile *cf,
attr.cache_pressure_size = 0; attr.cache_pressure_size = 0;
attr.is_valid = true; attr.is_valid = true;
CACHETABLE_WRITE_CALLBACK cb; CACHETABLE_WRITE_CALLBACK cb;
ZERO_STRUCT(cb); // All nullptr
for (uint32_t i = k; i < count + k; ++i) { for (uint32_t i = k; i < count + k; ++i) {
CACHEKEY key; CACHEKEY key;
...@@ -201,12 +202,12 @@ void checkpointer_test::add_pairs(struct cachefile *cf, ...@@ -201,12 +202,12 @@ void checkpointer_test::add_pairs(struct cachefile *cf,
pair_init(&(pairs[i]), pair_init(&(pairs[i]),
cf, cf,
key, key,
NULL, nullptr,
attr, attr,
CACHETABLE_CLEAN, CACHETABLE_CLEAN,
full_hash, full_hash,
cb, cb,
NULL, nullptr,
m_cp.m_list); m_cp.m_list);
m_cp.m_list->put(&pairs[i]); m_cp.m_list->put(&pairs[i]);
......
...@@ -27,7 +27,8 @@ cachetable_count_pinned_test (int n) { ...@@ -27,7 +27,8 @@ cachetable_count_pinned_test (int n) {
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == -1); assert(r == -1);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
......
...@@ -43,12 +43,12 @@ test_cachetable_def_flush (int n) { ...@@ -43,12 +43,12 @@ test_cachetable_def_flush (int n) {
uint32_t hi; uint32_t hi;
void *v; void *v;
hi = toku_cachetable_hash(f1, make_blocknum(i)); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == 0 && v == (void *)(long)i); assert(r == 0 && v == (void *)(long)i);
r = toku_test_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1)); r = toku_test_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1));
assert(r == 0); assert(r == 0);
hi = toku_cachetable_hash(f2, make_blocknum(i)); hi = toku_cachetable_hash(f2, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == 0 && v == (void *)(long)i); assert(r == 0 && v == (void *)(long)i);
r = toku_test_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1)); r = toku_test_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1));
assert(r == 0); assert(r == 0);
...@@ -63,10 +63,10 @@ test_cachetable_def_flush (int n) { ...@@ -63,10 +63,10 @@ test_cachetable_def_flush (int n) {
uint32_t hi; uint32_t hi;
void *v; void *v;
hi = toku_cachetable_hash(f1, make_blocknum(i)); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r != 0); assert(r != 0);
hi = toku_cachetable_hash(f2, make_blocknum(i)); hi = toku_cachetable_hash(f2, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == 0); assert(r == 0);
r = toku_test_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1)); r = toku_test_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1));
assert(r == 0); assert(r == 0);
......
...@@ -122,7 +122,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir ...@@ -122,7 +122,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
CACHEKEY key = make_blocknum(i); CACHEKEY key = make_blocknum(i);
uint32_t hi = toku_cachetable_hash(f1, key); uint32_t hi = toku_cachetable_hash(f1, key);
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, key, hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, key, hi, PL_WRITE_EXPENSIVE, &v);
if (r != 0) if (r != 0)
continue; continue;
r = toku_test_cachetable_unpin(f1, key, hi, CACHETABLE_CLEAN, make_pair_attr(item_size)); r = toku_test_cachetable_unpin(f1, key, hi, CACHETABLE_CLEAN, make_pair_attr(item_size));
......
...@@ -51,7 +51,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) { ...@@ -51,7 +51,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
int i; int i;
for (i=1; i>=0; i++) { for (i=1; i>=0; i++) {
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, key, fullhash, &v); r = toku_cachetable_maybe_get_and_pin(f1, key, fullhash, PL_WRITE_EXPENSIVE, &v);
if (r == 0) break; if (r == 0) break;
toku_pthread_yield(); toku_pthread_yield();
} }
......
...@@ -58,7 +58,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) { ...@@ -58,7 +58,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
int i; int i;
for (i=1; i>=0; i++) { for (i=1; i>=0; i++) {
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, key, fullhash, &v); r = toku_cachetable_maybe_get_and_pin(f1, key, fullhash, PL_WRITE_EXPENSIVE, &v);
if (r == 0) break; if (r == 0) break;
toku_pthread_yield(); toku_pthread_yield();
} }
......
...@@ -26,7 +26,7 @@ cachetable_put_test (int n) { ...@@ -26,7 +26,7 @@ cachetable_put_test (int n) {
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == -1); assert(r == -1);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
......
...@@ -26,37 +26,37 @@ cachetable_test (void) { ...@@ -26,37 +26,37 @@ cachetable_test (void) {
void* v1; void* v1;
long s1; long s1;
// nothing in cachetable, so this should fail // nothing in cachetable, so this should fail
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL); r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8)); r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
// maybe_get_and_pin_clean should succeed, maybe_get_and_pin should fail // maybe_get_and_pin_clean should succeed, maybe_get_and_pin should fail
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
r = toku_cachetable_maybe_get_and_pin_clean(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin_clean(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r == 0); assert(r == 0);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8)); r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
// maybe_get_and_pin_clean should succeed, maybe_get_and_pin should fail // maybe_get_and_pin_clean should succeed, maybe_get_and_pin should fail
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==0); assert(r==0);
// now these calls should fail because the node is already pinned, and therefore in use // now these calls should fail because the node is already pinned, and therefore in use
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
r = toku_cachetable_maybe_get_and_pin_clean(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin_clean(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8)); r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
// sanity check, this should still succeed, because the PAIR is dirty // sanity check, this should still succeed, because the PAIR is dirty
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==0); assert(r==0);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8)); r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct); CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
toku_cachetable_begin_checkpoint(cp, NULL); toku_cachetable_begin_checkpoint(cp, NULL);
// now these should fail, because the node should be pending a checkpoint // now these should fail, because the node should be pending a checkpoint
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, PL_WRITE_EXPENSIVE, &v1);
assert(r==-1); assert(r==-1);
toku_cachetable_end_checkpoint( toku_cachetable_end_checkpoint(
cp, cp,
......
...@@ -105,7 +105,7 @@ static void test_nested_pin (void) { ...@@ -105,7 +105,7 @@ static void test_nested_pin (void) {
assert(i0==0); assert(i0==0);
r = toku_test_cachetable_unpin(f, make_blocknum(1), f1hash, CACHETABLE_CLEAN, make_pair_attr(test_object_size)); r = toku_test_cachetable_unpin(f, make_blocknum(1), f1hash, CACHETABLE_CLEAN, make_pair_attr(test_object_size));
assert(r==0); assert(r==0);
r = toku_cachetable_maybe_get_and_pin(f, make_blocknum(1), f1hash, &vv2); r = toku_cachetable_maybe_get_and_pin(f, make_blocknum(1), f1hash, PL_WRITE_EXPENSIVE, &vv2);
assert(r==0); assert(r==0);
assert(vv2==vv); assert(vv2==vv);
r = toku_test_cachetable_unpin(f, make_blocknum(1), f1hash, CACHETABLE_CLEAN, make_pair_attr(test_object_size)); r = toku_test_cachetable_unpin(f, make_blocknum(1), f1hash, CACHETABLE_CLEAN, make_pair_attr(test_object_size));
......
...@@ -63,7 +63,7 @@ cachetable_unpin_and_remove_test (int n) { ...@@ -63,7 +63,7 @@ cachetable_unpin_and_remove_test (int n) {
// verify that k is removed // verify that k is removed
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(testkeys[i].b), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(testkeys[i].b), hi, PL_WRITE_EXPENSIVE, &v);
assert(r != 0); assert(r != 0);
testkeys[i] = testkeys[nkeys-1]; nkeys -= 1; testkeys[i] = testkeys[nkeys-1]; nkeys -= 1;
......
...@@ -27,7 +27,7 @@ cachetable_unpin_test (int n) { ...@@ -27,7 +27,7 @@ cachetable_unpin_test (int n) {
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, PL_WRITE_EXPENSIVE, &v);
assert(r == -1); assert(r == -1);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#ident "Copyright (c) 2007-2012 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007-2012 Tokutek Inc. All rights reserved."
#include "includes.h" #include "includes.h"
#include "test.h" #include "test.h"
#include <portability/toku_atomic.h>
static int total_size; static int total_size;
...@@ -25,7 +26,7 @@ flush (CACHEFILE f __attribute__((__unused__)), ...@@ -25,7 +26,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
bool UU(is_clone) bool UU(is_clone)
) { ) {
if (w) { if (w) {
int curr_size = __sync_fetch_and_sub(&total_size, 1); int curr_size = toku_sync_fetch_and_sub(&total_size, 1);
assert(curr_size <= 200); assert(curr_size <= 200);
usleep(500*1000); usleep(500*1000);
} }
...@@ -49,7 +50,7 @@ cachetable_test (void) { ...@@ -49,7 +50,7 @@ cachetable_test (void) {
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL); CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
wc.flush_callback = flush; wc.flush_callback = flush;
toku_cachetable_put(f1, make_blocknum(i), i, NULL, make_pair_attr(1), wc, put_callback_nop); toku_cachetable_put(f1, make_blocknum(i), i, NULL, make_pair_attr(1), wc, put_callback_nop);
int curr_size = __sync_fetch_and_add(&total_size, 1); int curr_size = toku_sync_fetch_and_add(&total_size, 1);
assert(curr_size <= test_limit + test_limit/2+1); assert(curr_size <= test_limit + test_limit/2+1);
r = toku_test_cachetable_unpin(f1, make_blocknum(i), i, CACHETABLE_DIRTY, make_pair_attr(4)); r = toku_test_cachetable_unpin(f1, make_blocknum(i), i, CACHETABLE_DIRTY, make_pair_attr(4));
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef FTLOADER_ERROR_INJECTOR_H #ifndef FTLOADER_ERROR_INJECTOR_H
#define FTLOADER_ERROR_INJECTOR_H #define FTLOADER_ERROR_INJECTOR_H
#include <portability/toku_atomic.h>
static toku_mutex_t event_mutex = TOKU_MUTEX_INITIALIZER; static toku_mutex_t event_mutex = TOKU_MUTEX_INITIALIZER;
static void lock_events(void) { static void lock_events(void) {
...@@ -107,9 +108,9 @@ static void reset_my_malloc_counts(void) { ...@@ -107,9 +108,9 @@ static void reset_my_malloc_counts(void) {
__attribute__((__unused__)) __attribute__((__unused__))
static void *my_malloc(size_t n) { static void *my_malloc(size_t n) {
(void) __sync_fetch_and_add(&my_malloc_count, 1); // my_malloc_count++; (void) toku_sync_fetch_and_add(&my_malloc_count, 1); // my_malloc_count++;
if (n >= my_big_malloc_limit) { if (n >= my_big_malloc_limit) {
(void) __sync_fetch_and_add(&my_big_malloc_count, 1); // my_big_malloc_count++; (void) toku_sync_fetch_and_add(&my_big_malloc_count, 1); // my_big_malloc_count++;
if (do_malloc_errors) { if (do_malloc_errors) {
if (event_add_and_fetch() == event_count_trigger) { if (event_add_and_fetch() == event_count_trigger) {
event_hit(); event_hit();
...@@ -125,9 +126,9 @@ static int do_realloc_errors = 0; ...@@ -125,9 +126,9 @@ static int do_realloc_errors = 0;
__attribute__((__unused__)) __attribute__((__unused__))
static void *my_realloc(void *p, size_t n) { static void *my_realloc(void *p, size_t n) {
(void) __sync_fetch_and_add(&my_realloc_count, 1); // my_realloc_count++; (void) toku_sync_fetch_and_add(&my_realloc_count, 1); // my_realloc_count++;
if (n >= my_big_malloc_limit) { if (n >= my_big_malloc_limit) {
(void) __sync_fetch_and_add(&my_big_realloc_count, 1); // my_big_realloc_count++; (void) toku_sync_fetch_and_add(&my_big_realloc_count, 1); // my_big_realloc_count++;
if (do_realloc_errors) { if (do_realloc_errors) {
if (event_add_and_fetch() == event_count_trigger) { if (event_add_and_fetch() == event_count_trigger) {
event_hit(); event_hit();
......
...@@ -82,8 +82,8 @@ static void test_keyrange (enum memory_state ms, uint64_t limit) { ...@@ -82,8 +82,8 @@ static void test_keyrange (enum memory_state ms, uint64_t limit) {
struct ftstat64_s s; struct ftstat64_s s;
toku_ft_handle_stat64(t, null_txn, &s); toku_ft_handle_stat64(t, null_txn, &s);
assert(0 < s.nkeys && s.nkeys < limit); assert(0 < s.nkeys && s.nkeys <= limit);
assert(0 < s.dsize && s.dsize < limit * (9 + 9)); // keylen = 9, vallen = 9 assert(0 < s.dsize && s.dsize <= limit * (9 + 9)); // keylen = 9, vallen = 9
} }
maybe_reopen(ms, limit); maybe_reopen(ms, limit);
......
...@@ -138,7 +138,7 @@ test_make_tree(int height, int fanout, int nperleaf, int do_verify) { ...@@ -138,7 +138,7 @@ test_make_tree(int height, int fanout, int nperleaf, int do_verify) {
// set the new root to point to the new tree // set the new root to point to the new tree
toku_ft_set_new_root_blocknum(brt->ft, newroot->thisnodename); toku_ft_set_new_root_blocknum(brt->ft, newroot->thisnodename);
newroot->max_msn_applied_to_node_on_disk = last_dummymsn(); // capture msn of last message injected into tree brt->ft->h->max_msn_in_ft = last_dummymsn(); // capture msn of last message injected into tree
// unpin the new root // unpin the new root
toku_unpin_ftnode(brt->ft, newroot); toku_unpin_ftnode(brt->ft, newroot);
......
...@@ -45,10 +45,10 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va ...@@ -45,10 +45,10 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va
// apply an insert to the leaf node // apply an insert to the leaf node
MSN msn = next_dummymsn(); MSN msn = next_dummymsn();
brt->ft->h->max_msn_in_ft = msn;
FT_MSG_S cmd = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &theval }} }; FT_MSG_S cmd = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &theval }} };
uint64_t workdone=0; toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, -1, &cmd, nullptr, nullptr);
toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, &cmd, &workdone, NULL);
{ {
int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair); int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair);
assert(r==0); assert(r==0);
...@@ -56,9 +56,8 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va ...@@ -56,9 +56,8 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va
} }
FT_MSG_S badcmd = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &badval }} }; FT_MSG_S badcmd = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &badval }} };
toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, &badcmd, &workdone, NULL); toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, -1, &badcmd, nullptr, nullptr);
// message should be rejected for duplicate msn, row should still have original val // message should be rejected for duplicate msn, row should still have original val
{ {
int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair); int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair);
...@@ -68,9 +67,10 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va ...@@ -68,9 +67,10 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va
// now verify that message with proper msn gets through // now verify that message with proper msn gets through
msn = next_dummymsn(); msn = next_dummymsn();
brt->ft->h->max_msn_in_ft = msn;
FT_MSG_S cmd2 = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &val2 }} }; FT_MSG_S cmd2 = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &val2 }} };
toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, &cmd2, &workdone, NULL); toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, -1, &cmd2, nullptr, nullptr);
// message should be accepted, val should have new value // message should be accepted, val should have new value
{ {
int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair2); int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair2);
...@@ -81,8 +81,8 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va ...@@ -81,8 +81,8 @@ append_leaf(FT_HANDLE brt, FTNODE leafnode, void *key, uint32_t keylen, void *va
// now verify that message with lesser (older) msn is rejected // now verify that message with lesser (older) msn is rejected
msn.msn = msn.msn - 10; msn.msn = msn.msn - 10;
FT_MSG_S cmd3 = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &badval } }}; FT_MSG_S cmd3 = { FT_INSERT, msn, xids_get_root_xids(), .u={.id = { &thekey, &badval } }};
toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, &cmd3, &workdone, NULL); toku_ft_leaf_apply_cmd(brt->ft->compare_fun, brt->ft->update_fun, &brt->ft->cmp_descriptor, leafnode, -1, &cmd3, nullptr, nullptr);
// message should be rejected, val should still have value in pair2 // message should be rejected, val should still have value in pair2
{ {
int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair2); int r = toku_ft_lookup(brt, &thekey, lookup_checkf, &pair2);
......
...@@ -580,7 +580,7 @@ flush_to_leaf(FT_HANDLE t, bool make_leaf_up_to_date, bool use_flush) { ...@@ -580,7 +580,7 @@ flush_to_leaf(FT_HANDLE t, bool make_leaf_up_to_date, bool use_flush) {
if (make_leaf_up_to_date) { if (make_leaf_up_to_date) {
for (i = 0; i < num_parent_messages; ++i) { for (i = 0; i < num_parent_messages; ++i) {
if (!parent_messages_is_fresh[i]) { if (!parent_messages_is_fresh[i]) {
toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child, parent_messages[i], NULL, NULL); toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child, -1, parent_messages[i], NULL, NULL);
} }
} }
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
...@@ -803,7 +803,7 @@ flush_to_leaf_with_keyrange(FT_HANDLE t, bool make_leaf_up_to_date) { ...@@ -803,7 +803,7 @@ flush_to_leaf_with_keyrange(FT_HANDLE t, bool make_leaf_up_to_date) {
for (i = 0; i < num_parent_messages; ++i) { for (i = 0; i < num_parent_messages; ++i) {
if (dummy_cmp(NULL, parent_messages[i]->u.id.key, &childkeys[7]) <= 0 && if (dummy_cmp(NULL, parent_messages[i]->u.id.key, &childkeys[7]) <= 0 &&
!parent_messages_is_fresh[i]) { !parent_messages_is_fresh[i]) {
toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child, parent_messages[i], NULL, NULL); toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child, -1, parent_messages[i], NULL, NULL);
} }
} }
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
...@@ -995,8 +995,8 @@ compare_apply_and_flush(FT_HANDLE t, bool make_leaf_up_to_date) { ...@@ -995,8 +995,8 @@ compare_apply_and_flush(FT_HANDLE t, bool make_leaf_up_to_date) {
if (make_leaf_up_to_date) { if (make_leaf_up_to_date) {
for (i = 0; i < num_parent_messages; ++i) { for (i = 0; i < num_parent_messages; ++i) {
if (!parent_messages_is_fresh[i]) { if (!parent_messages_is_fresh[i]) {
toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child1, parent_messages[i], NULL, NULL); toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child1, -1, parent_messages[i], NULL, NULL);
toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child2, parent_messages[i], NULL, NULL); toku_ft_leaf_apply_cmd(t->ft->compare_fun, t->ft->update_fun, &t->ft->descriptor, child2, -1, parent_messages[i], NULL, NULL);
} }
} }
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
......
...@@ -228,7 +228,8 @@ static UU() CACHETABLE_WRITE_CALLBACK def_write_callback(void* write_extraargs) ...@@ -228,7 +228,8 @@ static UU() CACHETABLE_WRITE_CALLBACK def_write_callback(void* write_extraargs)
wc.pe_callback = def_pe_callback; wc.pe_callback = def_pe_callback;
wc.cleaner_callback = def_cleaner_callback; wc.cleaner_callback = def_cleaner_callback;
wc.write_extraargs = write_extraargs; wc.write_extraargs = write_extraargs;
wc.clone_callback = NULL; wc.clone_callback = nullptr;
wc.checkpoint_complete_callback = nullptr;
return wc; return wc;
} }
......
...@@ -171,7 +171,7 @@ test_split_on_boundary(void) ...@@ -171,7 +171,7 @@ test_split_on_boundary(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
verify_basement_node_msns(nodea, dummy_msn_3884); verify_basement_node_msns(nodea, dummy_msn_3884);
verify_basement_node_msns(nodeb, dummy_msn_3884); verify_basement_node_msns(nodeb, dummy_msn_3884);
...@@ -244,7 +244,7 @@ test_split_with_everything_on_the_left(void) ...@@ -244,7 +244,7 @@ test_split_with_everything_on_the_left(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
toku_unpin_ftnode(brt->ft, nodeb); toku_unpin_ftnode(brt->ft, nodeb);
r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0); r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0);
...@@ -319,7 +319,7 @@ test_split_on_boundary_of_last_node(void) ...@@ -319,7 +319,7 @@ test_split_on_boundary_of_last_node(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
toku_unpin_ftnode(brt->ft, nodeb); toku_unpin_ftnode(brt->ft, nodeb);
r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0); r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0);
...@@ -387,7 +387,7 @@ test_split_at_begin(void) ...@@ -387,7 +387,7 @@ test_split_at_begin(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
toku_unpin_ftnode(brt->ft, nodeb); toku_unpin_ftnode(brt->ft, nodeb);
r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0); r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0);
...@@ -451,7 +451,7 @@ test_split_at_end(void) ...@@ -451,7 +451,7 @@ test_split_at_end(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
toku_unpin_ftnode(brt->ft, nodeb); toku_unpin_ftnode(brt->ft, nodeb);
r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0); r = toku_close_ft_handle_nolsn(brt, NULL); assert(r == 0);
...@@ -505,7 +505,7 @@ test_split_odd_nodes(void) ...@@ -505,7 +505,7 @@ test_split_odd_nodes(void)
FTNODE nodea, nodeb; FTNODE nodea, nodeb;
DBT splitk; DBT splitk;
// if we haven't done it right, we should hit the assert in the top of move_leafentries // if we haven't done it right, we should hit the assert in the top of move_leafentries
ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, 0, NULL); ftleaf_split(brt->ft, &sn, &nodea, &nodeb, &splitk, true, SPLIT_EVENLY, 0, NULL);
verify_basement_node_msns(nodea, dummy_msn_3884); verify_basement_node_msns(nodea, dummy_msn_3884);
verify_basement_node_msns(nodeb, dummy_msn_3884); verify_basement_node_msns(nodeb, dummy_msn_3884);
......
...@@ -60,10 +60,10 @@ void test_msg_modify_ule(ULE ule, FT_MSG msg); ...@@ -60,10 +60,10 @@ void test_msg_modify_ule(ULE ule, FT_MSG msg);
//Functions exported for test purposes only (used internally for non-test purposes). //Functions exported for test purposes only (used internally for non-test purposes).
void le_unpack(ULE ule, LEAFENTRY le); void le_unpack(ULE ule, LEAFENTRY le);
int le_pack(ULE ule, // data to be packed into new leafentry int le_pack(ULE ule, // data to be packed into new leafentry
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY * const new_leafentry_p, // this is what this function creates LEAFENTRY * const new_leafentry_p, // this is what this function creates
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free); void **maybe_free);
......
...@@ -154,11 +154,11 @@ static inline size_t uxr_unpack_length_and_bit(UXR uxr, uint8_t *p); ...@@ -154,11 +154,11 @@ static inline size_t uxr_unpack_length_and_bit(UXR uxr, uint8_t *p);
static inline size_t uxr_unpack_data(UXR uxr, uint8_t *p); static inline size_t uxr_unpack_data(UXR uxr, uint8_t *p);
static void * static void *
le_malloc(OMT omt, struct mempool *mp, size_t size, void **maybe_free) le_malloc(OMT *omtp, struct mempool *mp, size_t size, void **maybe_free)
{ {
void * rval; void * rval;
if (omt) if (omtp)
rval = mempool_malloc_from_omt(omt, mp, size, maybe_free); rval = mempool_malloc_from_omt(omtp, mp, size, maybe_free);
else else
rval = toku_xmalloc(size); rval = toku_xmalloc(size);
resource_assert(rval); resource_assert(rval);
...@@ -317,14 +317,14 @@ done:; ...@@ -317,14 +317,14 @@ done:;
// If the leafentry is destroyed it sets *new_leafentry_p to NULL. // If the leafentry is destroyed it sets *new_leafentry_p to NULL.
// Otehrwise the new_leafentry_p points at the new leaf entry. // Otehrwise the new_leafentry_p points at the new leaf entry.
// As of October 2011, this function always returns 0. // As of October 2011, this function always returns 0.
int int
apply_msg_to_leafentry(FT_MSG msg, // message to apply to leafentry apply_msg_to_leafentry(FT_MSG msg, // message to apply to leafentry
LEAFENTRY old_leafentry, // NULL if there was no stored data. LEAFENTRY old_leafentry, // NULL if there was no stored data.
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY *new_leafentry_p, LEAFENTRY *new_leafentry_p,
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free, void **maybe_free,
int64_t * numbytes_delta_p) { // change in total size of key and val, not including any overhead int64_t * numbytes_delta_p) { // change in total size of key and val, not including any overhead
ULE_S ule; ULE_S ule;
int rval; int rval;
...@@ -334,17 +334,17 @@ apply_msg_to_leafentry(FT_MSG msg, // message to apply to leafentry ...@@ -334,17 +334,17 @@ apply_msg_to_leafentry(FT_MSG msg, // message to apply to leafentry
if (old_leafentry == NULL) // if leafentry does not exist ... if (old_leafentry == NULL) // if leafentry does not exist ...
msg_init_empty_ule(&ule, msg); // ... create empty unpacked leaf entry msg_init_empty_ule(&ule, msg); // ... create empty unpacked leaf entry
else { else {
le_unpack(&ule, old_leafentry); // otherwise unpack leafentry le_unpack(&ule, old_leafentry); // otherwise unpack leafentry
oldnumbytes = ule_get_innermost_numbytes(&ule); oldnumbytes = ule_get_innermost_numbytes(&ule);
} }
msg_modify_ule(&ule, msg); // modify unpacked leafentry msg_modify_ule(&ule, msg); // modify unpacked leafentry
rval = le_pack(&ule, // create packed leafentry rval = le_pack(&ule, // create packed leafentry
new_leafentry_memorysize, new_leafentry_memorysize,
new_leafentry_p, new_leafentry_p,
omt, omtp,
mp, mp,
maybe_free); maybe_free);
if (new_leafentry_p) if (new_leafentry_p)
newnumbytes = ule_get_innermost_numbytes(&ule); newnumbytes = ule_get_innermost_numbytes(&ule);
*numbytes_delta_p = newnumbytes - oldnumbytes; *numbytes_delta_p = newnumbytes - oldnumbytes;
ule_cleanup(&ule); ule_cleanup(&ule);
...@@ -374,7 +374,7 @@ int ...@@ -374,7 +374,7 @@ int
garbage_collect_leafentry(LEAFENTRY old_leaf_entry, garbage_collect_leafentry(LEAFENTRY old_leaf_entry,
LEAFENTRY *new_leaf_entry, LEAFENTRY *new_leaf_entry,
size_t *new_leaf_entry_memory_size, size_t *new_leaf_entry_memory_size,
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free, void **maybe_free,
const xid_omt_t &snapshot_xids, const xid_omt_t &snapshot_xids,
...@@ -387,7 +387,7 @@ garbage_collect_leafentry(LEAFENTRY old_leaf_entry, ...@@ -387,7 +387,7 @@ garbage_collect_leafentry(LEAFENTRY old_leaf_entry,
r = le_pack(&ule, r = le_pack(&ule,
new_leaf_entry_memory_size, new_leaf_entry_memory_size,
new_leaf_entry, new_leaf_entry,
omt, omtp,
mp, mp,
maybe_free); maybe_free);
assert(r == 0); assert(r == 0);
...@@ -713,8 +713,8 @@ int ...@@ -713,8 +713,8 @@ int
le_pack(ULE ule, // data to be packed into new leafentry le_pack(ULE ule, // data to be packed into new leafentry
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY * const new_leafentry_p, // this is what this function creates LEAFENTRY * const new_leafentry_p, // this is what this function creates
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free) void **maybe_free)
{ {
invariant(ule->num_cuxrs > 0); invariant(ule->num_cuxrs > 0);
...@@ -740,7 +740,7 @@ le_pack(ULE ule, // data to be packed into new leafen ...@@ -740,7 +740,7 @@ le_pack(ULE ule, // data to be packed into new leafen
found_insert:; found_insert:;
memsize = le_memsize_from_ule(ule); memsize = le_memsize_from_ule(ule);
LEAFENTRY new_leafentry; LEAFENTRY new_leafentry;
CAST_FROM_VOIDP(new_leafentry, le_malloc(omt, mp, memsize, maybe_free)); CAST_FROM_VOIDP(new_leafentry, le_malloc(omtp, mp, memsize, maybe_free));
//Universal data //Universal data
new_leafentry->keylen = toku_htod32(ule->keylen); new_leafentry->keylen = toku_htod32(ule->keylen);
...@@ -2293,7 +2293,7 @@ int ...@@ -2293,7 +2293,7 @@ int
toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry,
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY *new_leafentry_p, LEAFENTRY *new_leafentry_p,
OMT omt, OMT *omtp,
struct mempool *mp) { struct mempool *mp) {
ULE_S ule; ULE_S ule;
int rval; int rval;
...@@ -2305,7 +2305,7 @@ toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, ...@@ -2305,7 +2305,7 @@ toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry,
rval = le_pack(&ule, // create packed leafentry rval = le_pack(&ule, // create packed leafentry
new_leafentry_memorysize, new_leafentry_memorysize,
new_leafentry_p, new_leafentry_p,
omt, mp, NULL); omtp, mp, NULL);
ule_cleanup(&ule); ule_cleanup(&ule);
return rval; return rval;
} }
......
...@@ -53,18 +53,18 @@ void fast_msg_to_leafentry( ...@@ -53,18 +53,18 @@ void fast_msg_to_leafentry(
LEAFENTRY *new_leafentry_p) ; LEAFENTRY *new_leafentry_p) ;
int apply_msg_to_leafentry(FT_MSG msg, int apply_msg_to_leafentry(FT_MSG msg,
LEAFENTRY old_leafentry, // NULL if there was no stored data. LEAFENTRY old_leafentry, // NULL if there was no stored data.
size_t *new_leafentry_memorysize, size_t *new_leafentry_memorysize,
LEAFENTRY *new_leafentry_p, LEAFENTRY *new_leafentry_p,
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free, void **maybe_free,
int64_t * numbytes_delta_p); int64_t * numbytes_delta_p);
int garbage_collect_leafentry(LEAFENTRY old_leaf_entry, int garbage_collect_leafentry(LEAFENTRY old_leaf_entry,
LEAFENTRY *new_leaf_entry, LEAFENTRY *new_leaf_entry,
size_t *new_leaf_entry_memory_size, size_t *new_leaf_entry_memory_size,
OMT omt, OMT *omtp,
struct mempool *mp, struct mempool *mp,
void **maybe_free, void **maybe_free,
const xid_omt_t &snapshot_xids, const xid_omt_t &snapshot_xids,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <errno.h> #include <errno.h>
#include "threadpool.h" #include "threadpool.h"
#include <portability/toku_atomic.h>
// use gcc builtin fetch_and_add 0->no 1->yes // use gcc builtin fetch_and_add 0->no 1->yes
#define DO_ATOMIC_FETCH_AND_ADD 0 #define DO_ATOMIC_FETCH_AND_ADD 0
...@@ -61,7 +62,7 @@ void threadpool_maybe_add(THREADPOOL threadpool, void *(*f)(void *), void *arg) ...@@ -61,7 +62,7 @@ void threadpool_maybe_add(THREADPOOL threadpool, void *(*f)(void *), void *arg)
void threadpool_set_thread_busy(THREADPOOL threadpool) { void threadpool_set_thread_busy(THREADPOOL threadpool) {
#if DO_ATOMIC_FETCH_AND_ADD #if DO_ATOMIC_FETCH_AND_ADD
(void) __sync_fetch_and_add(&threadpool->busy_threads, 1); (void) toku_sync_fetch_and_add(&threadpool->busy_threads, 1);
#else #else
threadpool->busy_threads++; threadpool->busy_threads++;
#endif #endif
...@@ -69,7 +70,7 @@ void threadpool_set_thread_busy(THREADPOOL threadpool) { ...@@ -69,7 +70,7 @@ void threadpool_set_thread_busy(THREADPOOL threadpool) {
void threadpool_set_thread_idle(THREADPOOL threadpool) { void threadpool_set_thread_idle(THREADPOOL threadpool) {
#if DO_ATOMIC_FETCH_AND_ADD #if DO_ATOMIC_FETCH_AND_ADD
(void) __sync_fetch_and_add(&threadpool->busy_threads, -1); (void) toku_sync_fetch_and_add(&threadpool->busy_threads, -1);
#else #else
threadpool->busy_threads--; threadpool->busy_threads--;
#endif #endif
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "memory.h" #include "memory.h"
#include "toku_time.h" #include "toku_time.h"
#include <portability/toku_atomic.h>
static int toku_assert_on_write_enospc = 0; static int toku_assert_on_write_enospc = 0;
static const int toku_write_enospc_sleep = 1; static const int toku_write_enospc_sleep = 1;
...@@ -60,8 +61,8 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) { ...@@ -60,8 +61,8 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) {
int out_of_disk_space = 1; int out_of_disk_space = 1;
assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives. assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives.
} else { } else {
__sync_fetch_and_add(&toku_write_enospc_total, 1); toku_sync_fetch_and_add(&toku_write_enospc_total, 1);
__sync_fetch_and_add(&toku_write_enospc_current, 1); toku_sync_fetch_and_add(&toku_write_enospc_current, 1);
time_t tnow = time(0); time_t tnow = time(0);
toku_write_enospc_last_time = tnow; toku_write_enospc_last_time = tnow;
...@@ -89,7 +90,7 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) { ...@@ -89,7 +90,7 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) {
} }
sleep(toku_write_enospc_sleep); sleep(toku_write_enospc_sleep);
try_again = 1; try_again = 1;
__sync_fetch_and_sub(&toku_write_enospc_current, 1); toku_sync_fetch_and_sub(&toku_write_enospc_current, 1);
break; break;
} }
} }
...@@ -347,9 +348,9 @@ static void file_fsync_internal (int fd, uint64_t *duration_p) { ...@@ -347,9 +348,9 @@ static void file_fsync_internal (int fd, uint64_t *duration_p) {
assert(get_error_errno() == EINTR); assert(get_error_errno() == EINTR);
} }
} }
__sync_fetch_and_add(&toku_fsync_count, 1); toku_sync_fetch_and_add(&toku_fsync_count, 1);
uint64_t duration = toku_current_time_usec() - tstart; uint64_t duration = toku_current_time_usec() - tstart;
__sync_fetch_and_add(&toku_fsync_time, duration); toku_sync_fetch_and_add(&toku_fsync_time, duration);
if (duration_p) { if (duration_p) {
*duration_p = duration; *duration_p = duration;
} }
...@@ -383,8 +384,8 @@ int toku_fsync_dir_by_name_without_accounting(const char *dir_name) { ...@@ -383,8 +384,8 @@ int toku_fsync_dir_by_name_without_accounting(const char *dir_name) {
void toku_file_fsync(int fd) { void toku_file_fsync(int fd) {
uint64_t duration; uint64_t duration;
file_fsync_internal (fd, &duration); file_fsync_internal (fd, &duration);
__sync_fetch_and_add(&sched_fsync_count, 1); toku_sync_fetch_and_add(&sched_fsync_count, 1);
__sync_fetch_and_add(&sched_fsync_time, duration); toku_sync_fetch_and_add(&sched_fsync_time, duration);
} }
// for real accounting // for real accounting
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <toku_race_tools.h> #include <toku_race_tools.h>
#include "memory.h" #include "memory.h"
#include "toku_assert.h" #include "toku_assert.h"
#include <portability/toku_atomic.h>
static malloc_fun_t t_malloc = 0; static malloc_fun_t t_malloc = 0;
static malloc_fun_t t_xmalloc = 0; static malloc_fun_t t_xmalloc = 0;
...@@ -120,7 +121,7 @@ set_max(uint64_t sum_used, uint64_t sum_freed) { ...@@ -120,7 +121,7 @@ set_max(uint64_t sum_used, uint64_t sum_freed) {
do { do {
old_max = status.max_in_use; old_max = status.max_in_use;
} while (old_max < in_use && } while (old_max < in_use &&
!__sync_bool_compare_and_swap(&status.max_in_use, old_max, in_use)); !toku_sync_bool_compare_and_swap(&status.max_in_use, old_max, in_use));
} }
} }
...@@ -150,13 +151,13 @@ toku_malloc(size_t size) { ...@@ -150,13 +151,13 @@ toku_malloc(size_t size) {
TOKU_ANNOTATE_NEW_MEMORY(p, size); // see #4671 and https://bugs.kde.org/show_bug.cgi?id=297147 TOKU_ANNOTATE_NEW_MEMORY(p, size); // see #4671 and https://bugs.kde.org/show_bug.cgi?id=297147
if (toku_memory_do_stats) { if (toku_memory_do_stats) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&status.malloc_count, 1); toku_sync_add_and_fetch(&status.malloc_count, 1);
__sync_add_and_fetch(&status.requested,size); toku_sync_add_and_fetch(&status.requested,size);
__sync_add_and_fetch(&status.used, used); toku_sync_add_and_fetch(&status.used, used);
set_max(status.used, status.freed); set_max(status.used, status.freed);
} }
} else { } else {
__sync_add_and_fetch(&status.malloc_fail, 1); toku_sync_add_and_fetch(&status.malloc_fail, 1);
} }
return p; return p;
} }
...@@ -176,14 +177,14 @@ toku_realloc(void *p, size_t size) { ...@@ -176,14 +177,14 @@ toku_realloc(void *p, size_t size) {
if (q) { if (q) {
if (toku_memory_do_stats) { if (toku_memory_do_stats) {
size_t used = my_malloc_usable_size(q); size_t used = my_malloc_usable_size(q);
__sync_add_and_fetch(&status.realloc_count, 1); toku_sync_add_and_fetch(&status.realloc_count, 1);
__sync_add_and_fetch(&status.requested, size); toku_sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); toku_sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&status.freed, used_orig); toku_sync_add_and_fetch(&status.freed, used_orig);
set_max(status.used, status.freed); set_max(status.used, status.freed);
} }
} else { } else {
__sync_add_and_fetch(&status.realloc_fail, 1); toku_sync_add_and_fetch(&status.realloc_fail, 1);
} }
return q; return q;
} }
...@@ -205,8 +206,8 @@ toku_free(void *p) { ...@@ -205,8 +206,8 @@ toku_free(void *p) {
if (p) { if (p) {
if (toku_memory_do_stats) { if (toku_memory_do_stats) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&status.free_count, 1); toku_sync_add_and_fetch(&status.free_count, 1);
__sync_add_and_fetch(&status.freed, used); toku_sync_add_and_fetch(&status.freed, used);
} }
if (t_free) if (t_free)
t_free(p); t_free(p);
...@@ -228,9 +229,9 @@ toku_xmalloc(size_t size) { ...@@ -228,9 +229,9 @@ toku_xmalloc(size_t size) {
TOKU_ANNOTATE_NEW_MEMORY(p, size); // see #4671 and https://bugs.kde.org/show_bug.cgi?id=297147 TOKU_ANNOTATE_NEW_MEMORY(p, size); // see #4671 and https://bugs.kde.org/show_bug.cgi?id=297147
if (toku_memory_do_stats) { if (toku_memory_do_stats) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&status.malloc_count, 1); toku_sync_add_and_fetch(&status.malloc_count, 1);
__sync_add_and_fetch(&status.requested, size); toku_sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); toku_sync_add_and_fetch(&status.used, used);
set_max(status.used, status.freed); set_max(status.used, status.freed);
} }
return p; return p;
...@@ -252,10 +253,10 @@ toku_xrealloc(void *v, size_t size) { ...@@ -252,10 +253,10 @@ toku_xrealloc(void *v, size_t size) {
resource_assert(p); resource_assert(p);
if (toku_memory_do_stats) { if (toku_memory_do_stats) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&status.realloc_count, 1); toku_sync_add_and_fetch(&status.realloc_count, 1);
__sync_add_and_fetch(&status.requested, size); toku_sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); toku_sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&status.freed, used_orig); toku_sync_add_and_fetch(&status.freed, used_orig);
set_max(status.used, status.freed); set_max(status.used, status.freed);
} }
return p; return p;
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "toku_os.h" #include "toku_os.h"
#include "toku_time.h" #include "toku_time.h"
#include "memory.h" #include "memory.h"
#include <portability/toku_atomic.h>
#include <util/partitioned_counter.h> #include <util/partitioned_counter.h>
int int
......
...@@ -5,6 +5,7 @@ if(BUILD_TESTING) ...@@ -5,6 +5,7 @@ if(BUILD_TESTING)
file(GLOB srcs RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cc) file(GLOB srcs RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cc)
foreach(src ${srcs}) foreach(src ${srcs})
get_filename_component(base ${src} NAME_WE) get_filename_component(base ${src} NAME_WE)
set_property(SOURCE ${src} APPEND PROPERTY COMPILE_DEFINITIONS "__SRCFILE__=\"${CMAKE_CURRENT_SOURCE_DIR}/${src}\"")
list(APPEND tests ${base}) list(APPEND tests ${base})
endforeach(src) endforeach(src)
......
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
#ident "Copyright (c) 2007-2012 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#include <config.h>
#include <memory.h>
#include <portability/toku_atomic.h>
#include "test.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int verbose = 0;
static const size_t cachelinesize = 64;
// cache line is 64 bytes
// nine 7-byte structs fill 63 bytes
// the tenth spans one byte of the first cache line and six of the next cache line
// we first SFAA the first 9 structs and ensure we don't crash, then we set a signal handler and SFAA the 10th and ensure we do crash
struct unpackedsevenbytestruct {
uint32_t i;
char pad[3];
};
struct __attribute__((packed)) packedsevenbytestruct {
uint32_t i;
char pad[3];
};
struct packedsevenbytestruct *psevenbytestructs;
static __attribute__((__noreturn__)) void catch_abort (int sig __attribute__((__unused__))) {
toku_free(psevenbytestructs);
#ifdef TOKU_DEBUG_PARANOID
exit(EXIT_SUCCESS); // with paranoid asserts, we expect to assert and reach this handler
#else
exit(EXIT_FAILURE); // we should not have crashed without paranoid asserts
#endif
}
int test_main(int UU(argc), char *const argv[] UU()) {
if (sizeof(unpackedsevenbytestruct) != 8) {
exit(EXIT_FAILURE);
}
if (sizeof(packedsevenbytestruct) != 7) {
exit(EXIT_FAILURE);
}
{
struct unpackedsevenbytestruct *usevenbytestructs;
int r = posix_memalign((void **) &usevenbytestructs, cachelinesize, sizeof(unpackedsevenbytestruct) * 10);
if (r) {
// this test is supposed to crash, so exiting cleanly is a failure
perror("posix_memalign");
exit(EXIT_FAILURE);
}
for (int idx = 0; idx < 10; ++idx) {
usevenbytestructs[idx].i = idx + 1;
(void) toku_sync_fetch_and_add(&usevenbytestructs[idx].i, 32U - idx);
}
toku_free(usevenbytestructs);
}
int r = posix_memalign((void **) &psevenbytestructs, cachelinesize, sizeof(packedsevenbytestruct) * 10);
if (r) {
// this test is supposed to crash, so exiting cleanly is a failure
perror("posix_memalign");
exit(EXIT_FAILURE);
}
for (int idx = 0; idx < 9; ++idx) {
psevenbytestructs[idx].i = idx + 1;
(void) toku_sync_fetch_and_add(&psevenbytestructs[idx].i, 32U - idx);
}
psevenbytestructs[9].i = 10;
signal(SIGABRT, catch_abort);
(void) toku_sync_fetch_and_add(&psevenbytestructs[9].i, 32U);
#ifdef TOKU_DEBUG_PARANOID
exit(EXIT_FAILURE); // with paranoid asserts, we should already have crashed
#else
exit(EXIT_SUCCESS); // without them, we should make it here
#endif
}
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <errno.h> #include <errno.h>
#include <util/rwlock.h> #include <util/rwlock.h>
#include <util/frwlock.h> #include <util/frwlock.h>
#include <portability/toku_atomic.h>
#include "toku_fair_rwlock.h" #include "toku_fair_rwlock.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -138,8 +139,8 @@ void time_cas (void) { ...@@ -138,8 +139,8 @@ void time_cas (void) {
for (int t=0; t<T; t++) { for (int t=0; t<T; t++) {
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
{ int r = __sync_val_compare_and_swap(&myval, 0, 1); assert(r==0); } { int r = toku_sync_val_compare_and_swap(&myval, 0, 1); assert(r==0); }
{ int r = __sync_val_compare_and_swap(&myval, 1, 0); assert(r==1); } { int r = toku_sync_val_compare_and_swap(&myval, 1, 0); assert(r==1); }
} }
gettimeofday(&end, NULL); gettimeofday(&end, NULL);
double diff = 1e9*toku_tdiff(&end, &start)/N; double diff = 1e9*toku_tdiff(&end, &start)/N;
...@@ -325,7 +326,7 @@ static int log_counter=0; ...@@ -325,7 +326,7 @@ static int log_counter=0;
static void logit (int threadid, int loopid, char action) { static void logit (int threadid, int loopid, char action) {
//printf("%d %d %c\n", threadid, loopid, action); //printf("%d %d %c\n", threadid, loopid, action);
int my_log_counter = __sync_fetch_and_add(&log_counter, 1); int my_log_counter = toku_sync_fetch_and_add(&log_counter, 1);
assert(my_log_counter<N_LOG_ENTRIES); assert(my_log_counter<N_LOG_ENTRIES);
actionlog[my_log_counter].threadid = threadid; actionlog[my_log_counter].threadid = threadid;
actionlog[my_log_counter].loopid = loopid; actionlog[my_log_counter].loopid = loopid;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "test.h" #include "test.h"
static size_t max(size_t a, size_t b) { static inline size_t max(size_t a, size_t b) {
return a > b ? a : b; return a > b ? a : b;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment