diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-06-04 17:05:36 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-06-04 17:05:36 +1000 |
commit | 953b622700125746202c116452638e0181db9165 (patch) | |
tree | bc03d820966af3cc87a2181137df6374ab7faacc /src/support | |
parent | d20711f22bad7fcd401367977d883cd1bba9c017 (diff) | |
parent | 97cb94c0ccdf8e4554e4b233271f9ba219fee811 (diff) | |
download | mongo-953b622700125746202c116452638e0181db9165.tar.gz |
Merge branch 'develop'
Diffstat (limited to 'src/support')
-rw-r--r-- | src/support/err.c | 294 | ||||
-rw-r--r-- | src/support/global.c | 2 | ||||
-rw-r--r-- | src/support/hazard.c | 65 | ||||
-rw-r--r-- | src/support/hex.c | 34 | ||||
-rw-r--r-- | src/support/huffman.c | 14 | ||||
-rw-r--r-- | src/support/scratch.c | 62 | ||||
-rw-r--r-- | src/support/sess_dump.c | 22 | ||||
-rw-r--r-- | src/support/stat.c | 7 |
8 files changed, 362 insertions, 138 deletions
diff --git a/src/support/err.c b/src/support/err.c index aac2f8ab3ea..53ff89829f2 100644 --- a/src/support/err.c +++ b/src/support/err.c @@ -8,19 +8,125 @@ #include "wt_internal.h" /* - * __wt_eventv -- - * Report a message to an event handler. + * __handle_error_default -- + * Default WT_EVENT_HANDLER->handle_error implementation: send to stderr. + */ +static int +__handle_error_default(WT_EVENT_HANDLER *handler, int error, const char *errmsg) +{ + WT_UNUSED(handler); + WT_UNUSED(error); + + return (fprintf(stderr, "%s\n", errmsg) >= 0 ? 0 : EIO); +} + +/* + * __handle_message_default -- + * Default WT_EVENT_HANDLER->handle_message implementation: send to stdout. + */ +static int +__handle_message_default(WT_EVENT_HANDLER *handler, const char *message) +{ + WT_UNUSED(handler); + + return (printf("%s\n", message) >= 0 ? 0 : EIO); +} + +/* + * __handle_progress_default -- + * Default WT_EVENT_HANDLER->handle_progress implementation: ignore. + */ +static int +__handle_progress_default( + WT_EVENT_HANDLER *handler, const char *operation, uint64_t progress) +{ + WT_UNUSED(handler); + WT_UNUSED(operation); + WT_UNUSED(progress); + + return (0); +} + +static WT_EVENT_HANDLER __event_handler_default = { + __handle_error_default, + __handle_message_default, + __handle_progress_default +}; + +/* + * __handler_failure -- + * Report the failure of an application-configured event handler. + */ +static void +__handler_failure(WT_SESSION_IMPL *session, + int error, const char *which, int error_handler_failed) +{ + WT_EVENT_HANDLER *handler; + + /* + * !!! + * SECURITY: + * Buffer placed at the end of the stack in case snprintf overflows. + */ + char s[256]; + + (void)snprintf(s, sizeof(s), + "application %s event handler failed: %s", + which, wiredtiger_strerror(error)); + + /* + * Use the error handler to report the failure, unless it was the error + * handler that failed. If it was the error handler that failed, or a + * call to the error handler fails, use the default error handler. + */ + handler = session->event_handler; + if (!error_handler_failed && + handler->handle_error != __handle_error_default && + handler->handle_error(handler, error, s) == 0) + return; + + (void)__handle_error_default(NULL, error, s); +} + +/* + * __wt_event_handler_set -- + * Set an event handler, fill in any NULL methods with the defaults. */ void -__wt_eventv(WT_SESSION_IMPL *session, int msg_event, - int error, +__wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler) +{ + if (handler == NULL) + handler = &__event_handler_default; + else { + if (handler->handle_error == NULL) + handler->handle_error = __handle_error_default; + if (handler->handle_message == NULL) + handler->handle_message = __handle_message_default; + if (handler->handle_progress == NULL) + handler->handle_progress = __handle_progress_default; + } + + session->event_handler = handler; +} + +/* + * __eventv -- + * Report a message to an event handler. + */ +static int +__eventv(WT_SESSION_IMPL *session, int msg_event, int error, const char *file_name, int line_number, const char *fmt, va_list ap) { WT_EVENT_HANDLER *handler; - const char *prefix1, *prefix2; + WT_DECL_RET; + size_t len, remain, wlen; + const char *err, *prefix1, *prefix2; char *end, *p; /* + * We're using a stack buffer because we want error messages no matter + * what, and allocating a WT_ITEM, or the memory it needs, might fail. + * * !!! * SECURITY: * Buffer placed at the end of the stack in case snprintf overflows. @@ -33,27 +139,74 @@ __wt_eventv(WT_SESSION_IMPL *session, int msg_event, prefix1 = (session->btree != NULL) ? session->btree->name : NULL; prefix2 = session->name; - if (prefix1 != NULL && prefix2 != NULL && p < end) - p += snprintf(p, (size_t)(end - p), - "%s [%s]: ", prefix1, prefix2); - else if (prefix1 != NULL && p < end) - p += snprintf(p, (size_t)(end - p), "%s: ", prefix1); - else if (prefix2 != NULL && p < end) - p += snprintf(p, (size_t)(end - p), "%s: ", prefix2); - if (file_name != NULL && p < end) - p += snprintf(p, (size_t)(end - p), - "%s, %d: ", file_name, line_number); - if (p < end) - p += vsnprintf(p, (size_t)(end - p), fmt, ap); - if (error != 0 && p < end) - p += snprintf(p, - (size_t)(end - p), ": %s", wiredtiger_strerror(error)); + remain = WT_PTRDIFF(end, p); + if (prefix1 != NULL && prefix2 != NULL) + wlen = + (size_t)snprintf(p, remain, "%s [%s]: ", prefix1, prefix2); + else if (prefix1 != NULL) + wlen = (size_t)snprintf(p, remain, "%s: ", prefix1); + else if (prefix2 != NULL) + wlen = (size_t)snprintf(p, remain, "%s: ", prefix2); + else + wlen = 0; + p = wlen >= remain ? end : p + wlen; + + if (file_name != NULL) { + remain = WT_PTRDIFF(end, p); + wlen = (size_t) + snprintf(p, remain, "%s, %d: ", file_name, line_number); + p = wlen >= remain ? end : p + wlen; + } + + remain = WT_PTRDIFF(end, p); + wlen = (size_t)vsnprintf(p, remain, fmt, ap); + p = wlen >= remain ? end : p + wlen; + + if (error != 0) { + /* + * When the engine calls __wt_err on error, it often outputs an + * error message including the string associated with the error + * it's returning. We could change the calls to call __wt_errx, + * but it's simpler to not append an error string if all we are + * doing is duplicating an existing error string. + * + * Use strcmp to compare: both strings are nul-terminated, and + * we don't want to run past the end of the buffer. + */ + err = wiredtiger_strerror(error); + len = strlen(err); + if (WT_PTRDIFF(p, s) < len || strcmp(p - len, err) != 0) { + remain = WT_PTRDIFF(end, p); + (void)snprintf(p, remain, ": %s", err); + } + } + /* + * If a handler fails, return the error status: if we're in the process + * of handling an error, any return value we provide will be ignored by + * our caller, our caller presumably already has an error value it will + * be returning. + * + * If an application-specified or default informational message handler + * fails, complain using the application-specified or default error + * handler. + * + * If an application-specified error message handler fails, complain + * using the default error handler. If the default error handler fails, + * there's nothing to do. + */ handler = session->event_handler; - if (msg_event) - (void)handler->handle_message(handler, s); - else - handler->handle_error(handler, error, s); + if (msg_event) { + ret = handler->handle_message(handler, s); + if (ret != 0) + __handler_failure(session, ret, "message", 0); + } else { + ret = handler->handle_error(handler, error, s); + if (ret != 0 && handler->handle_error != __handle_error_default) + __handler_failure(session, ret, "error", 1); + } + + return (ret); } /* @@ -66,8 +219,12 @@ __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) { va_list ap; + /* + * Ignore error returns from underlying event handlers, we already have + * an error value to return. + */ va_start(ap, fmt); - __wt_eventv(session, 0, error, NULL, 0, fmt, ap); + (void)__eventv(session, 0, error, NULL, 0, fmt, ap); va_end(ap); } @@ -81,17 +238,48 @@ __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) { va_list ap; + /* + * Ignore error returns from underlying event handlers, we already have + * an error value to return. + */ va_start(ap, fmt); - __wt_eventv(session, 0, 0, NULL, 0, fmt, ap); + (void)__eventv(session, 0, 0, NULL, 0, fmt, ap); va_end(ap); } /* - * __wt_msg_call -- - * Pass a message to an event handler. + * __wt_verrx -- + * Interface to support the extension API. */ -void -__wt_msgv(WT_SESSION_IMPL *session, const char *fmt, va_list ap) +int +__wt_verrx(WT_SESSION_IMPL *session, const char *fmt, va_list ap) +{ + return (__eventv(session, 0, 0, NULL, 0, fmt, ap)); +} +/* + * __wt_msg -- + * Informational message. + */ +int +__wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) +{ + WT_DECL_RET; + va_list ap; + + va_start(ap, fmt); + ret = __wt_vmsg(session, fmt, ap); + va_end(ap); + + return (ret); +} + +/* + * __wt_vmsg -- + * Informational message. + */ +int +__wt_vmsg(WT_SESSION_IMPL *session, const char *fmt, va_list ap) { WT_EVENT_HANDLER *handler; @@ -105,37 +293,42 @@ __wt_msgv(WT_SESSION_IMPL *session, const char *fmt, va_list ap) (void)vsnprintf(s, sizeof(s), fmt, ap); handler = session->event_handler; - (void)handler->handle_message(handler, s); + return (handler->handle_message(handler, s)); } /* - * __wt_verbose -- - * Verbose message. + * __wt_progress -- + * Progress message. */ -void -__wt_verbose(WT_SESSION_IMPL *session, const char *fmt, ...) - WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) +int +__wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v) { - va_list ap; + WT_DECL_RET; + WT_EVENT_HANDLER *handler; - va_start(ap, fmt); - __wt_eventv(session, 1, 0, NULL, 0, fmt, ap); - va_end(ap); + handler = session->event_handler; + if (handler != NULL && handler->handle_progress != NULL) + if ((ret = handler->handle_progress( + handler, s == NULL ? session->name : s, v)) != 0) + __handler_failure(session, ret, "progress", 0); + return (0); } /* - * __wt_msg -- - * Report a message. + * __wt_verbose -- + * Verbose message. */ -void -__wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) +int +__wt_verbose(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) { + WT_DECL_RET; va_list ap; va_start(ap, fmt); - __wt_msgv(session, fmt, ap); + ret = __eventv(session, 1, 0, NULL, 0, fmt, ap); va_end(ap); + return (ret); } /* @@ -143,7 +336,7 @@ __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) * Assert and other unexpected failures, includes file/line information * for debugging. */ -int +void __wt_assert(WT_SESSION_IMPL *session, int error, const char *file_name, int line_number, const char *fmt, ...) WT_GCC_FUNC_ATTRIBUTE((format (printf, 5, 6))) @@ -151,14 +344,13 @@ __wt_assert(WT_SESSION_IMPL *session, va_list ap; va_start(ap, fmt); - __wt_eventv(session, 0, error, file_name, line_number, fmt, ap); + (void)__eventv(session, 0, error, file_name, line_number, fmt, ap); va_end(ap); #ifdef HAVE_DIAGNOSTIC __wt_abort(session); /* NOTREACHED */ #endif - return (error); } /* @@ -166,13 +358,15 @@ __wt_assert(WT_SESSION_IMPL *session, * Print a standard error message when we detect an illegal value. */ int -__wt_illegal_value(WT_SESSION_IMPL *session) +__wt_illegal_value(WT_SESSION_IMPL *session, const char *name) { WT_RET_MSG(session, WT_ERROR, + "%s%s" "encountered an illegal file format or internal value; restart " "the system and verify the underlying files, if corruption is " "detected use the WT_SESSION salvage method or the wt utility's " - "salvage command to repair the file"); + "salvage command to repair the file", + name == NULL ? "" : name, name == NULL ? "" : " "); } /* diff --git a/src/support/global.c b/src/support/global.c index 7f78b620006..4d6420e6d14 100644 --- a/src/support/global.c +++ b/src/support/global.c @@ -32,7 +32,7 @@ __wt_library_init(void) { static pthread_once_t once_control = PTHREAD_ONCE_INIT; static int first = 1; - int ret; + WT_DECL_RET; /* * Do per-process initialization once, before anything else, but only diff --git a/src/support/hazard.c b/src/support/hazard.c index e22d25be3c2..3846889dce2 100644 --- a/src/support/hazard.c +++ b/src/support/hazard.c @@ -16,7 +16,7 @@ static void __hazard_dump(WT_SESSION_IMPL *); * Set a hazard reference. */ int -__wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref +__wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, int *busyp #ifdef HAVE_DIAGNOSTIC , const char *file, int line #endif @@ -26,6 +26,7 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref WT_HAZARD *hp; conn = S2C(session); + *busyp = 0; /* * Do the dance: @@ -60,7 +61,7 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref */ if (ref->state == WT_REF_MEM || ref->state == WT_REF_EVICT_WALK) { - WT_VERBOSE(session, hazard, + WT_VERBOSE_RET(session, hazard, "session %p hazard %p: set", session, ref->page); return (0); } @@ -78,7 +79,8 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref * again until it loops around through the tree. */ hp->page = NULL; - return (EBUSY); + *busyp = 1; + return (0); } __wt_errx(session, @@ -109,24 +111,39 @@ __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page) */ WT_ASSERT(session, page != NULL); - WT_VERBOSE(session, hazard, - "session %p hazard %p: clr", session, page); - /* Clear the caller's hazard pointer. */ for (hp = session->hazard; hp < session->hazard + conn->hazard_size; ++hp) if (hp->page == page) { - hp->page = NULL; /* - * We don't have to flush memory here for correctness; - * it would give the page server thread faster access - * to the block were the block selected to be evicted, - * but the generation number was just set which makes - * it unlikely to be selected for eviction. + * Check to see if the page has grown too big and force + * eviction. We have to request eviction while holding + * a hazard reference (else the page might disappear out + * from under us), but we can't wake the eviction server + * until we've released our hazard reference because our + * hazard reference blocks the page eviction. A little + * dance: check the page, schedule the forced eviction, + * clear/publish the hazard reference, wake the eviction + * server. + * + * We don't publish the hazard reference clear in the + * general case. It's not required for correctness; + * it gives the page server thread faster access to the + * page were the page selected for eviction, but the + * generation number was just set, so it's unlikely the + * page will be selected for eviction. */ + if (__wt_eviction_page_check(session, page)) { + __wt_evict_page_request(session, page); + WT_PUBLISH(hp->page, NULL); + __wt_evict_server_wake(session); + } else + hp->page = NULL; return; } - __wt_errx(session, "hazard reference not found"); + __wt_errx(session, + "clear hazard reference: session: %p reference %p: not found", + session, page); } /* @@ -190,26 +207,4 @@ __hazard_dump(WT_SESSION_IMPL *session) if (fail) __wt_errx(session, "unexpected hazard reference"); } - -/* - * __wt_hazard_validate -- - * Confirm that a page isn't on the hazard list. - */ -void -__wt_hazard_validate(WT_SESSION_IMPL *session, WT_PAGE *page) -{ - WT_CONNECTION_IMPL *conn; - WT_HAZARD *hp; - uint32_t elem, i; - - conn = S2C(session); - - elem = conn->session_size * conn->hazard_size; - for (i = 0, hp = conn->hazard; i < elem; ++i, ++hp) - if (hp->page == page) - __wt_errx(session, - "discarded page has hazard reference: " - "(%p: %s, line %d)", - hp->page, hp->file, hp->line); -} #endif diff --git a/src/support/hex.c b/src/support/hex.c index e582e9576ef..d9ee135599b 100644 --- a/src/support/hex.c +++ b/src/support/hex.c @@ -11,11 +11,11 @@ static const char hex[] = "0123456789abcdef"; /* * __wt_raw_to_hex -- - * Convert a chunk of data to a printable hex string. + * Convert a chunk of data to a nul-terminated printable hex string. */ int -__wt_raw_to_hex(WT_SESSION_IMPL *session, - const uint8_t *from, uint32_t size, WT_ITEM *to) +__wt_raw_to_hex( + WT_SESSION_IMPL *session, const uint8_t *from, uint32_t size, WT_ITEM *to) { uint32_t i; const uint8_t *p; @@ -38,12 +38,12 @@ __wt_raw_to_hex(WT_SESSION_IMPL *session, /* * __wt_raw_to_esc_hex -- - * Convert a chunk of data to an printable string using escaped hex as - * necessary. + * Convert a chunk of data to a nul-terminated printable string using + * escaped hex, as necessary. */ int -__wt_raw_to_esc_hex(WT_SESSION_IMPL *session, - const uint8_t *from, size_t size, WT_ITEM *to) +__wt_raw_to_esc_hex( + WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to) { size_t i; const uint8_t *p; @@ -136,22 +136,31 @@ __hex_fmterr(WT_SESSION_IMPL *session) /* * __wt_hex_to_raw -- - * Convert a printable hex string to a chunk of data. + * Convert a nul-terminated printable hex string to a chunk of data. */ int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) { + return (__wt_nhex_to_raw(session, from, strlen(from), to)); +} + +/* + * __wt_nhex_to_raw -- + * Convert a printable hex string to a chunk of data. + */ +int +__wt_nhex_to_raw( + WT_SESSION_IMPL *session, const char *from, size_t size, WT_ITEM *to) +{ const char *p; uint8_t *t; - size_t size; - size = strlen(from); if (size % 2 != 0) return (__hex_fmterr(session)); WT_RET(__wt_buf_init(session, to, size / 2)); - for (p = from, t = to->mem; *p != '\0'; p += 2, ++t) + for (p = from, t = to->mem; size > 0; p += 2, size -= 2, ++t) if (hex2byte(p, t)) return (__hex_fmterr(session)); @@ -161,8 +170,7 @@ __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) /* * __wt_esc_hex_to_raw -- - * Convert a printable string using escaped hex as necessary to a chunk - * of data. + * Convert a printable string, encoded in escaped hex, to a chunk of data. */ int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) diff --git a/src/support/huffman.c b/src/support/huffman.c index 7b66b321b9c..fa1f1499cff 100644 --- a/src/support/huffman.c +++ b/src/support/huffman.c @@ -62,7 +62,6 @@ typedef struct __wt_huffman_obj { * memory: code2symbol[1 << max_code_length] */ uint8_t *code2symbol; - } WT_HUFFMAN_OBJ; /* @@ -296,17 +295,16 @@ __wt_huffman_open(WT_SESSION_IMPL *session, { INDEXED_SYMBOL *indexed_freqs, *sym; NODE_QUEUE *combined_nodes, *leaves; + WT_DECL_RET; WT_FREQTREE_NODE *node, *node2, **refnode, *tempnode; WT_HUFFMAN_OBJ *huffman; uint64_t w1, w2; uint16_t i; - int ret; indexed_freqs = symbol_frequency_array; combined_nodes = leaves = NULL; node = node2 = tempnode = NULL; - ret = 0; WT_RET(__wt_calloc_def(session, 1, &huffman)); @@ -337,12 +335,12 @@ __wt_huffman_open(WT_SESSION_IMPL *session, if (i > 0 && indexed_freqs[i].symbol == indexed_freqs[i - 1].symbol) WT_ERR_MSG(session, EINVAL, - "duplicate symbol %" PRIx16 + "duplicate symbol %" PRIx32 " specified in a huffman table", indexed_freqs[i].symbol); if (indexed_freqs[i].symbol > huffman->numSymbols) WT_ERR_MSG(session, EINVAL, - "illegal symbol %" PRIx16 + "illegal symbol %" PRIx32 " specified in a huffman table", indexed_freqs[i].symbol); } @@ -590,6 +588,7 @@ int __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, uint32_t from_len, WT_ITEM *to_buf) { + WT_DECL_RET; WT_HUFFMAN_CODE code; WT_HUFFMAN_OBJ *huffman; WT_ITEM *tmp; @@ -597,7 +596,6 @@ __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, uint32_t max_len, outlen, bytes; const uint8_t *from; uint8_t len, *out, padding_info, symbol; - int ret; /* * Shift register to accumulate bits from input. @@ -612,7 +610,6 @@ __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, huffman = huffman_arg; from = from_arg; tmp = NULL; - ret = 0; /* * We don't want to find all of our callers and ensure they don't pass @@ -729,6 +726,7 @@ int __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, uint32_t from_len, WT_ITEM *to_buf) { + WT_DECL_RET; WT_ITEM *tmp; WT_HUFFMAN_OBJ *huffman; uint64_t from_len_bits; @@ -736,12 +734,10 @@ __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, uint16_t pattern; const uint8_t *from; uint8_t padding_info, symbol, *to, valid; - int ret; huffman = huffman_arg; from = from_arg; tmp = NULL; - ret = 0; /* * We don't want to find all of our callers and ensure they don't pass diff --git a/src/support/scratch.c b/src/support/scratch.c index 03e3d3a8b78..57b779bd5c2 100644 --- a/src/support/scratch.c +++ b/src/support/scratch.c @@ -248,12 +248,17 @@ __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) * Scratch buffer allocation function. */ int -__wt_scr_alloc(WT_SESSION_IMPL *session, uint32_t size, WT_ITEM **scratchp) +__wt_scr_alloc_func(WT_SESSION_IMPL *session, + uint32_t size, WT_ITEM **scratchp +#ifdef HAVE_DIAGNOSTIC + , const char *file, int line +#endif + ) { - WT_ITEM *buf, **p, *best, **slot; + WT_DECL_RET; + WT_ITEM *buf, **p, **best, **slot; size_t allocated; u_int i; - int ret; /* Don't risk the caller not catching the error. */ *scratchp = NULL; @@ -267,7 +272,7 @@ __wt_scr_alloc(WT_SESSION_IMPL *session, uint32_t size, WT_ITEM **scratchp) * * Walk the array, looking for a buffer we can use. */ - for (i = 0, best = NULL, slot = NULL, + for (i = 0, best = slot = NULL, p = session->scratch; i < session->scratch_alloc; ++i, ++p) { /* If we find an empty slot, remember it. */ if ((buf = *p) == NULL) { @@ -285,11 +290,13 @@ __wt_scr_alloc(WT_SESSION_IMPL *session, uint32_t size, WT_ITEM **scratchp) * or the largest buffer if none are large enough. */ if (best == NULL || - (best->memsize < size && buf->memsize > best->memsize) || - (buf->memsize >= size && buf->memsize < best->memsize)) - best = buf; + ((*best)->memsize < size && + buf->memsize > (*best)->memsize) || + (buf->memsize >= size && buf->memsize < (*best)->memsize)) + best = p; + /* If we find a perfect match, use it. */ - if (best->memsize == size) + if ((*best)->memsize == size) break; } @@ -302,6 +309,12 @@ __wt_scr_alloc(WT_SESSION_IMPL *session, uint32_t size, WT_ITEM **scratchp) WT_ERR(__wt_realloc(session, &allocated, (session->scratch_alloc + 10) * sizeof(WT_ITEM *), &session->scratch)); +#ifdef HAVE_DIAGNOSTIC + allocated = session->scratch_alloc * sizeof(WT_SCRATCH_TRACK); + WT_ERR(__wt_realloc(session, &allocated, + (session->scratch_alloc + 10) * sizeof(WT_SCRATCH_TRACK), + &session->scratch_track)); +#endif slot = session->scratch + session->scratch_alloc; session->scratch_alloc += 10; } @@ -312,17 +325,24 @@ __wt_scr_alloc(WT_SESSION_IMPL *session, uint32_t size, WT_ITEM **scratchp) */ if (best == NULL) { WT_ASSERT(session, slot != NULL); - WT_ERR(__wt_calloc_def(session, 1, slot)); - best = *slot; + best = slot; + + WT_ERR(__wt_calloc_def(session, 1, best)); /* Scratch buffers must be aligned. */ - F_SET(best, WT_ITEM_ALIGNED); + F_SET(*best, WT_ITEM_ALIGNED); } /* Grow the buffer as necessary and return. */ - WT_ERR(__wt_buf_init(session, best, size)); - F_SET(best, WT_ITEM_INUSE); - *scratchp = best; + WT_ERR(__wt_buf_init(session, *best, size)); + F_SET(*best, WT_ITEM_INUSE); + +#ifdef HAVE_DIAGNOSTIC + session->scratch_track[best - session->scratch].file = file; + session->scratch_track[best - session->scratch].line = line; +#endif + + *scratchp = *best; return (0); err: WT_RET_MSG(session, ret, @@ -356,16 +376,26 @@ __wt_scr_discard(WT_SESSION_IMPL *session) bufp = session->scratch; i < session->scratch_alloc; ++i, ++bufp) { if (*bufp == NULL) continue; -#if 0 if (F_ISSET(*bufp, WT_ITEM_INUSE)) __wt_errx(session, - "scratch buffer allocated and never discarded"); + "scratch buffer allocated and never discarded" +#ifdef HAVE_DIAGNOSTIC + ": %s: %d", + session-> + scratch_track[bufp - session->scratch].file, + session-> + scratch_track[bufp - session->scratch].line #endif + ); + __wt_buf_free(session, *bufp); __wt_free(session, *bufp); } __wt_free(session, session->scratch); +#ifdef HAVE_DIAGNOSTIC + __wt_free(session, session->scratch_track); +#endif } /* diff --git a/src/support/sess_dump.c b/src/support/sess_dump.c index 962f50c532f..5fa5deb2b74 100644 --- a/src/support/sess_dump.c +++ b/src/support/sess_dump.c @@ -15,13 +15,17 @@ void __wt_session_dump_all(WT_SESSION_IMPL *session) { - WT_SESSION_IMPL **tp; + WT_CONNECTION_IMPL *conn; + WT_SESSION_IMPL *s; + uint32_t i; if (session == NULL) return; - for (tp = S2C(session)->sessions; *tp != NULL; ++tp) - __wt_session_dump(*tp); + conn = S2C(session); + for (s = conn->sessions, i = 0; i < conn->session_size; ++s, ++i) + if (s->active) + __wt_session_dump(s); } /* @@ -38,15 +42,15 @@ __wt_session_dump(WT_SESSION_IMPL *session) conn = S2C(session); - __wt_msg(session, "session: %s%s%p", + (void)__wt_msg(session, "session: %s%s%p", session->name == NULL ? "" : session->name, session->name == NULL ? "" : " ", session); first = 0; TAILQ_FOREACH(cursor, &session->cursors, q) { if (++first == 1) - __wt_msg(session, "\tcursors:"); - __wt_msg(session, "\t\t%p", cursor); + (void)__wt_msg(session, "\tcursors:"); + (void)__wt_msg(session, "\t\t%p", cursor); } first = 0; @@ -55,12 +59,12 @@ __wt_session_dump(WT_SESSION_IMPL *session) if (hp->page == NULL) continue; if (++first == 1) - __wt_msg(session, "\thazard references:"); + (void)__wt_msg(session, "\thazard references:"); #ifdef HAVE_DIAGNOSTIC - __wt_msg(session, + (void)__wt_msg(session, "\t\t%p (%s, line %d)", hp->page, hp->file, hp->line); #else - __wt_msg(session, "\t\t%p", hp->page); + (void)__wt_msg(session, "\t\t%p", hp->page); #endif } } diff --git a/src/support/stat.c b/src/support/stat.c index bbd13b8b839..5741be441e8 100644 --- a/src/support/stat.c +++ b/src/support/stat.c @@ -28,9 +28,6 @@ __wt_stat_alloc_btree_stats(WT_SESSION_IMPL *session, WT_BTREE_STATS **statsp) "column-store variable-size leaf pages"; stats->file_entries.desc = "total entries"; stats->file_fixed_len.desc = "fixed-record size"; - stats->file_freelist_bytes.desc = "number of bytes in the freelist"; - stats->file_freelist_entries.desc = - "number of entries in the freelist"; stats->file_magic.desc = "magic number"; stats->file_major.desc = "major version number"; stats->file_maxintlitem.desc = "maximum internal page item size"; @@ -42,6 +39,7 @@ __wt_stat_alloc_btree_stats(WT_SESSION_IMPL *session, WT_BTREE_STATS **statsp) stats->file_row_int_pages.desc = "row-store internal pages"; stats->file_row_leaf_pages.desc = "row-store leaf pages"; stats->file_size.desc = "file: size"; + stats->file_write_conflicts.desc = "write generation conflicts"; stats->free.desc = "file: block frees"; stats->overflow_read.desc = "file: overflow pages read from the file"; stats->page_read.desc = "file: pages read from the file"; @@ -85,8 +83,6 @@ __wt_stat_clear_btree_stats(WT_STATS *stats_arg) stats->file_col_var_pages.v = 0; stats->file_entries.v = 0; stats->file_fixed_len.v = 0; - stats->file_freelist_bytes.v = 0; - stats->file_freelist_entries.v = 0; stats->file_magic.v = 0; stats->file_major.v = 0; stats->file_maxintlitem.v = 0; @@ -98,6 +94,7 @@ __wt_stat_clear_btree_stats(WT_STATS *stats_arg) stats->file_row_int_pages.v = 0; stats->file_row_leaf_pages.v = 0; stats->file_size.v = 0; + stats->file_write_conflicts.v = 0; stats->free.v = 0; stats->overflow_read.v = 0; stats->page_read.v = 0; |