Changeset 8565a42 in mainline for kernel/generic/src/adt


Ignore:
Timestamp:
2018-03-02T20:34:50Z (8 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a1a81f69, d5e5fd1
Parents:
3061bc1 (diff), 34e1206 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:34:50)
git-committer:
GitHub <noreply@…> (2018-03-02 20:34:50)
Message:

Remove all trailing whitespace, everywhere.

See individual commit messages for details.

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

Legend:

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

    r3061bc1 r8565a42  
    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 r8565a42  
    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 r8565a42  
    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 r8565a42  
    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 r8565a42  
    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 r8565a42  
    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.