Changes in uspace/srv/ns/task.c [4e00f87:9d58539] in mainline


Ignore:
File:
1 edited

Legend:

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

    r4e00f87 r9d58539  
    4343#include "ns.h"
    4444
     45#define TASK_HASH_TABLE_CHAINS  256
     46#define P2I_HASH_TABLE_CHAINS   256
    4547
    4648/* TODO:
     
    5355/** Task hash table item. */
    5456typedef struct {
    55         ht_link_t link;
     57        link_t link;
    5658       
    5759        task_id_t id;    /**< Task ID. */
     
    6163} hashed_task_t;
    6264
    63 
    64 static size_t task_key_hash(void *key)
    65 {
    66         return *(task_id_t*)key;
    67 }
    68 
    69 static 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 
    75 static 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. */
    82 static void task_remove(ht_link_t *item)
    83 {
    84         free(hash_table_get_inst(item, hashed_task_t, link));
     65/** Compute hash index into task hash table.
     66 *
     67 * @param key Pointer keys. However, only the first key (i.e. truncated task
     68 *            number) is used to compute the hash index.
     69 *
     70 * @return Hash index corresponding to key[0].
     71 *
     72 */
     73static hash_index_t task_hash(unsigned long key[])
     74{
     75        assert(key);
     76        return (LOWER32(key[0]) % TASK_HASH_TABLE_CHAINS);
     77}
     78
     79/** Compare a key with hashed item.
     80 *
     81 * @param key  Array of keys.
     82 * @param keys Must be less than or equal to 2.
     83 * @param item Pointer to a hash table item.
     84 *
     85 * @return Non-zero if the key matches the item, zero otherwise.
     86 *
     87 */
     88static int task_compare(unsigned long key[], hash_count_t keys, link_t *item)
     89{
     90        assert(key);
     91        assert(keys <= 2);
     92        assert(item);
     93       
     94        hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link);
     95       
     96        if (keys == 2)
     97                return ((LOWER32(key[1]) == UPPER32(ht->id))
     98                    && (LOWER32(key[0]) == LOWER32(ht->id)));
     99        else
     100                return (LOWER32(key[0]) == LOWER32(ht->id));
     101}
     102
     103/** Perform actions after removal of item from the hash table.
     104 *
     105 * @param item Item that was removed from the hash table.
     106 *
     107 */
     108static void task_remove(link_t *item)
     109{
     110        assert(item);
     111        free(hash_table_get_instance(item, hashed_task_t, link));
    85112}
    86113
    87114/** Operations for task hash table. */
    88 static hash_table_ops_t task_hash_table_ops = {
     115static hash_table_operations_t task_hash_table_ops = {
    89116        .hash = task_hash,
    90         .key_hash = task_key_hash,
    91         .key_equal = task_key_equal,
    92         .equal = NULL,
     117        .compare = task_compare,
    93118        .remove_callback = task_remove
    94119};
     
    98123
    99124typedef struct {
    100         ht_link_t link;
     125        link_t link;
    101126        sysarg_t in_phone_hash;  /**< Incoming phone hash. */
    102127        task_id_t id;            /**< Task ID. */
    103128} p2i_entry_t;
    104129
    105 /* phone-to-id hash table operations */
    106 
    107 static size_t p2i_key_hash(void *key)
    108 {
    109         sysarg_t in_phone_hash = *(sysarg_t*)key;
    110         return in_phone_hash;
    111 }
    112 
    113 static 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 
    119 static 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);
     130/** Compute hash index into task hash table.
     131 *
     132 * @param key Array of keys.
     133 *
     134 * @return Hash index corresponding to key[0].
     135 *
     136 */
     137static hash_index_t p2i_hash(unsigned long key[])
     138{
     139        assert(key);
     140        return (key[0] % TASK_HASH_TABLE_CHAINS);
     141}
     142
     143/** Compare a key with hashed item.
     144 *
     145 * @param key  Array of keys.
     146 * @param keys Must be less than or equal to 1.
     147 * @param item Pointer to a hash table item.
     148 *
     149 * @return Non-zero if the key matches the item, zero otherwise.
     150 *
     151 */
     152static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item)
     153{
     154        assert(key);
     155        assert(keys == 1);
     156        assert(item);
     157       
     158        p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link);
     159       
     160        return (key[0] == entry->in_phone_hash);
    125161}
    126162
     
    130166 *
    131167 */
    132 static void p2i_remove(ht_link_t *item)
     168static void p2i_remove(link_t *item)
    133169{
    134170        assert(item);
    135         free(hash_table_get_inst(item, p2i_entry_t, link));
     171        free(hash_table_get_instance(item, p2i_entry_t, link));
    136172}
    137173
    138174/** Operations for task hash table. */
    139 static hash_table_ops_t p2i_ops = {
     175static hash_table_operations_t p2i_ops = {
    140176        .hash = p2i_hash,
    141         .key_hash = p2i_key_hash,
    142         .key_equal = p2i_key_equal,
    143         .equal = NULL,
     177        .compare = p2i_compare,
    144178        .remove_callback = p2i_remove
    145179};
     
    159193int task_init(void)
    160194{
    161         if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) {
     195        if (!hash_table_create(&task_hash_table, TASK_HASH_TABLE_CHAINS,
     196            2, &task_hash_table_ops)) {
    162197                printf(NAME ": No memory available for tasks\n");
    163198                return ENOMEM;
    164199        }
    165200       
    166         if (!hash_table_create(&phone_to_id, 0, 0, &p2i_ops)) {
     201        if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS,
     202            1, &p2i_ops)) {
    167203                printf(NAME ": No memory available for tasks\n");
    168204                return ENOMEM;
     
    182218                pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
    183219               
    184                 ht_link_t *link = hash_table_find(&task_hash_table, &pr->id);
     220                unsigned long keys[2] = {
     221                        LOWER32(pr->id),
     222                        UPPER32(pr->id)
     223                };
     224               
     225                link_t *link = hash_table_find(&task_hash_table, keys);
    185226                if (!link)
    186227                        continue;
    187228               
    188                 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
     229                hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
    189230                if (!ht->finished)
    190231                        continue;
     
    197238                }
    198239               
    199                 hash_table_remove(&task_hash_table, &pr->id);
     240                hash_table_remove(&task_hash_table, keys, 2);
    200241                list_remove(cur);
    201242                free(pr);
     
    209250        task_exit_t texit;
    210251       
    211         ht_link_t *link = hash_table_find(&task_hash_table, &id);
     252        unsigned long keys[2] = {
     253                LOWER32(id),
     254                UPPER32(id)
     255        };
     256       
     257        link_t *link = hash_table_find(&task_hash_table, keys);
    212258        hashed_task_t *ht = (link != NULL) ?
    213             hash_table_get_inst(link, hashed_task_t, link) : NULL;
     259            hash_table_get_instance(link, hashed_task_t, link) : NULL;
    214260       
    215261        if (ht == NULL) {
     
    235281        }
    236282       
    237         hash_table_remove_item(&task_hash_table, link);
     283        hash_table_remove(&task_hash_table, keys, 2);
    238284        retval = EOK;
    239285       
     
    247293int ns_task_id_intro(ipc_call_t *call)
    248294{
     295        unsigned long keys[2];
    249296       
    250297        task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
    251 
    252         ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash);
     298        keys[0] = call->in_phone_hash;
     299       
     300        link_t *link = hash_table_find(&phone_to_id, keys);
    253301        if (link != NULL)
    254302                return EEXISTS;
     
    266314         */
    267315       
     316        link_initialize(&entry->link);
    268317        entry->in_phone_hash = call->in_phone_hash;
    269318        entry->id = id;
    270         hash_table_insert(&phone_to_id, &entry->link);
     319        hash_table_insert(&phone_to_id, keys, &entry->link);
    271320       
    272321        /*
     
    274323         */
    275324       
     325        keys[0] = LOWER32(id);
     326        keys[1] = UPPER32(id);
     327       
     328        link_initialize(&ht->link);
    276329        ht->id = id;
    277330        ht->finished = false;
    278331        ht->have_rval = false;
    279332        ht->retval = -1;
    280         hash_table_insert(&task_hash_table, &ht->link);
     333        hash_table_insert(&task_hash_table, keys, &ht->link);
    281334       
    282335        return EOK;
     
    285338static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id)
    286339{
    287         ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash);
     340        unsigned long keys[1] = {phone_hash};
     341       
     342        link_t *link = hash_table_find(&phone_to_id, keys);
    288343        if (link == NULL)
    289344                return ENOENT;
    290345       
    291         p2i_entry_t *entry = hash_table_get_inst(link, p2i_entry_t, link);
     346        p2i_entry_t *entry = hash_table_get_instance(link, p2i_entry_t, link);
    292347        *id = entry->id;
    293348       
     
    302357                return rc;
    303358       
    304         ht_link_t *link = hash_table_find(&task_hash_table, &id);
     359        unsigned long keys[2] = {
     360                LOWER32(id),
     361                UPPER32(id)
     362        };
     363       
     364        link_t *link = hash_table_find(&task_hash_table, keys);
    305365        hashed_task_t *ht = (link != NULL) ?
    306             hash_table_get_inst(link, hashed_task_t, link) : NULL;
     366            hash_table_get_instance(link, hashed_task_t, link) : NULL;
    307367       
    308368        if ((ht == NULL) || (ht->finished))
     
    318378int ns_task_disconnect(ipc_call_t *call)
    319379{
     380        unsigned long keys[2];
     381       
    320382        task_id_t id;
    321383        int rc = get_id_by_phone(call->in_phone_hash, &id);
     
    324386       
    325387        /* Delete from phone-to-id map. */
    326         hash_table_remove(&phone_to_id, &call->in_phone_hash);
     388        keys[0] = call->in_phone_hash;
     389        hash_table_remove(&phone_to_id, keys, 1);
    327390       
    328391        /* Mark task as finished. */
    329         ht_link_t *link = hash_table_find(&task_hash_table, &id);
    330         if (link == NULL)
     392        keys[0] = LOWER32(id);
     393        keys[1] = UPPER32(id);
     394       
     395        link_t *link = hash_table_find(&task_hash_table, keys);
     396        hashed_task_t *ht =
     397            hash_table_get_instance(link, hashed_task_t, link);
     398        if (ht == NULL)
    331399                return EOK;
    332 
    333         hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
    334400       
    335401        ht->finished = true;
Note: See TracChangeset for help on using the changeset viewer.