/* * __split_safe_free -- * Free a buffer if we can be sure no thread is accessing it, or schedule * it to be freed otherwise. */ static int __split_safe_free(WT_SESSION_IMPL *session, int exclusive, void *p, size_t s) { /* * We have swapped something in a page: if we don't have exclusive * access, check whether there are other threads in the same tree. */ if (!exclusive && __split_oldest_gen(session) == S2C(session)->split_gen + 1) exclusive = 1; if (exclusive) { __wt_free(session, p); return (0); } return (__split_stash_add(session, p, s)); }
/* * __split_safe_free -- * Free a buffer if we can be sure no thread is accessing it, or schedule * it to be freed otherwise. */ static int __split_safe_free(WT_SESSION_IMPL *session, uint64_t split_gen, bool exclusive, void *p, size_t s) { /* We should only call safe free if we aren't pinning the memory. */ WT_ASSERT(session, session->split_gen != split_gen); /* * We have swapped something in a page: if we don't have exclusive * access, check whether there are other threads in the same tree. */ if (!exclusive && __split_oldest_gen(session) > split_gen) exclusive = true; if (exclusive) { __wt_free(session, p); return (0); } return (__split_stash_add(session, split_gen, p, s)); }
/* * __wt_split_stash_discard -- * Discard any memory from a session's split stash that we can. */ void __wt_split_stash_discard(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; WT_SPLIT_STASH *stash; uint64_t oldest; size_t i; conn = S2C(session); /* Get the oldest split generation. */ oldest = __split_oldest_gen(session); for (i = 0, stash = session->split_stash; i < session->split_stash_cnt; ++i, ++stash) { if (stash->p == NULL) continue; else if (stash->split_gen >= oldest) break; /* * It's a bad thing if another thread is in this memory after * we free it, make sure nothing good happens to that thread. */ (void)__wt_atomic_sub64(&conn->split_stashed_bytes, stash->len); (void)__wt_atomic_sub64(&conn->split_stashed_objects, 1); __wt_overwrite_and_free_len(session, stash->p, stash->len); } /* * If there are enough free slots at the beginning of the list, shuffle * everything down. */ if (i > 100 || i == session->split_stash_cnt) if ((session->split_stash_cnt -= i) > 0) memmove(session->split_stash, stash, session->split_stash_cnt * sizeof(*stash)); }