Changeset bc216a0 in mainline for uspace/srv/ns


Ignore:
Timestamp:
2012-08-07T22:13:44Z (14 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
da68871a
Parents:
b17518e
Message:

Refactored any users of hash_table to use opaque void* keys instead of the cumbersome unsigned long[] keys. Switched from the ad hoc computations of hashes of multiple values to hash_combine().

Location:
uspace/srv/ns
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/ns/service.c

    rb17518e rbc216a0  
    4343/** Service hash table item. */
    4444typedef struct {
    45         link_t link;
     45        ht_link_t link;
    4646        sysarg_t service;        /**< Service ID. */
    4747        sysarg_t phone;          /**< Phone registered with the service. */
     
    4949} hashed_service_t;
    5050
    51 /** Compute hash index into service hash table.
    52  *
    53  * @param key Pointer keys. However, only the first key (i.e. service number)
    54  *            is used to compute the hash index.
    55  *
    56  * @return Hash index corresponding to key[0].
    57  *
    58  */
    59 static size_t service_key_hash(unsigned long key[])
     51
     52static size_t service_key_hash(void *key)
    6053{
    61         assert(key);
    62         return key[0];
     54        return *(sysarg_t*)key;
    6355}
    6456
    65 static size_t service_hash(const link_t *item)
     57static size_t service_hash(const ht_link_t *item)
    6658{
    67         hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link);
    68         unsigned long key = hs->service;
    69         return service_key_hash(&key);
     59        hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link);
     60        return hs->service;
    7061}
    7162
    72 /** Compare a key with hashed item.
    73  *
    74  * This compare function always ignores the third key.
    75  * It exists only to make it possible to remove records
    76  * originating from connection with key[1] in_phone_hash
    77  * value. Note that this is close to being classified
    78  * as a nasty hack.
    79  *
    80  * @param key  Array of keys.
    81  * @param keys Must be lesser or equal to 3.
    82  * @param item Pointer to a hash table item.
    83  *
    84  * @return Non-zero if the key matches the item, zero otherwise.
    85  *
    86  */
    87 static bool service_match(unsigned long key[], size_t keys, const link_t *item)
     63static bool service_key_equal(void *key, const ht_link_t *item)
    8864{
    89         assert(key);
    90         assert(keys <= 3);
    91         assert(item);
    92        
    93         hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link);
    94        
    95         if (keys == 2)
    96                 return ((key[0] == hs->service) && (key[1] == hs->in_phone_hash));
    97         else
    98                 return (key[0] == hs->service);
    99 }
    100 
    101 /** Perform actions after removal of item from the hash table.
    102  *
    103  * @param item Item that was removed from the hash table.
    104  *
    105  */
    106 static void service_remove(link_t *item)
    107 {
    108         assert(item);
    109         free(hash_table_get_instance(item, hashed_service_t, link));
     65        hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link);
     66        return hs->service == *(sysarg_t*)key;
    11067}
    11168
     
    11471        .hash = service_hash,
    11572        .key_hash = service_key_hash,
    116         .match = service_match,
     73        .key_equal = service_key_equal,
    11774        .equal = 0,
    118         .remove_callback = service_remove
     75        .remove_callback = 0
    11976};
    12077
     
    13592int service_init(void)
    13693{
    137         if (!hash_table_create(&service_hash_table, 0, 3, &service_hash_table_ops)) {
     94        if (!hash_table_create(&service_hash_table, 0, 0, &service_hash_table_ops)) {
    13895                printf(NAME ": No memory available for services\n");
    13996                return ENOMEM;
     
    152109                pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link);
    153110               
    154                 unsigned long keys[3] = {
    155                         pr->service,
    156                         0,
    157                         0
    158                 };
    159                
    160                 link_t *link = hash_table_find(&service_hash_table, keys);
     111                ht_link_t *link = hash_table_find(&service_hash_table, &pr->service);
    161112                if (!link)
    162113                        continue;
    163114               
    164                 hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
     115                hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link);
    165116                (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2,
    166117                    pr->arg3, 0, IPC_FF_NONE);
     
    183134int register_service(sysarg_t service, sysarg_t phone, ipc_call_t *call)
    184135{
    185         unsigned long keys[3] = {
    186                 service,
    187                 call->in_phone_hash,
    188                 0
    189         };
    190        
    191         if (hash_table_find(&service_hash_table, keys))
     136        if (hash_table_find(&service_hash_table, &service))
    192137                return EEXISTS;
    193138       
     
    196141                return ENOMEM;
    197142       
    198         link_initialize(&hs->link);
    199143        hs->service = service;
    200144        hs->phone = phone;
     
    217161{
    218162        sysarg_t retval;
    219         unsigned long keys[3] = {
    220                 service,
    221                 0,
    222                 0
    223         };
    224163       
    225         link_t *link = hash_table_find(&service_hash_table, keys);
     164        ht_link_t *link = hash_table_find(&service_hash_table, &service);
    226165        if (!link) {
    227166                if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) {
     
    246185        }
    247186       
    248         hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
     187        hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link);
    249188        (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
    250189            IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
  • uspace/srv/ns/task.c

    rb17518e rbc216a0  
    5353/** Task hash table item. */
    5454typedef struct {
    55         link_t link;
     55        ht_link_t link;
    5656       
    5757        task_id_t id;    /**< Task ID. */
     
    6161} hashed_task_t;
    6262
    63 /** Compute hash index into task hash table.
    64  *
    65  * @param key Pointer keys. However, only the first key (i.e. truncated task
    66  *            number) is used to compute the hash index.
    67  *
    68  * @return Hash index corresponding to key[0].
    69  *
    70  */
    71 static size_t task_key_hash(unsigned long key[])
    72 {
    73         size_t hash = 17;
    74         hash = 37 * hash + key[1];
    75         hash = 37 * hash + key[0];
    76         return hash;
    77 }
    78 
    79 static size_t task_hash(const link_t *item)
    80 {
    81         hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link);
    82 
    83         unsigned long key[] = {
    84                 LOWER32(ht->id),
    85                 UPPER32(ht->id)
    86         };
    87        
    88         return task_key_hash(key);
    89 }
    90 
    91 /** Compare a key with hashed item.
    92  *
    93  * @param key  Array of keys.
    94  * @param keys Must be less than or equal to 2.
    95  * @param item Pointer to a hash table item.
    96  *
    97  * @return Non-zero if the key matches the item, zero otherwise.
    98  *
    99  */
    100 static bool task_match(unsigned long key[], size_t keys, const link_t *item)
    101 {
    102         assert(key);
    103         assert(keys == 2);
    104         assert(item);
    105        
    106         hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link);
    107        
    108         return (key[0] == LOWER32(ht->id))
    109                 && (key[1] == UPPER32(ht->id));
    110 }
    111 
    112 /** Perform actions after removal of item from the hash table.
    113  *
    114  * @param item Item that was removed from the hash table.
    115  *
    116  */
    117 static void task_remove(link_t *item)
    118 {
    119         assert(item);
    120         free(hash_table_get_instance(item, hashed_task_t, link));
     63
     64static size_t task_key_hash(void *key)
     65{
     66        return *(task_id_t*)key;
     67}
     68
     69static size_t task_hash(const ht_link_t  *item)
     70{
     71        hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
     72        return ht->id;
     73}
     74
     75static bool task_key_equal(void *key, const ht_link_t *item)
     76{
     77        hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
     78        return ht->id == *(task_id_t*)key;
     79}
     80
     81/** Perform actions after removal of item from the hash table. */
     82static void task_remove(ht_link_t *item)
     83{
     84        free(hash_table_get_inst(item, hashed_task_t, link));
    12185}
    12286
     
    12589        .hash = task_hash,
    12690        .key_hash = task_key_hash,
    127         .match = task_match,
     91        .key_equal = task_key_equal,
    12892        .equal = 0,
    12993        .remove_callback = task_remove
     
    13498
    13599typedef struct {
    136         link_t link;
     100        ht_link_t link;
    137101        sysarg_t in_phone_hash;  /**< Incoming phone hash. */
    138102        task_id_t id;            /**< Task ID. */
    139103} p2i_entry_t;
    140104
    141 /** Compute hash index into task hash table.
    142  *
    143  * @param key Array of keys.
    144  *
    145  * @return Hash index corresponding to key[0].
    146  *
    147  */
    148 static size_t p2i_key_hash(unsigned long key[])
    149 {
    150         assert(key);
    151         return key[0];
    152 }
    153 
    154 static size_t p2i_hash(const link_t *item)
    155 {
    156         p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link);
    157         unsigned long key = entry->in_phone_hash;
    158         return p2i_key_hash(&key);
    159 }
    160 
    161 /** Compare a key with hashed item.
    162  *
    163  * @param key  Array of keys.
    164  * @param keys Must be less than or equal to 1.
    165  * @param item Pointer to a hash table item.
    166  *
    167  * @return Non-zero if the key matches the item, zero otherwise.
    168  *
    169  */
    170 static bool p2i_match(unsigned long key[], size_t keys, const link_t *item)
    171 {
    172         assert(key);
    173         assert(keys == 1);
     105/* phone-to-id hash table operations */
     106
     107static size_t p2i_key_hash(void *key)
     108{
     109        sysarg_t in_phone_hash = *(sysarg_t*)key;
     110        return in_phone_hash;
     111}
     112
     113static size_t p2i_hash(const ht_link_t *item)
     114{
     115        p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link);
     116        return entry->in_phone_hash;
     117}
     118
     119static bool p2i_key_equal(void *key, const ht_link_t *item)
     120{
     121        sysarg_t in_phone_hash = *(sysarg_t*)key;
     122        p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link);
     123       
     124        return (in_phone_hash == entry->in_phone_hash);
     125}
     126
     127/** Perform actions after removal of item from the hash table.
     128 *
     129 * @param item Item that was removed from the hash table.
     130 *
     131 */
     132static void p2i_remove(ht_link_t *item)
     133{
    174134        assert(item);
    175        
    176         p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link);
    177        
    178         return (key[0] == entry->in_phone_hash);
    179 }
    180 
    181 /** Perform actions after removal of item from the hash table.
    182  *
    183  * @param item Item that was removed from the hash table.
    184  *
    185  */
    186 static void p2i_remove(link_t *item)
    187 {
    188         assert(item);
    189         free(hash_table_get_instance(item, p2i_entry_t, link));
     135        free(hash_table_get_inst(item, p2i_entry_t, link));
    190136}
    191137
     
    194140        .hash = p2i_hash,
    195141        .key_hash = p2i_key_hash,
    196         .match = p2i_match,
     142        .key_equal = p2i_key_equal,
    197143        .equal = 0,
    198144        .remove_callback = p2i_remove
     
    213159int task_init(void)
    214160{
    215         if (!hash_table_create(&task_hash_table, 0, 2, &task_hash_table_ops)) {
     161        if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) {
    216162                printf(NAME ": No memory available for tasks\n");
    217163                return ENOMEM;
    218164        }
    219165       
    220         if (!hash_table_create(&phone_to_id, 0, 1, &p2i_ops)) {
     166        if (!hash_table_create(&phone_to_id, 0, 0, &p2i_ops)) {
    221167                printf(NAME ": No memory available for tasks\n");
    222168                return ENOMEM;
     
    236182                pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
    237183               
    238                 unsigned long keys[2] = {
    239                         LOWER32(pr->id),
    240                         UPPER32(pr->id)
    241                 };
    242                
    243                 link_t *link = hash_table_find(&task_hash_table, keys);
     184                ht_link_t *link = hash_table_find(&task_hash_table, &pr->id);
    244185                if (!link)
    245186                        continue;
    246187               
    247                 hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
     188                hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
    248189                if (!ht->finished)
    249190                        continue;
     
    256197                }
    257198               
    258                 hash_table_remove(&task_hash_table, keys, 2);
     199                hash_table_remove(&task_hash_table, &pr->id);
    259200                list_remove(cur);
    260201                free(pr);
     
    268209        task_exit_t texit;
    269210       
    270         unsigned long keys[2] = {
    271                 LOWER32(id),
    272                 UPPER32(id)
    273         };
    274        
    275         link_t *link = hash_table_find(&task_hash_table, keys);
     211        ht_link_t *link = hash_table_find(&task_hash_table, &id);
    276212        hashed_task_t *ht = (link != NULL) ?
    277             hash_table_get_instance(link, hashed_task_t, link) : NULL;
     213            hash_table_get_inst(link, hashed_task_t, link) : NULL;
    278214       
    279215        if (ht == NULL) {
     
    299235        }
    300236       
    301         hash_table_remove(&task_hash_table, keys, 2);
     237        hash_table_remove_item(&task_hash_table, link);
    302238        retval = EOK;
    303239       
     
    314250        task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
    315251
    316         unsigned long keys[] = { call->in_phone_hash };
    317        
    318         link_t *link = hash_table_find(&phone_to_id, keys);
     252        ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash);
    319253        if (link != NULL)
    320254                return EEXISTS;
     
    332266         */
    333267       
    334         link_initialize(&entry->link);
    335268        entry->in_phone_hash = call->in_phone_hash;
    336269        entry->id = id;
     
    341274         */
    342275       
    343         link_initialize(&ht->link);
    344276        ht->id = id;
    345277        ht->finished = false;
     
    353285static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id)
    354286{
    355         unsigned long keys[1] = {phone_hash};
    356        
    357         link_t *link = hash_table_find(&phone_to_id, keys);
     287        ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash);
    358288        if (link == NULL)
    359289                return ENOENT;
    360290       
    361         p2i_entry_t *entry = hash_table_get_instance(link, p2i_entry_t, link);
     291        p2i_entry_t *entry = hash_table_get_inst(link, p2i_entry_t, link);
    362292        *id = entry->id;
    363293       
     
    372302                return rc;
    373303       
    374         unsigned long keys[2] = {
    375                 LOWER32(id),
    376                 UPPER32(id)
    377         };
    378        
    379         link_t *link = hash_table_find(&task_hash_table, keys);
     304        ht_link_t *link = hash_table_find(&task_hash_table, &id);
    380305        hashed_task_t *ht = (link != NULL) ?
    381             hash_table_get_instance(link, hashed_task_t, link) : NULL;
     306            hash_table_get_inst(link, hashed_task_t, link) : NULL;
    382307       
    383308        if ((ht == NULL) || (ht->finished))
     
    393318int ns_task_disconnect(ipc_call_t *call)
    394319{
    395         unsigned long keys[2];
    396        
    397320        task_id_t id;
    398321        int rc = get_id_by_phone(call->in_phone_hash, &id);
     
    401324       
    402325        /* Delete from phone-to-id map. */
    403         keys[0] = call->in_phone_hash;
    404         hash_table_remove(&phone_to_id, keys, 1);
     326        hash_table_remove(&phone_to_id, &call->in_phone_hash);
    405327       
    406328        /* Mark task as finished. */
    407         keys[0] = LOWER32(id);
    408         keys[1] = UPPER32(id);
    409        
    410         link_t *link = hash_table_find(&task_hash_table, keys);
     329        ht_link_t *link = hash_table_find(&task_hash_table, &id);
    411330        if (link == NULL)
    412331                return EOK;
    413332
    414         hashed_task_t *ht =
    415             hash_table_get_instance(link, hashed_task_t, link);
     333        hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
    416334       
    417335        ht->finished = true;
Note: See TracChangeset for help on using the changeset viewer.