Changeset 82cbf8c6 in mainline for kernel/generic/src/lib/ra.c


Ignore:
Timestamp:
2017-10-08T19:37:24Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2fd26bb
Parents:
81b9d3e
Message:

Replace the old hash table implementation in the kernel with the newer one

This replaces the original hash table implementation with the resizable one
already used in uspace. Along the way, the IRQ hash table code was streamlined
and cleaned up.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/lib/ra.c

    r81b9d3e r82cbf8c6  
    5050#include <panic.h>
    5151#include <adt/list.h>
     52#include <adt/hash.h>
    5253#include <adt/hash_table.h>
    5354#include <align.h>
     
    5758static slab_cache_t *ra_segment_cache;
    5859
    59 #define USED_BUCKETS    1024
    60 
    61 static size_t used_hash(sysarg_t *key)
    62 {
    63         return ((*key >> 2) & (USED_BUCKETS - 1));
    64 }
    65 
    66 static bool used_compare(sysarg_t *key, size_t keys, link_t *item)
    67 {
    68         ra_segment_t *seg;
    69 
    70         seg = hash_table_get_instance(item, ra_segment_t, fu_link);
    71         return seg->base == *key;
    72 }
    73 
    74 static hash_table_operations_t used_ops = {
     60/** Return the hash of the key stored in the item */
     61static size_t used_hash(const ht_link_t *item)
     62{
     63        ra_segment_t *seg = hash_table_get_inst(item, ra_segment_t, uh_link);
     64        return hash_mix(seg->base);
     65}
     66
     67/** Return the hash of the key */
     68static size_t used_key_hash(void *key)
     69{
     70        uintptr_t *base = (uintptr_t *) key;
     71        return hash_mix(*base);
     72}
     73
     74/** Return true if the key is equal to the item's lookup key */
     75static bool used_key_equal(void *key, const ht_link_t *item)
     76{
     77        uintptr_t *base = (sysarg_t *) key;
     78        ra_segment_t *seg = hash_table_get_inst(item, ra_segment_t, uh_link);
     79        return seg->base == *base;
     80}
     81
     82static hash_table_ops_t used_ops = {
    7583        .hash = used_hash,
    76         .compare = used_compare,
    77         .remove_callback = NULL,
     84        .key_hash = used_key_hash,
     85        .key_equal = used_key_equal
    7886};
    7987
     
    97105
    98106        link_initialize(&seg->segment_link);
    99         link_initialize(&seg->fu_link);
     107        link_initialize(&seg->fl_link);
    100108
    101109        seg->base = base;
     
    160168        list_initialize(&span->segments);
    161169
    162         hash_table_create(&span->used, USED_BUCKETS, 1, &used_ops);
     170        hash_table_create(&span->used, 0, 0, &used_ops);
    163171
    164172        for (i = 0; i <= span->max_order; i++)
     
    171179
    172180        /* Insert the first segment into the respective free list. */
    173         list_append(&seg->fu_link, &span->free[span->max_order]);
     181        list_append(&seg->fl_link, &span->free[span->max_order]);
    174182
    175183        return span;
     
    232240                /* Take the first segment from the free list. */
    233241                seg = list_get_instance(list_first(&span->free[order]),
    234                     ra_segment_t, fu_link);
     242                    ra_segment_t, fl_link);
    235243
    236244                assert(seg->flags & RA_SEGMENT_FREE);
     
    274282                            &seg->segment_link);
    275283                        pred_order = fnzb(ra_segment_size_get(pred));
    276                         list_append(&pred->fu_link, &span->free[pred_order]);
     284                        list_append(&pred->fl_link, &span->free[pred_order]);
    277285                }
    278286                if (succ) {
     
    282290                            &seg->segment_link);
    283291                        succ_order = fnzb(ra_segment_size_get(succ));
    284                         list_append(&succ->fu_link, &span->free[succ_order]);
     292                        list_append(&succ->fl_link, &span->free[succ_order]);
    285293                }
    286294
    287295                /* Now remove the found segment from the free list. */
    288                 list_remove(&seg->fu_link);
     296                list_remove(&seg->fl_link);
    289297                seg->base = newbase;
    290298                seg->flags &= ~RA_SEGMENT_FREE;
    291299
    292300                /* Hash-in the segment into the used hash. */
    293                 sysarg_t key = seg->base;
    294                 hash_table_insert(&span->used, &key, &seg->fu_link);
     301                hash_table_insert(&span->used, &seg->uh_link);
    295302
    296303                *base = newbase;
     
    304311{
    305312        sysarg_t key = base;
    306         link_t *link;
     313        ht_link_t *link;
    307314        ra_segment_t *seg;
    308315        ra_segment_t *pred;
     
    318325                    PRIxn ", size=%" PRIdn ").", base, size);
    319326        }
    320         seg = hash_table_get_instance(link, ra_segment_t, fu_link);
     327        seg = hash_table_get_inst(link, ra_segment_t, uh_link);
    321328
    322329        /*
    323330         * Hash out the segment.
    324331         */
    325         hash_table_remove(&span->used, &key, 1);
     332        hash_table_remove_item(&span->used, link);
    326333
    327334        assert(!(seg->flags & RA_SEGMENT_FREE));
     
    333340         */
    334341        if (list_first(&span->segments) != &seg->segment_link) {
    335                 pred = hash_table_get_instance(seg->segment_link.prev,
     342                pred = hash_table_get_inst(seg->segment_link.prev,
    336343                    ra_segment_t, segment_link);
    337344
     
    345352                         * away.
    346353                         */
    347                         list_remove(&pred->fu_link);
     354                        list_remove(&pred->fl_link);
    348355                        list_remove(&pred->segment_link);
    349356                        seg->base = pred->base;
     
    355362         * Check whether the segment can be coalesced with its right neighbor.
    356363         */
    357         succ = hash_table_get_instance(seg->segment_link.next, ra_segment_t,
     364        succ = hash_table_get_inst(seg->segment_link.next, ra_segment_t,
    358365            segment_link);
    359366        assert(succ->base > seg->base);
     
    364371                 * and throw it away.
    365372                 */
    366                 list_remove(&succ->fu_link);
     373                list_remove(&succ->fl_link);
    367374                list_remove(&succ->segment_link);
    368375                ra_segment_destroy(succ);
     
    372379        seg->flags |= RA_SEGMENT_FREE;
    373380        order = fnzb(ra_segment_size_get(seg));
    374         list_append(&seg->fu_link, &span->free[order]);
     381        list_append(&seg->fl_link, &span->free[order]);
    375382}
    376383
Note: See TracChangeset for help on using the changeset viewer.