wiredtiger - hazard pointers

http://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890

memory deallocation  lock-free

 

session.h

/*
 * WT_HAZARD --
 *    A hazard pointer.
 */
struct __wt_hazard {
    WT_PAGE *page;            /* Page address */
#ifdef HAVE_DIAGNOSTIC
    const char *file;        /* File/line where hazard acquired */
    int        line;
#endif
};

struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) __wt_session_impl {
    // 略...
    /*
     * Hazard pointers.
     *
     * Use the non-NULL state of the hazard field to know if the session has
     * previously been initialized.
     */
#define    WT_SESSION_FIRST_USE(s)                        \
    ((s)->hazard == NULL)

    /* The number of hazard pointers grows dynamically. */
#define    WT_HAZARD_INCR        10
    uint32_t   hazard_size;        /* Allocated slots in hazard array. */
    uint32_t   nhazard;        /* Count of active hazard pointers */
    WT_HAZARD *hazard;        /* Hazard pointer array */
};

 

support/hazard.c

__wt_hazard_set()

 

/__wt_hazard_clear()

 

btree.i

在__wt_page_hazard_check前, cas保证WT_REF为 WT_REF_LOCKED(btmem.h, struct __wt_ref)

__wt_page_hazard_check(WT_SESSION_IMPL *session, WT_PAGE *page)
{
    WT_CONNECTION_IMPL *conn;
    WT_HAZARD *hp;
    WT_SESSION_IMPL *s;
    uint32_t i, hazard_size, session_cnt;

    conn = S2C(session);

    /*
     * No lock is required because the session array is fixed size, but it
     * may contain inactive entries.  We must review any active session
     * that might contain a hazard pointer, so insert a barrier before
     * reading the active session count.  That way, no matter what sessions
     * come or go, we'll check the slots for all of the sessions that could
     * have been active when we started our check.
     */
    WT_ORDERED_READ(session_cnt, conn->session_cnt);
    for (s = conn->sessions, i = 0; i < session_cnt; ++s, ++i) {
        if (!s->active)
            continue;
        WT_ORDERED_READ(hazard_size, s->hazard_size);
        for (hp = s->hazard; hp < s->hazard + hazard_size; ++hp)
            if (hp->page == page)
                return (hp);
    }
    return (NULL);
}

 

posted @ 2016-08-17 13:12  brayden  阅读(316)  评论(0编辑  收藏  举报