Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/adt/cht.c

    r63e27ef r8f9c808  
    290290#include <adt/cht.h>
    291291#include <adt/hash.h>
    292 #include <assert.h>
     292#include <debug.h>
     293#include <memstr.h>
    293294#include <mm/slab.h>
    294295#include <arch/barrier.h>
     
    522523        bool can_block, cht_ops_t *op)
    523524{
    524         assert(h);
    525         assert(op && op->hash && op->key_hash && op->equal && op->key_equal);
     525        ASSERT(h);
     526        ASSERT(op && op->hash && op->key_hash && op->equal && op->key_equal);
    526527        /* Memoized hashes are stored in the rcu_link.func function pointer. */
    527         static_assert(sizeof(size_t) == sizeof(rcu_func_t), "");
    528         assert(sentinel.hash == (uintptr_t)sentinel.rcu_link.func);
     528        STATIC_ASSERT(sizeof(size_t) == sizeof(rcu_func_t));
     529        ASSERT(sentinel.hash == (uintptr_t)sentinel.rcu_link.func);
    529530
    530531        /* All operations are compulsory. */
     
    625626       
    626627        /* You must clear the table of items. Otherwise cht_destroy will leak. */
    627         assert(atomic_get(&h->item_cnt) == 0);
     628        ASSERT(atomic_get(&h->item_cnt) == 0);
    628629}
    629630
     
    685686static inline cht_link_t *find_lazy(cht_t *h, void *key)
    686687{
    687         assert(h);
     688        ASSERT(h);
    688689        /* See docs to cht_find() and cht_find_lazy(). */
    689         assert(rcu_read_locked());
     690        ASSERT(rcu_read_locked());
    690691       
    691692        size_t hash = calc_key_hash(h, key);
     
    731732cht_link_t *cht_find_next_lazy(cht_t *h, const cht_link_t *item)
    732733{
    733         assert(h);
    734         assert(rcu_read_locked());
    735         assert(item);
     734        ASSERT(h);
     735        ASSERT(rcu_read_locked());
     736        ASSERT(item);
    736737       
    737738        return find_duplicate(h, item, calc_node_hash(h, item), get_next(item->link));
     
    755756        do {
    756757                cur = get_next(prev);
    757                 assert(cur);
     758                ASSERT(cur);
    758759                prev = cur->link;
    759760        } while (node_hash(h, cur) < search_hash);
     
    770771               
    771772                cur = get_next(cur->link);
    772                 assert(cur);
     773                ASSERT(cur);
    773774        }
    774775       
     
    790791        marked_ptr_t old_head, size_t old_idx)
    791792{
    792         assert(N_INVALID == get_mark(old_head));
    793         assert(h->new_b);
     793        ASSERT(N_INVALID == get_mark(old_head));
     794        ASSERT(h->new_b);
    794795       
    795796        size_t new_idx = calc_bucket_idx(hash, h->new_b->order);
     
    903904                         * traversing search_head.
    904905                         */
    905                         assert(N_JOIN & get_mark(get_next(old_head)->link));
     906                        ASSERT(N_JOIN & get_mark(get_next(old_head)->link));
    906907                        return search_bucket(h, old_head, key, hash);
    907908                }
     
    913914                 * sure all cpus see that the new table replaced the old one.
    914915                 */
    915                 assert(h->b->order == h->new_b->order);
     916                ASSERT(h->b->order == h->new_b->order);
    916917                /*
    917918                 * The resizer must ensure all new bucket heads are visible before
    918919                 * replacing the old table.
    919920                 */
    920                 assert(N_NORMAL == get_mark(new_head));
     921                ASSERT(N_NORMAL == get_mark(new_head));
    921922                return search_bucket(h, new_head, key, hash);
    922923        }
     
    961962bool cht_insert_unique(cht_t *h, cht_link_t *item, cht_link_t **dup_item)
    962963{
    963         assert(rcu_read_locked());
    964         assert(dup_item);
     964        ASSERT(rcu_read_locked());
     965        ASSERT(dup_item);
    965966        return insert_impl(h, item, dup_item);
    966967}
     
    10601061                return ret == make_link(wnd->cur, jf_mark);
    10611062        } else {
    1062                 assert(walk_mode == WM_LEAVE_JOIN);
     1063                ASSERT(walk_mode == WM_LEAVE_JOIN);
    10631064
    10641065                item->link = make_link(wnd->cur, N_NORMAL);
     
    10871088        cht_link_t *cur, cht_link_t **dup_item)
    10881089{
    1089         assert(cur);
    1090         assert(cur == &sentinel || hash <= node_hash(h, cur)
     1090        ASSERT(cur);
     1091        ASSERT(cur == &sentinel || hash <= node_hash(h, cur)
    10911092                || node_hash(h, cur) == h->invalid_hash);
    10921093       
     
    11101111        cht_link_t *start)
    11111112{
    1112         assert(hash <= node_hash(h, start) || h->invalid_hash == node_hash(h, start));
     1113        ASSERT(hash <= node_hash(h, start) || h->invalid_hash == node_hash(h, start));
    11131114
    11141115        cht_link_t *cur = start;
    11151116       
    11161117try_again:     
    1117         assert(cur);
     1118        ASSERT(cur);
    11181119
    11191120        while (node_hash(h, cur) == hash) {
    1120                 assert(cur != &sentinel);
     1121                ASSERT(cur != &sentinel);
    11211122               
    11221123                bool deleted = (N_DELETED & get_mark(cur->link));
     
    11271128               
    11281129                cur = get_next(cur->link);
    1129                 assert(cur);
     1130                ASSERT(cur);
    11301131        }
    11311132
     
    11421143size_t cht_remove_key(cht_t *h, void *key)
    11431144{
    1144         assert(h);
     1145        ASSERT(h);
    11451146       
    11461147        size_t hash = calc_key_hash(h, key);
     
    11631164bool cht_remove_item(cht_t *h, cht_link_t *item)
    11641165{
    1165         assert(h);
    1166         assert(item);
     1166        ASSERT(h);
     1167        ASSERT(item);
    11671168        /* Otherwise a concurrent cht_remove_key might free the item. */
    1168         assert(rcu_read_locked());
     1169        ASSERT(rcu_read_locked());
    11691170
    11701171        /*
     
    12621263        bool *deleted_but_gc, bool *resizing)
    12631264{
    1264         assert(wnd->cur && wnd->cur != &sentinel);
     1265        ASSERT(wnd->cur && wnd->cur != &sentinel);
    12651266       
    12661267        *deleted_but_gc = false;
     
    12921293        bool *resizing)
    12931294{
    1294         assert(cur && cur != &sentinel);
     1295        ASSERT(cur && cur != &sentinel);
    12951296       
    12961297        /*
     
    13101311                }
    13111312        } else {
    1312                 static_assert(N_JOIN == N_JOIN_FOLLOWS, "");
     1313                STATIC_ASSERT(N_JOIN == N_JOIN_FOLLOWS);
    13131314               
    13141315                /* Keep the N_JOIN/N_JOIN_FOLLOWS mark but strip N_DELETED. */
     
    13291330        bool *resizing)
    13301331{
    1331         assert(wnd->cur != &sentinel);
    1332         assert(wnd->cur && (N_DELETED & get_mark(wnd->cur->link)));
     1332        ASSERT(wnd->cur != &sentinel);
     1333        ASSERT(wnd->cur && (N_DELETED & get_mark(wnd->cur->link)));
    13331334       
    13341335        cht_link_t *next = get_next(wnd->cur->link);
     
    13361337        if (walk_mode == WM_LEAVE_JOIN) {
    13371338                /* Never try to unlink join nodes. */
    1338                 assert(!(N_JOIN & get_mark(wnd->cur->link)));
     1339                ASSERT(!(N_JOIN & get_mark(wnd->cur->link)));
    13391340
    13401341                mark_t pred_mark = get_mark(*wnd->ppred);
     
    13481349                        return false;
    13491350        } else {
    1350                 assert(walk_mode == WM_MOVE_JOIN_FOLLOWS || walk_mode == WM_NORMAL);
     1351                ASSERT(walk_mode == WM_MOVE_JOIN_FOLLOWS || walk_mode == WM_NORMAL);
    13511352                /* Move the JF mark if set. Clear DEL mark. */
    13521353                mark_t cur_mark = N_JOIN_FOLLOWS & get_mark(wnd->cur->link);
     
    13981399        equal_pred_t pred, void *pred_arg, wnd_t *wnd, bool *resizing)
    13991400{
    1400         assert(wnd->cur);
     1401        ASSERT(wnd->cur);
    14011402       
    14021403        if (wnd->cur == &sentinel)
     
    14151416               
    14161417        while (cur_hash <= hash) {
    1417                 assert(wnd->cur && wnd->cur != &sentinel);
     1418                ASSERT(wnd->cur && wnd->cur != &sentinel);
    14181419               
    14191420                /* GC any deleted nodes on the way. */
     
    14361437        if (cur_hash == h->invalid_hash) {
    14371438                next_wnd(wnd);
    1438                 assert(wnd->cur);
     1439                ASSERT(wnd->cur);
    14391440                goto try_again;
    14401441        }
     
    14691470{
    14701471try_again:
    1471         assert(wnd->cur);
     1472        ASSERT(wnd->cur);
    14721473
    14731474        while (node_hash(h, wnd->cur) < hash) {
     
    14821483                }
    14831484               
    1484                 assert(wnd->cur);
     1485                ASSERT(wnd->cur);
    14851486        }
    14861487       
     
    14981499        bool *resizing)
    14991500{
    1500         assert(N_DELETED & get_mark(wnd->cur->link));
     1501        ASSERT(N_DELETED & get_mark(wnd->cur->link));
    15011502
    15021503        /* Skip deleted JOIN nodes. */
     
    15051506        } else {
    15061507                /* Ordinary deleted node or a deleted JOIN_FOLLOWS. */
    1507                 assert(walk_mode != WM_LEAVE_JOIN
     1508                ASSERT(walk_mode != WM_LEAVE_JOIN
    15081509                        || !((N_JOIN | N_JOIN_FOLLOWS) & get_mark(wnd->cur->link)));
    15091510
     
    15461547         * it
    15471548         */
    1548         assert(h->b->order > h->new_b->order);
    1549         assert(wnd->cur);
     1549        ASSERT(h->b->order > h->new_b->order);
     1550        ASSERT(wnd->cur);
    15501551       
    15511552        /* Either we did not need the joining link or we have already followed it.*/
     
    16201621                /* The hash belongs to the moved bucket. */
    16211622                if (move_dest_idx == new_idx) {
    1622                         assert(pmoved_head == pnew_head);
     1623                        ASSERT(pmoved_head == pnew_head);
    16231624                        /*
    16241625                         * move_head() makes the new head of the moved bucket visible.
    16251626                         * The new head may be marked with a JOIN_FOLLOWS
    16261627                         */
    1627                         assert(!(N_CONST & get_mark(*pmoved_head)));
     1628                        ASSERT(!(N_CONST & get_mark(*pmoved_head)));
    16281629                        *walk_mode = WM_MOVE_JOIN_FOLLOWS;
    16291630                } else {
    1630                         assert(pmoved_head != pnew_head);
     1631                        ASSERT(pmoved_head != pnew_head);
    16311632                        /*
    16321633                         * The hash belongs to the bucket that is the result of splitting
     
    16431644                                 * JOIN_FOLLOWS in this part of split bucket.
    16441645                                 */
    1645                                 assert(N_NORMAL == get_mark(*pnew_head));
     1646                                ASSERT(N_NORMAL == get_mark(*pnew_head));
    16461647                        }
    16471648                       
     
    16751676               
    16761677                /* move_head() or join_buckets() makes it so or makes the mark visible.*/
    1677                 assert(N_INVALID == get_mark(*pold_head));
     1678                ASSERT(N_INVALID == get_mark(*pold_head));
    16781679                /* move_head() makes it visible. No JOIN_FOLLOWS used when shrinking. */
    1679                 assert(N_NORMAL == get_mark(*pnew_head));
     1680                ASSERT(N_NORMAL == get_mark(*pnew_head));
    16801681
    16811682                *walk_mode = WM_LEAVE_JOIN;
     
    16851686                 * readers to notice that the old table had been replaced.
    16861687                 */
    1687                 assert(b == h->new_b);
     1688                ASSERT(b == h->new_b);
    16881689                *walk_mode = WM_NORMAL;
    16891690        }
     
    17121713{
    17131714        /* Head move has to in progress already when calling this func. */
    1714         assert(N_CONST & get_mark(*psrc_head));
     1715        ASSERT(N_CONST & get_mark(*psrc_head));
    17151716       
    17161717        /* Head already moved. */
     
    17251726        }
    17261727       
    1727         assert(!(N_CONST & get_mark(*pdest_head)));
     1728        ASSERT(!(N_CONST & get_mark(*pdest_head)));
    17281729}
    17291730
     
    17561757static void complete_head_move(marked_ptr_t *psrc_head, marked_ptr_t *pdest_head)
    17571758{
    1758         assert(N_JOIN_FOLLOWS != get_mark(*psrc_head));
    1759         assert(N_CONST & get_mark(*psrc_head));
     1759        ASSERT(N_JOIN_FOLLOWS != get_mark(*psrc_head));
     1760        ASSERT(N_CONST & get_mark(*psrc_head));
    17601761       
    17611762        cht_link_t *next = get_next(*psrc_head);
     
    17631764        DBG(marked_ptr_t ret = )
    17641765                cas_link(pdest_head, &sentinel, N_INVALID, next, N_NORMAL);
    1765         assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
     1766        ASSERT(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
    17661767        cas_order_barrier();
    17671768       
    17681769        DBG(ret = )
    17691770                cas_link(psrc_head, next, N_CONST, next, N_INVALID);   
    1770         assert(ret == make_link(next, N_CONST) || (N_INVALID == get_mark(ret)));
     1771        ASSERT(ret == make_link(next, N_CONST) || (N_INVALID == get_mark(ret)));
    17711772        cas_order_barrier();
    17721773}
     
    18611862        DBG(marked_ptr_t ret = )
    18621863                cas_link(pdest_head, &sentinel, N_INVALID, wnd.cur, N_NORMAL);
    1863         assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
     1864        ASSERT(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
    18641865        cas_order_barrier();
    18651866       
     
    19051906               
    19061907                /* Must not report that the table is resizing if WM_MOVE_JOIN_FOLLOWS.*/
    1907                 assert(!resizing);
     1908                ASSERT(!resizing);
    19081909                /*
    19091910                 * Mark the last node of the first half of the split bucket
     
    20422043        DBG(marked_ptr_t ret = )
    20432044                cas_link(psrc_head, join_node, N_CONST, join_node, N_INVALID);
    2044         assert(ret == make_link(join_node, N_CONST) || (N_INVALID == get_mark(ret)));
     2045        ASSERT(ret == make_link(join_node, N_CONST) || (N_INVALID == get_mark(ret)));
    20452046        cas_order_barrier();
    20462047       
     
    20732074                        continue;
    20742075
    2075                 assert(!resizing);
     2076                ASSERT(!resizing);
    20762077               
    20772078                if (wnd.cur != &sentinel) {
    20782079                        /* Must be from the new appended bucket. */
    2079                         assert(split_hash <= node_hash(h, wnd.cur)
     2080                        ASSERT(split_hash <= node_hash(h, wnd.cur)
    20802081                                || h->invalid_hash == node_hash(h, wnd.cur));
    20812082                        return;
     
    20962097static void free_later(cht_t *h, cht_link_t *item)
    20972098{
    2098         assert(item != &sentinel);
     2099        ASSERT(item != &sentinel);
    20992100       
    21002101        /*
     
    21562157       
    21572158#ifdef CONFIG_DEBUG
    2158         assert(h->b);
     2159        ASSERT(h->b);
    21592160        /* Make resize_reqs visible. */
    21602161        read_barrier();
    2161         assert(0 < atomic_get(&h->resize_reqs));
     2162        ASSERT(0 < atomic_get(&h->resize_reqs));
    21622163#endif
    21632164
     
    23362337                /* Set the invalid joinee head to NULL. */
    23372338                if (old_idx != move_src_idx) {
    2338                         assert(N_INVALID == get_mark(h->b->head[old_idx]));
     2339                        ASSERT(N_INVALID == get_mark(h->b->head[old_idx]));
    23392340                       
    23402341                        if (&sentinel != get_next(h->b->head[old_idx]))
     
    23922393        marked_ptr_t *new_head)
    23932394{
    2394         assert(join_node != &sentinel);
    2395         assert(join_node && (N_JOIN & get_mark(join_node->link)));
     2395        ASSERT(join_node != &sentinel);
     2396        ASSERT(join_node && (N_JOIN & get_mark(join_node->link)));
    23962397       
    23972398        bool done;
     
    24092410                /* Done if the mark was cleared. Retry if a new node was inserted. */
    24102411                done = (ret == jn_link);
    2411                 assert(ret == jn_link || (get_mark(ret) & N_JOIN));
     2412                ASSERT(ret == jn_link || (get_mark(ret) & N_JOIN));
    24122413        } while (!done);
    24132414       
     
    24322433                        join_node, &wnd, &resizing);
    24332434               
    2434                 assert(!resizing);
     2435                ASSERT(!resizing);
    24352436        } while (!done);
    24362437}
     
    24392440static void cleanup_join_follows(cht_t *h, marked_ptr_t *new_head)
    24402441{
    2441         assert(new_head);
     2442        ASSERT(new_head);
    24422443       
    24432444        rcu_read_lock();
     
    24642465                /* GC any deleted nodes on the way - even deleted JOIN_FOLLOWS. */
    24652466                if (N_DELETED & get_mark(*cur_link)) {
    2466                         assert(cur_link != new_head);
    2467                         assert(wnd.ppred && wnd.cur && wnd.cur != &sentinel);
    2468                         assert(cur_link == &wnd.cur->link);
     2467                        ASSERT(cur_link != new_head);
     2468                        ASSERT(wnd.ppred && wnd.cur && wnd.cur != &sentinel);
     2469                        ASSERT(cur_link == &wnd.cur->link);
    24692470
    24702471                        bool dummy;
     
    24842485                                        cas_link(cur_link, next, N_JOIN_FOLLOWS, &sentinel, N_NORMAL);
    24852486                               
    2486                                 assert(next == &sentinel
     2487                                ASSERT(next == &sentinel
    24872488                                        || ((N_JOIN | N_JOIN_FOLLOWS) & get_mark(ret)));
    24882489
     
    25052506
    25062507                /* We must encounter a JF node before we reach the end of the bucket. */
    2507                 assert(wnd.cur && wnd.cur != &sentinel);
     2508                ASSERT(wnd.cur && wnd.cur != &sentinel);
    25082509                cur_link = &wnd.cur->link;
    25092510        }
     
    25192520static inline size_t calc_split_hash(size_t split_idx, size_t order)
    25202521{
    2521         assert(1 <= order && order <= 8 * sizeof(size_t));
     2522        ASSERT(1 <= order && order <= 8 * sizeof(size_t));
    25222523        return split_idx << (8 * sizeof(size_t) - order);
    25232524}
     
    25262527static inline size_t calc_bucket_idx(size_t hash, size_t order)
    25272528{
    2528         assert(1 <= order && order <= 8 * sizeof(size_t));
     2529        ASSERT(1 <= order && order <= 8 * sizeof(size_t));
    25292530        return hash >> (8 * sizeof(size_t) - order);
    25302531}
     
    25582559static inline size_t node_hash(cht_t *h, const cht_link_t *item)
    25592560{
    2560         assert(item->hash == h->invalid_hash
     2561        ASSERT(item->hash == h->invalid_hash
    25612562                || item->hash == sentinel.hash
    25622563                || item->hash == calc_node_hash(h, item));
     
    25682569static inline size_t calc_node_hash(cht_t *h, const cht_link_t *item)
    25692570{
    2570         assert(item != &sentinel);
     2571        ASSERT(item != &sentinel);
    25712572        /*
    25722573         * Clear the lowest order bit in order for sentinel's node hash
     
    25872588        marked_ptr_t ptr = (marked_ptr_t) next;
    25882589       
    2589         assert(!(ptr & N_MARK_MASK));
    2590         assert(!((unsigned)mark & ~N_MARK_MASK));
     2590        ASSERT(!(ptr & N_MARK_MASK));
     2591        ASSERT(!((unsigned)mark & ~N_MARK_MASK));
    25912592       
    25922593        return ptr | mark;
     
    26082609static inline void next_wnd(wnd_t *wnd)
    26092610{
    2610         assert(wnd);
    2611         assert(wnd->cur);
     2611        ASSERT(wnd);
     2612        ASSERT(wnd->cur);
    26122613
    26132614        wnd->last = wnd->cur;
     
    26352636        marked_ptr_t new)
    26362637{
    2637         assert(link != &sentinel.link);
     2638        ASSERT(link != &sentinel.link);
    26382639        /*
    26392640         * cas(x) on the same location x on one cpu must be ordered, but do not
Note: See TracChangeset for help on using the changeset viewer.