/** Compare a key with hashed item. * * @param key Array of keys. * @param keys Must be less than or equal to 2. * @param item Pointer to a hash table item. * * @return Non-zero if the key matches the item, zero otherwise. * */ static int task_compare(unsigned long key[], hash_count_t keys, link_t *item) { assert(key); assert(keys <= 2); assert(item); hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link); if (keys == 2) return ((LOWER32(key[1]) == UPPER32(ht->id)) && (LOWER32(key[0]) == LOWER32(ht->id))); else return (LOWER32(key[0]) == LOWER32(ht->id)); }
static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item) { tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, nh_link); switch (keys) { case 1: return (nodep->service_id == key[NODES_KEY_DEV]); case 2: return ((nodep->service_id == key[NODES_KEY_DEV]) && (nodep->index == key[NODES_KEY_INDEX])); default: assert((keys == 1) || (keys == 2)); } return 0; }
/** Search and lock the kernel IRQ hash table. * */ static irq_t *irq_dispatch_and_lock_kernel(inr_t inr) { link_t *lnk; sysarg_t key[] = { (sysarg_t) inr, (sysarg_t) -1 /* Search will use claim() instead of devno */ }; irq_spinlock_lock(&irq_kernel_hash_table_lock, false); lnk = hash_table_find(&irq_kernel_hash_table, key); if (lnk) { irq_t *irq = hash_table_get_instance(lnk, irq_t, link); irq_spinlock_unlock(&irq_kernel_hash_table_lock, false); return irq; } irq_spinlock_unlock(&irq_kernel_hash_table_lock, false); return NULL; }
static void nodes_remove_callback(link_t *item) { tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, nh_link); while (!list_empty(&nodep->cs_list)) { tmpfs_dentry_t *dentryp = list_get_instance( list_first(&nodep->cs_list), tmpfs_dentry_t, link); assert(nodep->type == TMPFS_DIRECTORY); list_remove(&dentryp->link); free(dentryp); } if (nodep->data) { assert(nodep->type == TMPFS_FILE); free(nodep->data); } free(nodep->bp); free(nodep); }
/** Compare hash table element with a key. * * There are two things to note about this function. * First, it is used for the more complex architecture setup * in which there are way too many interrupt numbers (i.e. inr's) * to arrange the hash table so that collisions occur only * among same inrs of different devnos. So the explicit check * for inr match must be done. * Second, if devno is -1, the second key (i.e. devno) is not * used for the match and the result of the claim() function * is used instead. * * This function assumes interrupts are already disabled. * * @param key Keys (i.e. inr and devno). * @param keys This is 2. * @param item The item to compare the key with. * * @return True on match or false otherwise. * */ bool irq_ht_compare(sysarg_t key[], size_t keys, link_t *item) { irq_t *irq = hash_table_get_instance(item, irq_t, link); inr_t inr = (inr_t) key[KEY_INR]; devno_t devno = (devno_t) key[KEY_DEVNO]; bool rv; irq_spinlock_lock(&irq->lock, false); if (devno == -1) { /* Invoked by irq_dispatch_and_lock(). */ rv = ((irq->inr == inr) && (irq->claim(irq) == IRQ_ACCEPT)); } else { /* Invoked by irq_find_and_lock(). */ rv = ((irq->inr == inr) && (irq->devno == devno)); } /* unlock only on non-match */ if (!rv) irq_spinlock_unlock(&irq->lock, false); return rv; }
/** Unlock IRQ structure after hash_table_remove(). * * @param lnk Link in the removed and locked IRQ structure. * */ void irq_lin_remove(link_t *lnk) { irq_t *irq __attribute__((unused)) = hash_table_get_instance(lnk, irq_t, link); irq_spinlock_unlock(&irq->lock, false); }
/** Perform actions after removal of item from the hash table. * * @param item Item that was removed from the hash table. * */ static void p2i_remove(link_t *item) { assert(item); free(hash_table_get_instance(item, p2i_entry_t, link)); }
/** Perform actions after removal of item from the hash table. * * @param item Item that was removed from the hash table. * */ static void task_remove(link_t *item) { assert(item); free(hash_table_get_instance(item, hashed_task_t, link)); }