Changeset a35b458 in mainline for kernel/generic/src/adt


Ignore:
Timestamp:
2018-03-02T20:10:49Z (7 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1380b7
Parents:
3061bc1
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
Message:

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

Location:
kernel/generic/src/adt
Files:
6 edited

Legend:

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

    r3061bc1 ra35b458  
    6666{
    6767        avltree_node_t *p;
    68        
     68
    6969        /*
    7070         * Iteratively descend to the leaf that can contain the searched key.
     
    9292{
    9393        avltree_node_t *p = t->root;
    94        
     94
    9595        /*
    9696         * Check whether the tree is empty.
     
    9898        if (!p)
    9999                return NULL;
    100        
     100
    101101        /*
    102102         * Iteratively descend to the leftmost leaf in the tree.
     
    104104        while (p->lft != NULL)
    105105                p = p->lft;
    106        
     106
    107107        return p;
    108108}
     
    151151#define REBALANCE_INSERT_LR()           REBALANCE_INSERT_XY(lft, rgt, 1)
    152152#define REBALANCE_INSERT_RL()           REBALANCE_INSERT_XY(rgt, lft, -1)
    153        
     153
    154154/** Insert new node into AVL tree.
    155155 *
     
    172172         */
    173173        key = newnode->key + t->base;
    174        
     174
    175175        /*
    176176         * Iteratively descend to the leaf that can contain the new node.
     
    244244                }
    245245        }
    246        
     246
    247247        /*
    248248         * To balance the tree, we must check and balance top node.
     
    260260                         */
    261261                        assert(par->balance == 1);
    262                        
     262
    263263                        REBALANCE_INSERT_LR();
    264264                }
     
    275275                         */
    276276                        assert(par->balance == -1);
    277                
     277
    278278                        REBALANCE_INSERT_RL();
    279279                }
     
    375375        assert(t);
    376376        assert(node);
    377        
     377
    378378        if (node->lft == NULL) {
    379379                if (node->rgt) {
     
    451451                cur->par = node->par;
    452452        }
    453        
     453
    454454        /*
    455455         * Repair the parent node's pointer which pointed previously to the
     
    457457         */
    458458        (void) repair(t, node, node, cur, NULL, false);
    459        
     459
    460460        /*
    461461         * Repair cycle which repairs balances of nodes on the way from from the
     
    484484                                         * RL rotation.
    485485                                         */
    486                                        
     486
    487487                                        cur = par->lft;
    488488                                        par->lft = cur->rgt;
     
    490490                                        gpa->rgt = cur->lft;
    491491                                        cur->lft = gpa;
    492                                        
     492
    493493                                        /*
    494494                                         * Repair balances and paternity of
     
    497497                                         */
    498498                                        REBALANCE_DELETE_RL();
    499                                        
     499
    500500                                        /*
    501501                                         * Repair paternity.
     
    513513                                         * RR rotation.
    514514                                         */
    515                                        
     515
    516516                                        gpa->rgt = par->lft;
    517517                                        if (par->lft)
    518518                                                par->lft->par = gpa;
    519519                                        par->lft = gpa;
    520                                        
     520
    521521                                        /*
    522522                                         * Repair paternity.
     
    524524                                        par->par = gpa->par;
    525525                                        gpa->par = par;
    526                                        
     526
    527527                                        if (par->balance == 0) {
    528528                                                /*
     
    575575                                 */
    576576                                par = gpa->lft;
    577                                
     577
    578578                                if (par->balance == 1) {
    579579                                        /*
    580580                                         * LR rotation.
    581581                                         */
    582                                        
     582
    583583                                        cur = par->rgt;
    584584                                        par->rgt = cur->lft;
     
    586586                                        gpa->lft = cur->rgt;
    587587                                        cur->rgt = gpa;
    588                                        
     588
    589589                                        /*
    590590                                         * Repair balances and paternity of
     
    619619                                        par->par = gpa->par;
    620620                                        gpa->par = par;
    621                                        
     621
    622622                                        if (par->balance == 0) {
    623623                                                /*
     
    630630                                                par->balance = 1;
    631631                                                gpa->balance = -1;
    632                                                
     632
    633633                                                (void) repair(t, par, gpa, par,
    634634                                                    NULL, false);
     
    637637                                                par->balance = 0;
    638638                                                gpa->balance = 0;
    639                                                
     639
    640640                                                if (!repair(t, par, gpa, par,
    641641                                                    &dir, false))
     
    667667{
    668668        avltree_node_t *node;
    669        
     669
    670670        /*
    671671         * Start searching for the smallest key in the tree starting in the root
     
    673673         * must have the smallest key).
    674674         */
    675          
     675
    676676        node = t->root;
    677677        if (!node)
    678678                return false;
    679        
     679
    680680        while (node->lft != NULL)
    681681                node = node->lft;
    682        
     682
    683683        avltree_delete(t, node);
    684684
  • kernel/generic/src/adt/bitmap.c

    r3061bc1 ra35b458  
    6262        size_t byte = element / BITMAP_ELEMENT;
    6363        uint8_t mask = 1 << (element & BITMAP_REMAINER);
    64        
     64
    6565        return !!((bitmap->bits)[byte] & mask);
    6666}
     
    7878{
    7979        size_t size = elements / BITMAP_ELEMENT;
    80        
     80
    8181        if ((elements % BITMAP_ELEMENT) != 0)
    8282                size++;
    83        
     83
    8484        return size;
    8585}
     
    113113{
    114114        assert(start + count <= bitmap->elements);
    115        
     115
    116116        if (count == 0)
    117117                return;
    118        
     118
    119119        size_t start_byte = start / BITMAP_ELEMENT;
    120120        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
    121        
     121
    122122        /* Leading unaligned bits */
    123123        size_t lub = min(aligned_start - start, count);
    124        
     124
    125125        /* Aligned middle bits */
    126126        size_t amb = (count > lub) ? (count - lub) : 0;
    127        
     127
    128128        /* Trailing aligned bits */
    129129        size_t tab = amb % BITMAP_ELEMENT;
    130        
     130
    131131        if (start + count < aligned_start) {
    132132                /* Set bits in the middle of byte. */
     
    135135                return;
    136136        }
    137        
     137
    138138        if (lub) {
    139139                /* Make sure to set any leading unaligned bits. */
     
    141141                    ~((1 << (BITMAP_ELEMENT - lub)) - 1);
    142142        }
    143        
     143
    144144        size_t i;
    145        
     145
    146146        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    147147                /* The middle bits can be set byte by byte. */
     
    149149                    ALL_ONES;
    150150        }
    151        
     151
    152152        if (tab) {
    153153                /* Make sure to set any trailing aligned bits. */
     
    167167{
    168168        assert(start + count <= bitmap->elements);
    169        
     169
    170170        if (count == 0)
    171171                return;
    172        
     172
    173173        size_t start_byte = start / BITMAP_ELEMENT;
    174174        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
    175        
     175
    176176        /* Leading unaligned bits */
    177177        size_t lub = min(aligned_start - start, count);
    178        
     178
    179179        /* Aligned middle bits */
    180180        size_t amb = (count > lub) ? (count - lub) : 0;
    181        
     181
    182182        /* Trailing aligned bits */
    183183        size_t tab = amb % BITMAP_ELEMENT;
    184        
     184
    185185        if (start + count < aligned_start) {
    186186                /* Set bits in the middle of byte */
     
    189189                return;
    190190        }
    191        
     191
    192192        if (lub) {
    193193                /* Make sure to clear any leading unaligned bits. */
     
    195195                    (1 << (BITMAP_ELEMENT - lub)) - 1;
    196196        }
    197        
     197
    198198        size_t i;
    199        
     199
    200200        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    201201                /* The middle bits can be cleared byte by byte. */
     
    203203                    ALL_ZEROES;
    204204        }
    205        
     205
    206206        if (tab) {
    207207                /* Make sure to clear any trailing aligned bits. */
     
    209209                    ~((1 << tab) - 1);
    210210        }
    211        
     211
    212212        bitmap->next_fit = start_byte;
    213213}
     
    224224        assert(count <= dst->elements);
    225225        assert(count <= src->elements);
    226        
     226
    227227        size_t i;
    228        
     228
    229229        for (i = 0; i < count / BITMAP_ELEMENT; i++)
    230230                dst->bits[i] = src->bits[i];
    231        
     231
    232232        if (count % BITMAP_ELEMENT) {
    233233                bitmap_clear_range(dst, i * BITMAP_ELEMENT,
     
    274274        if (count == 0)
    275275                return false;
    276        
     276
    277277        size_t size = bitmap_size(bitmap->elements);
    278278        size_t next_fit = bitmap->next_fit;
    279        
     279
    280280        /*
    281281         * Adjust the next-fit value according to the address
     
    284284        if ((prefered > base) && (prefered < base + bitmap->elements)) {
    285285                size_t prefered_fit = (prefered - base) / BITMAP_ELEMENT;
    286                
     286
    287287                if (prefered_fit > next_fit)
    288288                        next_fit = prefered_fit;
    289289        }
    290        
     290
    291291        for (size_t pos = 0; pos < size; pos++) {
    292292                size_t byte = (next_fit + pos) % size;
    293                
     293
    294294                /* Skip if the current byte has all bits set */
    295295                if (bitmap->bits[byte] == ALL_ONES)
    296296                        continue;
    297                
     297
    298298                size_t byte_bit = byte * BITMAP_ELEMENT;
    299                
     299
    300300                for (size_t bit = 0; bit < BITMAP_ELEMENT; bit++) {
    301301                        size_t i = byte_bit + bit;
    302                        
     302
    303303                        if (i >= bitmap->elements)
    304304                                break;
    305                        
     305
    306306                        if (!constraint_satisfy(i, base, constraint))
    307307                                continue;
    308                        
     308
    309309                        if (!bitmap_get_fast(bitmap, i)) {
    310310                                size_t continuous = 1;
    311                                
     311
    312312                                for (size_t j = 1; j < count; j++) {
    313313                                        if ((i + j < bitmap->elements) &&
     
    317317                                                break;
    318318                                }
    319                                
     319
    320320                                if (continuous == count) {
    321321                                        if (index != NULL) {
     
    324324                                                *index = i;
    325325                                        }
    326                                        
     326
    327327                                        return true;
    328328                                } else
     
    331331                }
    332332        }
    333        
     333
    334334        return false;
    335335}
  • kernel/generic/src/adt/btree.c

    r3061bc1 ra35b458  
    8383{
    8484        unsigned int i;
    85        
     85
    8686        node->keys = 0;
    87        
     87
    8888        /* Clean also space for the extra key. */
    8989        for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
     
    9292                node->subtree[i] = NULL;
    9393        }
    94        
     94
    9595        node->subtree[i] = NULL;
    9696        node->parent = NULL;
    97        
     97
    9898        link_initialize(&node->leaf_link);
    9999        link_initialize(&node->bfs_link);
     
    122122{
    123123        size_t i;
    124        
     124
    125125        if (root->keys) {
    126126                for (i = 0; i < root->keys + 1; i++) {
     
    129129                }
    130130        }
    131        
     131
    132132        slab_free(btree_node_cache, root);
    133133}
     
    156156{
    157157        size_t i;
    158        
     158
    159159        for (i = 0; i < node->keys; i++) {
    160160                if (key < node->key[i]) {
    161161                        size_t j;
    162                        
     162
    163163                        for (j = node->keys; j > i; j--) {
    164164                                node->key[j] = node->key[j - 1];
     
    166166                                node->subtree[j + 1] = node->subtree[j];
    167167                        }
    168                        
     168
    169169                        break;
    170170                }
    171171        }
    172        
     172
    173173        node->key[i] = key;
    174174        node->value[i] = value;
     
    191191{
    192192        size_t i;
    193        
     193
    194194        for (i = 0; i < node->keys + 1; i++) {
    195195                if (subtree == node->subtree[i])
    196196                        return i - (int) (right != false);
    197197        }
    198        
     198
    199199        panic("Node %p does not contain subtree %p.", node, subtree);
    200200}
     
    215215        size_t i;
    216216        size_t j;
    217        
     217
    218218        for (i = 0; i < node->keys; i++) {
    219219                if (key == node->key[i]) {
     
    223223                                node->subtree[j - 1] = node->subtree[j];
    224224                        }
    225                        
     225
    226226                        node->subtree[j - 1] = node->subtree[j];
    227227                        node->keys--;
    228                        
     228
    229229                        return;
    230230                }
    231231        }
    232        
     232
    233233        panic("Node %p does not contain key %" PRIu64 ".", node, key);
    234234}
     
    248248{
    249249        size_t i, j;
    250        
     250
    251251        for (i = 0; i < node->keys; i++) {
    252252                if (key == node->key[i]) {
     
    256256                                node->subtree[j] = node->subtree[j + 1];
    257257                        }
    258                        
     258
    259259                        node->keys--;
    260260                        return;
    261261                }
    262262        }
    263        
     263
    264264        panic("Node %p does not contain key %" PRIu64 ".", node, key);
    265265}
     
    280280{
    281281        size_t i;
    282        
     282
    283283        for (i = 0; i < node->keys; i++) {
    284284                if (key < node->key[i]) {
    285285                        size_t j;
    286                        
     286
    287287                        for (j = node->keys; j > i; j--) {
    288288                                node->key[j] = node->key[j - 1];
     
    290290                                node->subtree[j + 1] = node->subtree[j];
    291291                        }
    292                        
     292
    293293                        node->subtree[j + 1] = node->subtree[j];
    294294                        break;
    295295                }
    296296        }
    297        
     297
    298298        node->key[i] = key;
    299299        node->value[i] = value;
    300300        node->subtree[i] = lsubtree;
    301        
     301
    302302        node->keys++;
    303303}
     
    320320{
    321321        btree_key_t key = lnode->key[lnode->keys - 1];
    322        
     322
    323323        if (LEAF_NODE(lnode)) {
    324324                void *value = lnode->value[lnode->keys - 1];
    325                
     325
    326326                node_remove_key_and_rsubtree(lnode, key);
    327327                node_insert_key_and_lsubtree(rnode, key, value, NULL);
     
    329329        } else {
    330330                btree_node_t *rsubtree = lnode->subtree[lnode->keys];
    331                
     331
    332332                node_remove_key_and_rsubtree(lnode, key);
    333333                node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
    334334                lnode->parent->key[idx] = key;
    335                
     335
    336336                /* Fix parent link of the reconnected right subtree. */
    337337                rsubtree->parent = rnode;
     
    356356{
    357357        btree_key_t key = rnode->key[0];
    358        
     358
    359359        if (LEAF_NODE(rnode)) {
    360360                void *value = rnode->value[0];
    361                
     361
    362362                node_remove_key_and_lsubtree(rnode, key);
    363363                node_insert_key_and_rsubtree(lnode, key, value, NULL);
     
    365365        } else {
    366366                btree_node_t *lsubtree = rnode->subtree[0];
    367                
     367
    368368                node_remove_key_and_lsubtree(rnode, key);
    369369                node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
    370370                rnode->parent->key[idx] = key;
    371                
     371
    372372                /* Fix parent link of the reconnected left subtree. */
    373373                lsubtree->parent = lnode;
     
    395395        size_t idx;
    396396        btree_node_t *lnode;
    397        
     397
    398398        /*
    399399         * If this is root node, the rotation can not be done.
     
    401401        if (ROOT_NODE(node))
    402402                return false;
    403        
     403
    404404        idx = find_key_by_subtree(node->parent, node, true);
    405405        if ((int) idx == -1) {
     
    410410                return false;
    411411        }
    412        
     412
    413413        lnode = node->parent->subtree[idx];
    414414        if (lnode->keys < BTREE_MAX_KEYS) {
     
    420420                return true;
    421421        }
    422        
     422
    423423        return false;
    424424}
     
    444444        size_t idx;
    445445        btree_node_t *rnode;
    446        
     446
    447447        /*
    448448         * If this is root node, the rotation can not be done.
     
    450450        if (ROOT_NODE(node))
    451451                return false;
    452        
     452
    453453        idx = find_key_by_subtree(node->parent, node, false);
    454454        if (idx == node->parent->keys) {
     
    459459                return false;
    460460        }
    461        
     461
    462462        rnode = node->parent->subtree[idx + 1];
    463463        if (rnode->keys < BTREE_MAX_KEYS) {
     
    469469                return true;
    470470        }
    471        
     471
    472472        return false;
    473473}
     
    499499        size_t i;
    500500        size_t j;
    501        
     501
    502502        assert(median);
    503503        assert(node->keys == BTREE_MAX_KEYS);
    504        
     504
    505505        /*
    506506         * Use the extra space to store the extra node.
    507507         */
    508508        node_insert_key_and_rsubtree(node, key, value, rsubtree);
    509        
     509
    510510        /*
    511511         * Compute median of keys.
    512512         */
    513513        *median = MEDIAN_HIGH(node);
    514        
     514
    515515        /*
    516516         * Allocate and initialize new right sibling.
     
    520520        rnode->parent = node->parent;
    521521        rnode->depth = node->depth;
    522        
     522
    523523        /*
    524524         * Copy big keys, values and subtree pointers to the new right sibling.
     
    530530                rnode->value[j] = node->value[i];
    531531                rnode->subtree[j] = node->subtree[i];
    532                
     532
    533533                /*
    534534                 * Fix parent links in subtrees.
     
    537537                        rnode->subtree[j]->parent = rnode;
    538538        }
    539        
     539
    540540        rnode->subtree[j] = node->subtree[i];
    541541        if (rnode->subtree[j])
    542542                rnode->subtree[j]->parent = rnode;
    543        
     543
    544544        rnode->keys = j;  /* Set number of keys of the new node. */
    545545        node->keys /= 2;  /* Shrink the old node. */
    546        
     546
    547547        return rnode;
    548548}
     
    578578                btree_node_t *rnode;
    579579                btree_key_t median;
    580                
     580
    581581                /*
    582582                 * Node is full and both siblings (if both exist) are full too.
     
    584584                 * bigger keys (i.e. the new node) into its parent.
    585585                 */
    586                
     586
    587587                rnode = node_split(node, key, value, rsubtree, &median);
    588                
     588
    589589                if (LEAF_NODE(node)) {
    590590                        list_insert_after(&rnode->leaf_link, &node->leaf_link);
    591591                }
    592                
     592
    593593                if (ROOT_NODE(node)) {
    594594                        /*
     
    599599                        rnode->parent = t->root;
    600600                        node_initialize(t->root);
    601                        
     601
    602602                        /*
    603603                         * Left-hand side subtree will be the old root (i.e. node).
     
    605605                         */
    606606                        t->root->subtree[0] = node;
    607                        
     607
    608608                        t->root->depth = node->depth + 1;
    609609                }
     
    624624{
    625625        btree_node_t *lnode;
    626        
     626
    627627        assert(value);
    628        
     628
    629629        lnode = leaf_node;
    630630        if (!lnode) {
     
    632632                        panic("B-tree %p already contains key %" PRIu64 ".", t, key);
    633633        }
    634        
     634
    635635        _btree_insert(t, key, value, NULL, lnode);
    636636}
     
    648648        size_t idx;
    649649        btree_node_t *lnode;
    650        
     650
    651651        /*
    652652         * If this is root node, the rotation can not be done.
     
    654654        if (ROOT_NODE(rnode))
    655655                return false;
    656        
     656
    657657        idx = find_key_by_subtree(rnode->parent, rnode, true);
    658658        if ((int) idx == -1) {
     
    663663                return false;
    664664        }
    665        
     665
    666666        lnode = rnode->parent->subtree[idx];
    667667        if (lnode->keys > FILL_FACTOR) {
     
    669669                return true;
    670670        }
    671        
     671
    672672        return false;
    673673}
     
    685685        size_t idx;
    686686        btree_node_t *rnode;
    687        
     687
    688688        /*
    689689         * If this is root node, the rotation can not be done.
     
    691691        if (ROOT_NODE(lnode))
    692692                return false;
    693        
     693
    694694        idx = find_key_by_subtree(lnode->parent, lnode, false);
    695695        if (idx == lnode->parent->keys) {
     
    700700                return false;
    701701        }
    702        
     702
    703703        rnode = lnode->parent->subtree[idx + 1];
    704704        if (rnode->keys > FILL_FACTOR) {
     
    706706                return true;
    707707        }
    708        
     708
    709709        return false;
    710710}
     
    724724        btree_node_t *rnode;
    725725        size_t i;
    726        
     726
    727727        assert(!ROOT_NODE(node));
    728        
     728
    729729        idx = find_key_by_subtree(node->parent, node, false);
    730730        if (idx == node->parent->keys) {
     
    737737        } else
    738738                rnode = node->parent->subtree[idx + 1];
    739        
     739
    740740        /* Index nodes need to insert parent node key in between left and right node. */
    741741        if (INDEX_NODE(node))
    742742                node->key[node->keys++] = node->parent->key[idx];
    743        
     743
    744744        /* Copy the key-value-subtree triplets from the right node. */
    745745        for (i = 0; i < rnode->keys; i++) {
    746746                node->key[node->keys + i] = rnode->key[i];
    747747                node->value[node->keys + i] = rnode->value[i];
    748                
     748
    749749                if (INDEX_NODE(node)) {
    750750                        node->subtree[node->keys + i] = rnode->subtree[i];
     
    752752                }
    753753        }
    754        
     754
    755755        if (INDEX_NODE(node)) {
    756756                node->subtree[node->keys + i] = rnode->subtree[i];
    757757                rnode->subtree[i]->parent = node;
    758758        }
    759        
     759
    760760        node->keys += rnode->keys;
    761761        return rnode;
     
    789789                        node_remove_key_and_rsubtree(node, key);
    790790                }
    791                
     791
    792792                return;
    793793        }
    794        
     794
    795795        if (node->keys <= FILL_FACTOR) {
    796796                /*
     
    801801                        try_rotation_from_right(node);
    802802        }
    803        
     803
    804804        if (node->keys > FILL_FACTOR) {
    805805                size_t i;
    806                
     806
    807807                /*
    808808                 * The key can be immediately removed.
     
    813813                 */
    814814                node_remove_key_and_rsubtree(node, key);
    815                
     815
    816816                for (i = 0; i < node->parent->keys; i++) {
    817817                        if (node->parent->key[i] == key)
     
    822822                btree_node_t *rnode;
    823823                btree_node_t *parent;
    824                
     824
    825825                /*
    826826                 * The node is below the fill factor as well as its left and right sibling.
     
    832832                node_remove_key_and_rsubtree(node, key);
    833833                rnode = node_combine(node);
    834                
     834
    835835                if (LEAF_NODE(rnode))
    836836                        list_remove(&rnode->leaf_link);
    837                
     837
    838838                idx = find_key_by_subtree(parent, rnode, true);
    839839                assert((int) idx != -1);
     
    855855{
    856856        btree_node_t *lnode;
    857        
     857
    858858        lnode = leaf_node;
    859859        if (!lnode) {
     
    861861                        panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
    862862        }
    863        
     863
    864864        _btree_remove(t, key, lnode);
    865865}
     
    877877{
    878878        btree_node_t *cur, *next;
    879        
     879
    880880        /*
    881881         * Iteratively descend to the leaf that can contain the searched key.
     
    887887                 */
    888888                *leaf_node = cur;
    889                
     889
    890890                if (cur->keys == 0)
    891891                        return NULL;
     
    901901                        void *val;
    902902                        size_t i;
    903                        
     903
    904904                        /*
    905905                         * Now if the key is smaller than cur->key[i]
     
    911911                                        next = cur->subtree[i];
    912912                                        val = cur->value[i - 1];
    913                                        
     913
    914914                                        if (LEAF_NODE(cur))
    915915                                                return key == cur->key[i - 1] ? val : NULL;
    916                                        
     916
    917917                                        goto descend;
    918918                                }
    919919                        }
    920                        
     920
    921921                        /*
    922922                         * Last possibility is that the key is
     
    925925                        next = cur->subtree[i];
    926926                        val = cur->value[i - 1];
    927                        
     927
    928928                        if (LEAF_NODE(cur))
    929929                                return key == cur->key[i - 1] ? val : NULL;
     
    932932                ;
    933933        }
    934        
     934
    935935        /*
    936936         * The key was not found in the *leaf_node and
     
    952952{
    953953        assert(LEAF_NODE(node));
    954        
     954
    955955        if (node->leaf_link.prev != &t->leaf_list.head)
    956956                return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
     
    971971{
    972972        assert(LEAF_NODE(node));
    973        
     973
    974974        if (node->leaf_link.next != &t->leaf_list.head)
    975975                return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
     
    988988        int depth = t->root->depth;
    989989        list_t list;
    990        
     990
    991991        printf("Printing B-tree:\n");
    992992        list_initialize(&list);
    993993        list_append(&t->root->bfs_link, &list);
    994        
     994
    995995        /*
    996996         * Use BFS search to print out the tree.
     
    10001000                link_t *hlp;
    10011001                btree_node_t *node;
    1002                
     1002
    10031003                hlp = list_first(&list);
    10041004                assert(hlp != NULL);
    10051005                node = list_get_instance(hlp, btree_node_t, bfs_link);
    10061006                list_remove(hlp);
    1007                
     1007
    10081008                assert(node);
    1009                
     1009
    10101010                if (node->depth != depth) {
    10111011                        printf("\n");
    10121012                        depth = node->depth;
    10131013                }
    1014                
     1014
    10151015                printf("(");
    1016                
     1016
    10171017                for (i = 0; i < node->keys; i++) {
    10181018                        printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
     
    10211021                        }
    10221022                }
    1023                
     1023
    10241024                if (node->depth && node->subtree[i])
    10251025                        list_append(&node->subtree[i]->bfs_link, &list);
    1026                
     1026
    10271027                printf(")");
    10281028        }
    1029        
     1029
    10301030        printf("\n");
    1031        
     1031
    10321032        printf("Printing list of leaves:\n");
    10331033        list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
    10341034                assert(node);
    1035                
     1035
    10361036                printf("(");
    1037                
     1037
    10381038                for (i = 0; i < node->keys; i++)
    10391039                        printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
    1040                
     1040
    10411041                printf(")");
    10421042        }
    1043        
     1043
    10441044        printf("\n");
    10451045}
  • kernel/generic/src/adt/cht.c

    r3061bc1 ra35b458  
    531531        if (!op || !op->hash || !op->key_hash || !op->equal || !op->key_equal)
    532532                return false;
    533        
     533
    534534        size_t min_order = size_to_order(min_size, CHT_MIN_ORDER);
    535535        size_t order = size_to_order(init_size, min_order);
    536        
     536
    537537        h->b = alloc_buckets(order, false, can_block);
    538        
     538
    539539        if (!h->b)
    540540                return false;
    541        
     541
    542542        h->max_load = (max_load == 0) ? CHT_MAX_LOAD : max_load;
    543543        h->min_order = min_order;
     
    546546        atomic_set(&h->item_cnt, 0);
    547547        atomic_set(&h->resize_reqs, 0);
    548        
     548
    549549        if (NULL == op->remove_callback) {
    550550                h->op->remove_callback = dummy_remove_callback;
    551551        }
    552        
     552
    553553        /*
    554554         * Cached item hashes are stored in item->rcu_link.func. Once the item
     
    556556         */
    557557        h->invalid_hash = (uintptr_t)h->op->remove_callback;
    558        
     558
    559559        /* Ensure the initialization takes place before we start using the table. */
    560560        write_barrier();
    561        
     561
    562562        return true;
    563563}
     
    581581                sizeof(cht_buckets_t) + (bucket_cnt - 1) * sizeof(marked_ptr_t);
    582582        cht_buckets_t *b = malloc(bytes, can_block ? 0 : FRAME_ATOMIC);
    583        
     583
    584584        if (!b)
    585585                return NULL;
    586        
     586
    587587        b->order = order;
    588        
     588
    589589        marked_ptr_t head_link = set_invalid
    590590                ? make_link(&sentinel, N_INVALID)
    591591                : make_link(&sentinel, N_NORMAL);
    592        
     592
    593593        for (size_t i = 0; i < bucket_cnt; ++i) {
    594594                b->head[i] = head_link;
    595595        }
    596        
     596
    597597        return b;
    598598}
     
    607607                if (bucket_cnt <= ((size_t)1 << order))
    608608                        return order;
    609                
     609
    610610                ++order;
    611611        } while (order < CHT_MAX_ORDER);
    612        
     612
    613613        return order;
    614614}
     
    623623{
    624624        cht_destroy_unsafe(h);
    625        
     625
    626626        /* You must clear the table of items. Otherwise cht_destroy will leak. */
    627627        assert(atomic_get(&h->item_cnt) == 0);
     
    635635                rcu_barrier();
    636636        }
    637        
     637
    638638        /* Wait for all remove_callback()s to complete. */
    639639        rcu_barrier();
    640        
     640
    641641        free(h->b);
    642642        h->b = NULL;
     
    688688        /* See docs to cht_find() and cht_find_lazy(). */
    689689        assert(rcu_read_locked());
    690        
     690
    691691        size_t hash = calc_key_hash(h, key);
    692        
     692
    693693        cht_buckets_t *b = rcu_access(h->b);
    694694        size_t idx = calc_bucket_idx(hash, b->order);
     
    698698         */
    699699        marked_ptr_t head = b->head[idx];
    700        
     700
    701701        /* Undergoing a resize - take the slow path. */
    702702        if (N_INVALID == get_mark(head))
    703703                return find_resizing(h, key, hash, head, idx);
    704        
     704
    705705        return search_bucket(h, head, key, hash);
    706706}
     
    734734        assert(rcu_read_locked());
    735735        assert(item);
    736        
     736
    737737        return find_duplicate(h, item, calc_node_hash(h, item), get_next(item->link));
    738738}
     
    758758                prev = cur->link;
    759759        } while (node_hash(h, cur) < search_hash);
    760        
     760
    761761        /*
    762762         * Only search for an item with an equal key if cur is not the sentinel
     
    768768                                return cur;
    769769                }
    770                
     770
    771771                cur = get_next(cur->link);
    772772                assert(cur);
    773773        }
    774        
     774
    775775        /*
    776776         * In the unlikely case that we have encountered a node whose cached
     
    782782                goto try_again;
    783783        }
    784        
     784
    785785        return NULL;
    786786}
     
    792792        assert(N_INVALID == get_mark(old_head));
    793793        assert(h->new_b);
    794        
     794
    795795        size_t new_idx = calc_bucket_idx(hash, h->new_b->order);
    796796        marked_ptr_t new_head = h->new_b->head[new_idx];
    797797        marked_ptr_t search_head = new_head;
    798        
     798
    799799        /* Growing. */
    800800        if (h->b->order < h->new_b->order) {
     
    818818                                new_head = h->new_b->head[grow_idx(old_idx)];
    819819                        }
    820                        
     820
    821821                        /* new_head is now the moved bucket, either valid or invalid. */
    822                        
     822
    823823                        /*
    824824                         * The old bucket was definitely moved to new_head but the
     
    845845                        }
    846846                }
    847                
     847
    848848                return search_bucket(h, search_head, key, hash);
    849849        } else if (h->b->order > h->new_b->order) {
    850850                /* Shrinking. */
    851                
     851
    852852                /* Index of the bucket in the old table that was moved. */
    853853                size_t move_src_idx = grow_idx(new_idx);
    854854                marked_ptr_t moved_old_head = h->b->head[move_src_idx];
    855                
     855
    856856                /*
    857857                 * h->b->head[move_src_idx] had already been moved to new_head
     
    883883                        search_head = moved_old_head;
    884884                }
    885                
     885
    886886                cht_link_t *ret = search_bucket(h, search_head, key, hash);
    887                
     887
    888888                if (ret)
    889889                        return ret;
     
    906906                        return search_bucket(h, old_head, key, hash);
    907907                }
    908                
     908
    909909                return NULL;
    910910        } else {
     
    979979        bool resizing = false;
    980980        bool inserted = false;
    981        
     981
    982982        do {
    983983                walk_mode_t walk_mode = WM_NORMAL;
    984984                bool join_finishing;
    985                
     985
    986986                resizing = resizing || (N_NORMAL != get_mark(*phead));
    987                
     987
    988988                /* The table is resizing. Get the correct bucket head. */
    989989                if (resizing) {
    990990                        upd_resizing_head(h, hash, &phead, &join_finishing, &walk_mode);
    991991                }
    992                
     992
    993993                wnd_t wnd = {
    994994                        .ppred = phead,
     
    996996                        .last = NULL
    997997                };
    998                
     998
    999999                if (!find_wnd_and_gc(h, hash, walk_mode, &wnd, &resizing)) {
    10001000                        /* Could not GC a node; or detected an unexpected resize. */
    10011001                        continue;
    10021002                }
    1003                
     1003
    10041004                if (dup_item && has_duplicate(h, item, hash, wnd.cur, dup_item)) {
    10051005                        rcu_read_unlock();
    10061006                        return false;
    10071007                }
    1008                
     1008
    10091009                inserted = insert_at(item, &wnd, walk_mode, &resizing);
    10101010        } while (!inserted);
    1011        
     1011
    10121012        rcu_read_unlock();
    10131013
     
    10321032{
    10331033        marked_ptr_t ret;
    1034        
     1034
    10351035        if (walk_mode == WM_NORMAL) {
    10361036                item->link = make_link(wnd->cur, N_NORMAL);
    10371037                /* Initialize the item before adding it to a bucket. */
    10381038                memory_barrier();
    1039                
     1039
    10401040                /* Link a clean/normal predecessor to the item. */
    10411041                ret = cas_link(wnd->ppred, wnd->cur, N_NORMAL, item, N_NORMAL);
    1042                
     1042
    10431043                if (ret == make_link(wnd->cur, N_NORMAL)) {
    10441044                        return true;
     
    10541054                /* Initialize the item before adding it to a bucket. */
    10551055                memory_barrier();
    1056                
     1056
    10571057                /* Link the not-deleted predecessor to the item. Move its JF mark. */
    10581058                ret = cas_link(wnd->ppred, wnd->cur, jf_mark, item, N_NORMAL);
    1059                
     1059
    10601060                return ret == make_link(wnd->cur, jf_mark);
    10611061        } else {
     
    10651065                /* Initialize the item before adding it to a bucket. */
    10661066                memory_barrier();
    1067                
     1067
    10681068                mark_t pred_mark = get_mark(*wnd->ppred);
    10691069                /* If the predecessor is a join node it may be marked deleted.*/
     
    10901090        assert(cur == &sentinel || hash <= node_hash(h, cur)
    10911091                || node_hash(h, cur) == h->invalid_hash);
    1092        
     1092
    10931093        /* hash < node_hash(h, cur) */
    10941094        if (hash != node_hash(h, cur) && h->invalid_hash != node_hash(h, cur))
     
    11011101         */
    11021102        read_barrier();
    1103        
     1103
    11041104        *dup_item = find_duplicate(h, item, hash, cur);
    11051105        return NULL != *dup_item;
     
    11131113
    11141114        cht_link_t *cur = start;
    1115        
     1115
    11161116try_again:
    11171117        assert(cur);
     
    11191119        while (node_hash(h, cur) == hash) {
    11201120                assert(cur != &sentinel);
    1121                
     1121
    11221122                bool deleted = (N_DELETED & get_mark(cur->link));
    1123                
     1123
    11241124                /* Skip logically deleted nodes. */
    11251125                if (!deleted && h->op->equal(item, cur))
    11261126                        return cur;
    1127                
     1127
    11281128                cur = get_next(cur->link);
    11291129                assert(cur);
     
    11351135                goto try_again;
    11361136        }
    1137        
     1137
    11381138        return NULL;
    11391139}
     
    11431143{
    11441144        assert(h);
    1145        
     1145
    11461146        size_t hash = calc_key_hash(h, key);
    11471147        size_t removed = 0;
    1148        
     1148
    11491149        while (remove_pred(h, hash, h->op->key_equal, key))
    11501150                ++removed;
    1151        
     1151
    11521152        return removed;
    11531153}
     
    11811181{
    11821182        rcu_read_lock();
    1183        
     1183
    11841184        bool resizing = false;
    11851185        bool deleted = false;
    11861186        bool deleted_but_gc = false;
    1187        
     1187
    11881188        cht_buckets_t *b = rcu_access(h->b);
    11891189        size_t idx = calc_bucket_idx(hash, b->order);
    11901190        marked_ptr_t *phead = &b->head[idx];
    1191        
     1191
    11921192        do {
    11931193                walk_mode_t walk_mode = WM_NORMAL;
    11941194                bool join_finishing = false;
    1195                
     1195
    11961196                resizing = resizing || (N_NORMAL != get_mark(*phead));
    1197                
     1197
    11981198                /* The table is resizing. Get the correct bucket head. */
    11991199                if (resizing) {
    12001200                        upd_resizing_head(h, hash, &phead, &join_finishing, &walk_mode);
    12011201                }
    1202                
     1202
    12031203                wnd_t wnd = {
    12041204                        .ppred = phead,
     
    12061206                        .last = NULL
    12071207                };
    1208                
     1208
    12091209                if (!find_wnd_and_gc_pred(
    12101210                        h, hash, walk_mode, pred, pred_arg, &wnd, &resizing)) {
     
    12121212                        continue;
    12131213                }
    1214                
     1214
    12151215                /*
    12161216                 * The item lookup is affected by a bucket join but effects of
     
    12251225                        continue;
    12261226                }
    1227                
     1227
    12281228                /* Already deleted, but delete_at() requested one GC pass. */
    12291229                if (deleted_but_gc)
    12301230                        break;
    1231                
     1231
    12321232                bool found = (wnd.cur != &sentinel && pred(pred_arg, wnd.cur));
    1233                
     1233
    12341234                if (!found) {
    12351235                        rcu_read_unlock();
    12361236                        return false;
    12371237                }
    1238                
     1238
    12391239                deleted = delete_at(h, &wnd, walk_mode, &deleted_but_gc, &resizing);
    12401240        } while (!deleted || deleted_but_gc);
    1241        
     1241
    12421242        rcu_read_unlock();
    12431243        return true;
     
    12631263{
    12641264        assert(wnd->cur && wnd->cur != &sentinel);
    1265        
     1265
    12661266        *deleted_but_gc = false;
    1267        
     1267
    12681268        if (!mark_deleted(wnd->cur, walk_mode, resizing)) {
    12691269                /* Already deleted, or unexpectedly marked as JOIN/JOIN_FOLLOWS. */
    12701270                return false;
    12711271        }
    1272        
     1272
    12731273        /* Marked deleted. Unlink from the bucket. */
    1274        
     1274
    12751275        /* Never unlink join nodes. */
    12761276        if (walk_mode == WM_LEAVE_JOIN && (N_JOIN & get_mark(wnd->cur->link)))
    12771277                return true;
    1278        
     1278
    12791279        cas_order_barrier();
    1280        
     1280
    12811281        if (unlink_from_pred(wnd, walk_mode, resizing)) {
    12821282                free_later(h, wnd->cur);
     
    12841284                *deleted_but_gc = true;
    12851285        }
    1286        
     1286
    12871287        return true;
    12881288}
     
    12931293{
    12941294        assert(cur && cur != &sentinel);
    1295        
     1295
    12961296        /*
    12971297         * Btw, we could loop here if the cas fails but let's not complicate
    12981298         * things and let's retry from the head of the bucket.
    12991299         */
    1300        
     1300
    13011301        cht_link_t *next = get_next(cur->link);
    1302        
     1302
    13031303        if (walk_mode == WM_NORMAL) {
    13041304                /* Only mark clean/normal nodes - JF/JN is used only during resize. */
    13051305                marked_ptr_t ret = cas_link(&cur->link, next, N_NORMAL, next, N_DELETED);
    1306                
     1306
    13071307                if (ret != make_link(next, N_NORMAL)) {
    13081308                        *resizing = (N_JOIN | N_JOIN_FOLLOWS) & get_mark(ret);
     
    13111311        } else {
    13121312                static_assert(N_JOIN == N_JOIN_FOLLOWS, "");
    1313                
     1313
    13141314                /* Keep the N_JOIN/N_JOIN_FOLLOWS mark but strip N_DELETED. */
    13151315                mark_t cur_mark = get_mark(cur->link) & N_JOIN_FOLLOWS;
    1316                
     1316
    13171317                marked_ptr_t ret =
    13181318                        cas_link(&cur->link, next, cur_mark, next, cur_mark | N_DELETED);
    1319                
     1319
    13201320                if (ret != make_link(next, cur_mark))
    13211321                        return false;
    13221322        }
    1323        
     1323
    13241324        return true;
    13251325}
     
    13311331        assert(wnd->cur != &sentinel);
    13321332        assert(wnd->cur && (N_DELETED & get_mark(wnd->cur->link)));
    1333        
     1333
    13341334        cht_link_t *next = get_next(wnd->cur->link);
    1335                
     1335
    13361336        if (walk_mode == WM_LEAVE_JOIN) {
    13371337                /* Never try to unlink join nodes. */
     
    13411341                /* Succeed only if the predecessor is clean/normal or a join node. */
    13421342                mark_t exp_pred_mark = (N_JOIN & pred_mark) ? pred_mark : N_NORMAL;
    1343                
     1343
    13441344                marked_ptr_t pred_link = make_link(wnd->cur, exp_pred_mark);
    13451345                marked_ptr_t next_link = make_link(next, exp_pred_mark);
    1346                
     1346
    13471347                if (pred_link != _cas_link(wnd->ppred, pred_link, next_link))
    13481348                        return false;
     
    13511351                /* Move the JF mark if set. Clear DEL mark. */
    13521352                mark_t cur_mark = N_JOIN_FOLLOWS & get_mark(wnd->cur->link);
    1353                
     1353
    13541354                /* The predecessor must be clean/normal. */
    13551355                marked_ptr_t pred_link = make_link(wnd->cur, N_NORMAL);
    13561356                /* Link to cur's successor keeping/copying cur's JF mark. */
    13571357                marked_ptr_t next_link = make_link(next, cur_mark);
    1358                
     1358
    13591359                marked_ptr_t ret = _cas_link(wnd->ppred, pred_link, next_link);
    1360                
     1360
    13611361                if (pred_link != ret) {
    13621362                        /* If we're not resizing the table there are no JF/JN nodes. */
     
    13661366                }
    13671367        }
    1368        
     1368
    13691369        return true;
    13701370}
     
    13991399{
    14001400        assert(wnd->cur);
    1401        
     1401
    14021402        if (wnd->cur == &sentinel)
    14031403                return true;
    1404        
     1404
    14051405        /*
    14061406         * A read barrier is not needed here to bring up the most recent
     
    14081408         * an already deleted node; fail in delete_at(); and retry.
    14091409         */
    1410        
     1410
    14111411        size_t cur_hash;
    14121412
    14131413try_again:
    14141414        cur_hash = node_hash(h, wnd->cur);
    1415                
     1415
    14161416        while (cur_hash <= hash) {
    14171417                assert(wnd->cur && wnd->cur != &sentinel);
    1418                
     1418
    14191419                /* GC any deleted nodes on the way. */
    14201420                if (N_DELETED & get_mark(wnd->cur->link)) {
     
    14271427                        if (cur_hash == hash && pred(pred_arg, wnd->cur))
    14281428                                return true;
    1429                        
     1429
    14301430                        next_wnd(wnd);
    14311431                }
    1432                
     1432
    14331433                cur_hash = node_hash(h, wnd->cur);
    14341434        }
    1435        
     1435
    14361436        if (cur_hash == h->invalid_hash) {
    14371437                next_wnd(wnd);
     
    14391439                goto try_again;
    14401440        }
    1441        
     1441
    14421442        /* The searched for node is not in the current bucket. */
    14431443        return true;
     
    14811481                        next_wnd(wnd);
    14821482                }
    1483                
     1483
    14841484                assert(wnd->cur);
    14851485        }
    1486        
     1486
    14871487        if (node_hash(h, wnd->cur) == h->invalid_hash) {
    14881488                next_wnd(wnd);
     
    15201520                wnd->cur = get_next(wnd->cur->link);
    15211521        }
    1522        
     1522
    15231523        return true;
    15241524}
     
    15391539         * is visible and if not, make it visible to this cpu.
    15401540         */
    1541        
     1541
    15421542        /*
    15431543         * Resizer ensures h->b->order stays the same for the duration of this
     
    15481548        assert(h->b->order > h->new_b->order);
    15491549        assert(wnd->cur);
    1550        
     1550
    15511551        /* Either we did not need the joining link or we have already followed it.*/
    15521552        if (wnd->cur != &sentinel)
    15531553                return true;
    1554        
     1554
    15551555        /* We have reached the end of a bucket. */
    1556        
     1556
    15571557        if (wnd->last != &sentinel) {
    15581558                size_t last_seen_hash = node_hash(h, wnd->last);
    1559                
     1559
    15601560                if (last_seen_hash == h->invalid_hash) {
    15611561                        last_seen_hash = calc_node_hash(h, wnd->last);
    15621562                }
    1563                
     1563
    15641564                size_t last_old_idx = calc_bucket_idx(last_seen_hash, h->b->order);
    15651565                size_t move_src_idx = grow_idx(shrink_idx(last_old_idx));
    1566                
     1566
    15671567                /*
    15681568                 * Last node seen was in the joining bucket - if the searched
     
    15721572                        return true;
    15731573        }
    1574        
     1574
    15751575        /*
    15761576         * Reached the end of the bucket but no nodes from the joining bucket
     
    16031603        size_t old_idx = calc_bucket_idx(hash, b->order);
    16041604        size_t new_idx = calc_bucket_idx(hash, h->new_b->order);
    1605        
     1605
    16061606        marked_ptr_t *pold_head = &b->head[old_idx];
    16071607        marked_ptr_t *pnew_head = &h->new_b->head[new_idx];
    1608        
     1608
    16091609        /* In any case, use the bucket in the new table. */
    16101610        *phead = pnew_head;
     
    16141614                size_t move_dest_idx = grow_idx(old_idx);
    16151615                marked_ptr_t *pmoved_head = &h->new_b->head[move_dest_idx];
    1616                
     1616
    16171617                /* Complete moving the bucket from the old to the new table. */
    16181618                help_head_move(pold_head, pmoved_head);
    1619                
     1619
    16201620                /* The hash belongs to the moved bucket. */
    16211621                if (move_dest_idx == new_idx) {
     
    16341634                         * half of the split/old/moved bucket.
    16351635                         */
    1636                        
     1636
    16371637                        /* The moved bucket has not yet been split. */
    16381638                        if (N_NORMAL != get_mark(*pnew_head)) {
     
    16451645                                assert(N_NORMAL == get_mark(*pnew_head));
    16461646                        }
    1647                        
     1647
    16481648                        *walk_mode = WM_LEAVE_JOIN;
    16491649                }
    16501650        } else if (h->new_b->order < b->order ) {
    16511651                /* Shrinking the table. */
    1652                
     1652
    16531653                size_t move_src_idx = grow_idx(new_idx);
    1654                
     1654
    16551655                /*
    16561656                 * Complete moving the bucket from the old to the new table.
     
    16581658                 */
    16591659                help_head_move(&b->head[move_src_idx], pnew_head);
    1660                
     1660
    16611661                /* Hash belongs to the bucket to be joined with the moved bucket. */
    16621662                if (move_src_idx != old_idx) {
     
    16661666                                join_buckets(h, pold_head, pnew_head, split_hash);
    16671667                        }
    1668                        
     1668
    16691669                        /*
    16701670                         * The resizer sets pold_head to &sentinel when all cpus are
     
    16731673                        *join_finishing = (&sentinel != get_next(*pold_head));
    16741674                }
    1675                
     1675
    16761676                /* move_head() or join_buckets() makes it so or makes the mark visible.*/
    16771677                assert(N_INVALID == get_mark(*pold_head));
     
    17131713        /* Head move has to in progress already when calling this func. */
    17141714        assert(N_CONST & get_mark(*psrc_head));
    1715        
     1715
    17161716        /* Head already moved. */
    17171717        if (N_INVALID == get_mark(*psrc_head)) {
     
    17241724                complete_head_move(psrc_head, pdest_head);
    17251725        }
    1726        
     1726
    17271727        assert(!(N_CONST & get_mark(*pdest_head)));
    17281728}
     
    17421742{
    17431743        marked_ptr_t ret, src_link;
    1744        
     1744
    17451745        /* Mark src head immutable. */
    17461746        do {
    17471747                cht_link_t *next = get_next(*psrc_head);
    17481748                src_link = make_link(next, N_NORMAL);
    1749                
     1749
    17501750                /* Mark the normal/clean src link immutable/const. */
    17511751                ret = cas_link(psrc_head, next, N_NORMAL, next, N_CONST);
     
    17581758        assert(N_JOIN_FOLLOWS != get_mark(*psrc_head));
    17591759        assert(N_CONST & get_mark(*psrc_head));
    1760        
     1760
    17611761        cht_link_t *next = get_next(*psrc_head);
    17621762
     
    17651765        assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
    17661766        cas_order_barrier();
    1767        
     1767
    17681768        DBG(ret = )
    17691769                cas_link(psrc_head, next, N_CONST, next, N_INVALID);
     
    17911791        if (N_NORMAL == get_mark(*pdest_head))
    17921792                return;
    1793        
     1793
    17941794        /*
    17951795         * L == Last node of the first part of the split bucket. That part
     
    18361836         */
    18371837        wnd_t wnd;
    1838        
     1838
    18391839        rcu_read_lock();
    1840        
     1840
    18411841        /* Mark the last node of the first part of the split bucket as JF. */
    18421842        mark_join_follows(h, psrc_head, split_hash, &wnd);
    18431843        cas_order_barrier();
    1844        
     1844
    18451845        /* There are nodes in the dest bucket, ie the second part of the split. */
    18461846        if (wnd.cur != &sentinel) {
     
    18571857                 */
    18581858        }
    1859        
     1859
    18601860        /* Link the dest head to the second part of the split. */
    18611861        DBG(marked_ptr_t ret = )
     
    18631863        assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
    18641864        cas_order_barrier();
    1865        
     1865
    18661866        rcu_read_unlock();
    18671867}
     
    18881888{
    18891889        /* See comment in split_bucket(). */
    1890        
     1890
    18911891        bool done = false;
    18921892
     
    18951895                wnd->ppred = psrc_head;
    18961896                wnd->cur = get_next(*psrc_head);
    1897                
     1897
    18981898                /*
    18991899                 * Find the split window, ie the last node of the first part of
     
    19031903                if (!find_wnd_and_gc(h, split_hash, WM_MOVE_JOIN_FOLLOWS, wnd, &resizing))
    19041904                        continue;
    1905                
     1905
    19061906                /* Must not report that the table is resizing if WM_MOVE_JOIN_FOLLOWS.*/
    19071907                assert(!resizing);
     
    19261926{
    19271927        /* See comment in split_bucket(). */
    1928        
     1928
    19291929        bool done;
    19301930        do {
    19311931                cht_link_t *next = get_next(join_node->link);
    19321932                mark_t mark = get_mark(join_node->link);
    1933                
     1933
    19341934                /*
    19351935                 * May already be marked as deleted, but it won't be unlinked
     
    19381938                marked_ptr_t ret
    19391939                        = cas_link(&join_node->link, next, mark, next, mark | N_JOIN);
    1940                
     1940
    19411941                /* Successfully marked or already marked as a join node. */
    19421942                done = (ret == make_link(next, mark))
     
    20232023         *  [src_head | Inv]-----------> [JN] -> ..
    20242024         */
    2025        
     2025
    20262026        rcu_read_lock();
    2027        
     2027
    20282028        /* Mark src_head immutable - signals updaters that bucket join started. */
    20292029        mark_const(psrc_head);
    20302030        cas_order_barrier();
    2031        
     2031
    20322032        cht_link_t *join_node = get_next(*psrc_head);
    20332033
     
    20352035                mark_join_node(join_node);
    20362036                cas_order_barrier();
    2037                
     2037
    20382038                link_to_join_node(h, pdest_head, join_node, split_hash);
    20392039                cas_order_barrier();
    20402040        }
    2041        
     2041
    20422042        DBG(marked_ptr_t ret = )
    20432043                cas_link(psrc_head, join_node, N_CONST, join_node, N_INVALID);
    20442044        assert(ret == make_link(join_node, N_CONST) || (N_INVALID == get_mark(ret)));
    20452045        cas_order_barrier();
    2046        
     2046
    20472047        rcu_read_unlock();
    20482048}
     
    20672067                        .cur = get_next(*pdest_head)
    20682068                };
    2069                
     2069
    20702070                bool resizing = false;
    2071                
     2071
    20722072                if (!find_wnd_and_gc(h, split_hash, WM_LEAVE_JOIN, &wnd, &resizing))
    20732073                        continue;
    20742074
    20752075                assert(!resizing);
    2076                
     2076
    20772077                if (wnd.cur != &sentinel) {
    20782078                        /* Must be from the new appended bucket. */
     
    20812081                        return;
    20822082                }
    2083                
     2083
    20842084                /* Reached the tail of pdest_head - link it to the join node. */
    20852085                marked_ptr_t ret =
    20862086                        cas_link(wnd.ppred, &sentinel, N_NORMAL, join_node, N_NORMAL);
    2087                
     2087
    20882088                done = (ret == make_link(&sentinel, N_NORMAL));
    20892089        } while (!done);
     
    20972097{
    20982098        assert(item != &sentinel);
    2099        
     2099
    21002100        /*
    21012101         * remove_callback only works as rcu_func_t because rcu_link is the first
     
    21032103         */
    21042104        rcu_call(&item->rcu_link, (rcu_func_t)h->op->remove_callback);
    2105        
     2105
    21062106        item_removed(h);
    21072107}
     
    21162116        size_t items = (size_t) atomic_predec(&h->item_cnt);
    21172117        size_t bucket_cnt = (1 << h->b->order);
    2118        
     2118
    21192119        bool need_shrink = (items == h->max_load * bucket_cnt / 4);
    21202120        bool missed_shrink = (items == h->max_load * bucket_cnt / 8);
    2121        
     2121
    21222122        if ((need_shrink || missed_shrink) && h->b->order > h->min_order) {
    21232123                atomic_count_t resize_reqs = atomic_preinc(&h->resize_reqs);
     
    21372137        size_t items = (size_t) atomic_preinc(&h->item_cnt);
    21382138        size_t bucket_cnt = (1 << h->b->order);
    2139        
     2139
    21402140        bool need_grow = (items == h->max_load * bucket_cnt);
    21412141        bool missed_grow = (items == 2 * h->max_load * bucket_cnt);
    2142        
     2142
    21432143        if ((need_grow || missed_grow) && h->b->order < CHT_MAX_ORDER) {
    21442144                atomic_count_t resize_reqs = atomic_preinc(&h->resize_reqs);
     
    21542154{
    21552155        cht_t *h = member_to_inst(arg, cht_t, resize_work);
    2156        
     2156
    21572157#ifdef CONFIG_DEBUG
    21582158        assert(h->b);
     
    21882188        if (h->b->order >= CHT_MAX_ORDER)
    21892189                return;
    2190        
     2190
    21912191        h->new_b = alloc_buckets(h->b->order + 1, true, false);
    21922192
     
    21982198        rcu_synchronize();
    21992199        size_t old_bucket_cnt = (1 << h->b->order);
    2200        
     2200
    22012201        /*
    22022202         * Give updaters a chance to help out with the resize. Do the minimum
     
    22062206                start_head_move(&h->b->head[idx]);
    22072207        }
    2208        
     2208
    22092209        /* Order start_head_move() wrt complete_head_move(). */
    22102210        cas_order_barrier();
    2211        
     2211
    22122212        /* Complete moving heads and split any buckets not yet split by updaters. */
    22132213        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
     
    22262226                split_bucket(h, move_dest_head, split_dest_head, split_hash);
    22272227        }
    2228        
     2228
    22292229        /*
    22302230         * Wait for all updaters to notice the new heads. Once everyone sees
     
    22332233         */
    22342234        rcu_synchronize();
    2235        
     2235
    22362236        /* Clear the JOIN_FOLLOWS mark and remove the link between the split buckets.*/
    22372237        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
    22382238                size_t new_idx = grow_idx(old_idx);
    2239                
     2239
    22402240                cleanup_join_follows(h, &h->new_b->head[new_idx]);
    22412241        }
     
    22462246         */
    22472247        rcu_synchronize();
    2248        
     2248
    22492249        /* Clear the JOIN mark and GC any deleted join nodes. */
    22502250        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
    22512251                size_t new_idx = grow_to_split_idx(old_idx);
    2252                
     2252
    22532253                cleanup_join_node(h, &h->new_b->head[new_idx]);
    22542254        }
     
    22562256        /* Wait for everyone to see that the table is clear of any resize marks. */
    22572257        rcu_synchronize();
    2258        
     2258
    22592259        cht_buckets_t *old_b = h->b;
    22602260        rcu_assign(h->b, h->new_b);
     
    22622262        /* Wait for everyone to start using the new table. */
    22632263        rcu_synchronize();
    2264        
     2264
    22652265        free(old_b);
    2266        
     2266
    22672267        /* Not needed; just for increased readability. */
    22682268        h->new_b = NULL;
     
    22742274        if (h->b->order <= h->min_order)
    22752275                return;
    2276        
     2276
    22772277        h->new_b = alloc_buckets(h->b->order - 1, true, false);
    22782278
     
    22832283        /* Wait for all readers and updaters to see the initialized new table. */
    22842284        rcu_synchronize();
    2285        
     2285
    22862286        size_t old_bucket_cnt = (1 << h->b->order);
    2287        
     2287
    22882288        /*
    22892289         * Give updaters a chance to help out with the resize. Do the minimum
     
    22922292        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
    22932293                size_t new_idx = shrink_idx(old_idx);
    2294                
     2294
    22952295                /* This bucket should be moved. */
    22962296                if (grow_idx(new_idx) == old_idx) {
     
    23002300                }
    23012301        }
    2302        
     2302
    23032303        /* Order start_head_move() wrt to complete_head_move(). */
    23042304        cas_order_barrier();
    2305        
     2305
    23062306        /* Complete moving heads and join buckets with the moved buckets. */
    23072307        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
    23082308                size_t new_idx = shrink_idx(old_idx);
    23092309                size_t move_src_idx = grow_idx(new_idx);
    2310                
     2310
    23112311                /* This bucket should be moved. */
    23122312                if (move_src_idx == old_idx) {
     
    23222322                }
    23232323        }
    2324        
     2324
    23252325        /*
    23262326         * Wait for all updaters to notice the new heads. Once everyone sees
     
    23292329         */
    23302330        rcu_synchronize();
    2331        
     2331
    23322332        /* Let everyone know joins are complete and fully visible. */
    23332333        for (size_t old_idx = 0; old_idx < old_bucket_cnt; ++old_idx) {
    23342334                size_t move_src_idx = grow_idx(shrink_idx(old_idx));
    2335        
     2335
    23362336                /* Set the invalid joinee head to NULL. */
    23372337                if (old_idx != move_src_idx) {
    23382338                        assert(N_INVALID == get_mark(h->b->head[old_idx]));
    2339                        
     2339
    23402340                        if (&sentinel != get_next(h->b->head[old_idx]))
    23412341                                h->b->head[old_idx] = make_link(&sentinel, N_INVALID);
    23422342                }
    23432343        }
    2344        
     2344
    23452345        /* todo comment join node vs reset joinee head*/
    23462346        rcu_synchronize();
    23472347
    23482348        size_t new_bucket_cnt = (1 << h->new_b->order);
    2349                
     2349
    23502350        /* Clear the JOIN mark and GC any deleted join nodes. */
    23512351        for (size_t new_idx = 0; new_idx < new_bucket_cnt; ++new_idx) {
     
    23552355        /* Wait for everyone to see that the table is clear of any resize marks. */
    23562356        rcu_synchronize();
    2357        
     2357
    23582358        cht_buckets_t *old_b = h->b;
    23592359        rcu_assign(h->b, h->new_b);
    2360        
     2360
    23612361        /* Wait for everyone to start using the new table. */
    23622362        rcu_synchronize();
    2363        
     2363
    23642364        free(old_b);
    2365        
     2365
    23662366        /* Not needed; just for increased readability. */
    23672367        h->new_b = NULL;
     
    23742374
    23752375        cht_link_t *cur = get_next(*new_head);
    2376                
     2376
    23772377        while (cur != &sentinel) {
    23782378                /* Clear the join node's JN mark - even if it is marked as deleted. */
     
    23812381                        break;
    23822382                }
    2383                
     2383
    23842384                cur = get_next(cur->link);
    23852385        }
    2386        
     2386
    23872387        rcu_read_unlock();
    23882388}
     
    23942394        assert(join_node != &sentinel);
    23952395        assert(join_node && (N_JOIN & get_mark(join_node->link)));
    2396        
     2396
    23972397        bool done;
    2398        
     2398
    23992399        /* Clear the JN mark. */
    24002400        do {
     
    24112411                assert(ret == jn_link || (get_mark(ret) & N_JOIN));
    24122412        } while (!done);
    2413        
     2413
    24142414        if (!(N_DELETED & get_mark(join_node->link)))
    24152415                return;
     
    24192419        /* Clear the JOIN mark before trying to unlink the deleted join node.*/
    24202420        cas_order_barrier();
    2421        
     2421
    24222422        size_t jn_hash = node_hash(h, join_node);
    24232423        do {
    24242424                bool resizing = false;
    2425                
     2425
    24262426                wnd_t wnd = {
    24272427                        .ppred = new_head,
    24282428                        .cur = get_next(*new_head)
    24292429                };
    2430                
     2430
    24312431                done = find_wnd_and_gc_pred(h, jn_hash, WM_NORMAL, same_node_pred,
    24322432                        join_node, &wnd, &resizing);
    2433                
     2433
    24342434                assert(!resizing);
    24352435        } while (!done);
     
    24402440{
    24412441        assert(new_head);
    2442        
     2442
    24432443        rcu_read_lock();
    24442444
     
    24482448        };
    24492449        marked_ptr_t *cur_link = new_head;
    2450                
     2450
    24512451        /*
    24522452         * Find the non-deleted node with a JF mark and clear the JF mark.
     
    24612461        while (true) {
    24622462                bool is_jf_node = N_JOIN_FOLLOWS & get_mark(*cur_link);
    2463                
     2463
    24642464                /* GC any deleted nodes on the way - even deleted JOIN_FOLLOWS. */
    24652465                if (N_DELETED & get_mark(*cur_link)) {
     
    24832483                                marked_ptr_t ret =
    24842484                                        cas_link(cur_link, next, N_JOIN_FOLLOWS, &sentinel, N_NORMAL);
    2485                                
     2485
    24862486                                assert(next == &sentinel
    24872487                                        || ((N_JOIN | N_JOIN_FOLLOWS) & get_mark(ret)));
     
    25082508                cur_link = &wnd.cur->link;
    25092509        }
    2510        
     2510
    25112511        rcu_read_unlock();
    25122512}
     
    25612561                || item->hash == sentinel.hash
    25622562                || item->hash == calc_node_hash(h, item));
    2563        
     2563
    25642564        return item->hash;
    25652565}
     
    25862586{
    25872587        marked_ptr_t ptr = (marked_ptr_t) next;
    2588        
     2588
    25892589        assert(!(ptr & N_MARK_MASK));
    25902590        assert(!((unsigned)mark & ~N_MARK_MASK));
    2591        
     2591
    25922592        return ptr | mark;
    25932593}
     
    26902690         */
    26912691        void *expected = (void*)cur;
    2692        
     2692
    26932693        /*
    26942694         * Use the acquire-release model, although we could probably
     
    26982698        __atomic_compare_exchange_n((void**)link, &expected, (void *)new, false,
    26992699                __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
    2700        
     2700
    27012701        return (marked_ptr_t) expected;
    27022702}
  • kernel/generic/src/adt/hash_table.c

    r3061bc1 ra35b458  
    9696        assert(h);
    9797        assert(op && op->hash && op->key_hash && op->key_equal);
    98        
     98
    9999        /* Check for compulsory ops. */
    100100        if (!op || !op->hash || !op->key_hash || !op->key_equal)
    101101                return false;
    102        
     102
    103103        h->bucket_cnt = round_up_size(init_size);
    104        
     104
    105105        if (!alloc_table(h->bucket_cnt, &h->bucket))
    106106                return false;
    107        
     107
    108108        h->max_load = (max_load == 0) ? HT_MAX_LOAD : max_load;
    109109        h->item_cnt = 0;
     
    115115                h->op->remove_callback = nop_remove_callback;
    116116        }
    117        
     117
    118118        return true;
    119119}
     
    128128        assert(h && h->bucket);
    129129        assert(!h->apply_ongoing);
    130        
     130
    131131        clear_items(h);
    132        
     132
    133133        free(h->bucket);
    134134
     
    159159        assert(h && h->bucket);
    160160        assert(!h->apply_ongoing);
    161        
     161
    162162        clear_items(h);
    163        
     163
    164164        /* Shrink the table to its minimum size if possible. */
    165165        if (HT_MIN_BUCKETS < h->bucket_cnt) {
     
    173173        if (h->item_cnt == 0)
    174174                return;
    175        
     175
    176176        for (size_t idx = 0; idx < h->bucket_cnt; ++idx) {
    177177                list_foreach_safe(h->bucket[idx], cur, next) {
    178178                        assert(cur);
    179179                        ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
    180                        
     180
    181181                        list_remove(cur);
    182182                        h->op->remove_callback(cur_link);
    183183                }
    184184        }
    185        
     185
    186186        h->item_cnt = 0;
    187187}
     
    197197        assert(h && h->bucket);
    198198        assert(!h->apply_ongoing);
    199        
     199
    200200        size_t idx = h->op->hash(item) % h->bucket_cnt;
    201        
     201
    202202        list_append(&item->link, &h->bucket[idx]);
    203203        ++h->item_cnt;
     
    220220        assert(h->op && h->op->hash && h->op->equal);
    221221        assert(!h->apply_ongoing);
    222        
     222
    223223        size_t idx = h->op->hash(item) % h->bucket_cnt;
    224        
     224
    225225        /* Check for duplicates. */
    226226        list_foreach(h->bucket[idx], link, ht_link_t, cur_link) {
     
    232232                        return false;
    233233        }
    234        
     234
    235235        list_append(&item->link, &h->bucket[idx]);
    236236        ++h->item_cnt;
    237237        grow_if_needed(h);
    238        
     238
    239239        return true;
    240240}
     
    251251{
    252252        assert(h && h->bucket);
    253        
     253
    254254        size_t idx = h->op->key_hash(key) % h->bucket_cnt;
    255255
     
    264264                }
    265265        }
    266        
     266
    267267        return NULL;
    268268}
     
    305305        assert(h && h->bucket);
    306306        assert(!h->apply_ongoing);
    307        
     307
    308308        size_t idx = h->op->key_hash(key) % h->bucket_cnt;
    309309
    310310        size_t removed = 0;
    311        
     311
    312312        list_foreach_safe(h->bucket[idx], cur, next) {
    313313                ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
    314                
     314
    315315                if (h->op->key_equal(key, cur_link)) {
    316316                        ++removed;
     
    322322        h->item_cnt -= removed;
    323323        shrink_if_needed(h);
    324        
     324
    325325        return removed;
    326326}
     
    352352        assert(f);
    353353        assert(h && h->bucket);
    354        
     354
    355355        if (h->item_cnt == 0)
    356356                return;
    357        
     357
    358358        h->apply_ongoing = true;
    359        
     359
    360360        for (size_t idx = 0; idx < h->bucket_cnt; ++idx) {
    361361                list_foreach_safe(h->bucket[idx], cur, next) {
     
    371371out:
    372372        h->apply_ongoing = false;
    373        
     373
    374374        shrink_if_needed(h);
    375375        grow_if_needed(h);
     
    380380{
    381381        size_t rounded_size = HT_MIN_BUCKETS;
    382        
     382
    383383        while (rounded_size < size) {
    384384                rounded_size = 2 * rounded_size + 1;
    385385        }
    386        
     386
    387387        return rounded_size;
    388388}
     
    392392{
    393393        assert(pbuckets && HT_MIN_BUCKETS <= bucket_cnt);
    394                
     394
    395395        list_t *buckets = malloc(bucket_cnt * sizeof(list_t), FRAME_ATOMIC);
    396396        if (!buckets)
    397397                return false;
    398        
     398
    399399        for (size_t i = 0; i < bucket_cnt; i++)
    400400                list_initialize(&buckets[i]);
     
    434434        assert(h && h->bucket);
    435435        assert(HT_MIN_BUCKETS <= new_bucket_cnt);
    436        
     436
    437437        /* We are traversing the table and resizing would mess up the buckets. */
    438438        if (h->apply_ongoing)
    439439                return;
    440        
     440
    441441        list_t *new_buckets;
    442442
     
    444444        if (!alloc_table(new_bucket_cnt, &new_buckets))
    445445                return;
    446        
     446
    447447        if (0 < h->item_cnt) {
    448448                /* Rehash all the items to the new table. */
     
    457457                }
    458458        }
    459        
     459
    460460        free(h->bucket);
    461461        h->bucket = new_buckets;
  • kernel/generic/src/adt/list.c

    r3061bc1 ra35b458  
    5656        bool found = false;
    5757        link_t *hlp = list->head.next;
    58        
     58
    5959        while (hlp != &list->head) {
    6060                if (hlp == link) {
     
    6464                hlp = hlp->next;
    6565        }
    66        
     66
    6767        return found;
    6868}
     
    8080        if (list_empty(list))
    8181                return;
    82        
     82
    8383        /* Attach list to destination. */
    8484        list->head.next->prev = pos;
    8585        list->head.prev->next = pos->next;
    86        
     86
    8787        /* Link destination list to the added list. */
    8888        pos->next->prev = list->head.prev;
    8989        pos->next = list->head.next;
    90        
     90
    9191        list_initialize(list);
    9292}
     
    102102{
    103103        unsigned long count = 0;
    104        
     104
    105105        link_t *link = list_first(list);
    106106        while (link != NULL) {
     
    108108                link = list_next(link, list);
    109109        }
    110        
     110
    111111        return count;
    112112}
Note: See TracChangeset for help on using the changeset viewer.