Changeset 957cfa58 in mainline for uspace/srv/devman/devman.c


Ignore:
Timestamp:
2010-05-26T20:25:43Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c9f3b45c
Parents:
d51ee2b
Message:

devman - use hash table to lookup device according to its handle.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/devman.c

    rd51ee2b r957cfa58  
    3939#include "devman.h"
    4040
     41// hash table operations
     42
     43static hash_index_t devices_hash(unsigned long key[])
     44{
     45        return key[0] % DEVICE_BUCKETS;
     46}
     47
     48static int devman_devices_compare(unsigned long key[], hash_count_t keys, link_t *item)
     49{
     50        node_t *dev = hash_table_get_instance(item, node_t, devman_link);
     51        return (dev->handle == (device_handle_t) key[0]);
     52}
     53
     54static int devmap_devices_compare(unsigned long key[], hash_count_t keys, link_t *item)
     55{
     56        node_t *dev = hash_table_get_instance(item, node_t, devmap_link);
     57        return (dev->devmap_handle == (dev_handle_t) key[0]);
     58}
     59
     60static void devices_remove_callback(link_t *item)
     61{
     62}
     63
     64static hash_table_operations_t devman_devices_ops = {
     65        .hash = devices_hash,
     66        .compare = devman_devices_compare,
     67        .remove_callback = devices_remove_callback
     68};
     69
     70static hash_table_operations_t devmap_devices_ops = {
     71        .hash = devices_hash,
     72        .compare = devmap_devices_compare,
     73        .remove_callback = devices_remove_callback
     74};
     75
    4176/** Allocate and initialize a new driver structure.
    4277 *
     
    584619        printf(NAME ": init_device_tree.\n");
    585620       
    586         memset(tree->node_map, 0, MAX_DEV * sizeof(node_t *));
    587        
    588         atomic_set(&tree->current_handle, 0);
     621        tree->current_handle = 0;
     622       
     623        hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, &devman_devices_ops);
     624        hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops);
     625       
     626        fibril_rwlock_initialize(&tree->rwlock);
    589627       
    590628        // create root node and add it to the device tree
     
    630668/** Insert new device into device tree.
    631669 *
     670 * The device tree's rwlock should be already held exclusively when calling this function.
     671 *
    632672 * @param tree the device tree.
    633673 * @param node the newly added device node.
     
    644684        node->name = dev_name;
    645685        if (!set_dev_path(node, parent)) {
     686                fibril_rwlock_write_unlock(&tree->rwlock);
    646687                return false;           
    647688        }
    648689       
    649690        // add the node to the handle-to-node map
    650         node->handle = atomic_postinc(&tree->current_handle);
    651         if (node->handle >= MAX_DEV) {
    652                 printf(NAME ": failed to add device to device tree, because maximum number of devices was reached.\n");
    653                 free(node->pathname);
    654                 node->pathname = NULL;
    655                 atomic_postdec(&tree->current_handle);
    656                 return false;
    657         }
    658         tree->node_map[node->handle] = node;
     691        node->handle = ++tree->current_handle;
     692        unsigned long key = node->handle;
     693        hash_table_insert(&tree->devman_devices, &key, &node->devman_link);
    659694
    660695        // add the node to the list of its parent's children
    661696        node->parent = parent;
    662697        if (NULL != parent) {
    663                 fibril_mutex_lock(&parent->children_mutex);
    664                 list_append(&node->sibling, &parent->children);
    665                 fibril_mutex_unlock(&parent->children_mutex);
    666         }       
     698                list_append(&node->sibling, &parent->children);         
     699        }
    667700        return true;
    668701}
     
    678711node_t * find_dev_node_by_path(dev_tree_t *tree, char *path)
    679712{
     713        fibril_rwlock_read_lock(&tree->rwlock);
     714       
    680715        node_t *dev = tree->root_node;
    681716        // relative path to the device from its parent (but with '/' at the beginning)
     
    702737        }
    703738       
     739        fibril_rwlock_read_unlock(&tree->rwlock);
     740       
    704741        return dev;
    705742}
     
    708745 * Find child device node with a specified name.
    709746 *
     747 * Device tree rwlock should be held at least for reading.
     748 *
    710749 * @param parent the parent device node.
    711750 * @param name the name of the child device node.
     
    717756        node_t *dev;
    718757        link_t *link;
    719        
    720         fibril_mutex_lock(&parent->children_mutex);             
     758                       
    721759        link = parent->children.next;
    722760       
     
    725763               
    726764                if (0 == str_cmp(name, dev->name)) {
    727                         fibril_mutex_unlock(&parent->children_mutex);
    728765                        return dev;                     
    729766                }
     
    731768                link = link->next;
    732769        }       
    733        
    734         fibril_mutex_unlock(&parent->children_mutex);   
     770               
    735771        return NULL;
    736772}
Note: See TracChangeset for help on using the changeset viewer.