Changeset 062d900 in mainline for uspace/srv
- Timestamp:
- 2012-10-09T11:49:43Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4e00f87
- Parents:
- 87e9392
- git-author:
- Adam Hraska <adam.hraska+hos@…> (2012-10-09 11:49:43)
- git-committer:
- Jakub Jermar <jakub@…> (2012-10-09 11:49:43)
- Location:
- uspace/srv
- Files:
-
- 21 edited
-
devman/devman.c (modified) (12 diffs)
-
devman/devman.h (modified) (3 diffs)
-
fs/cdfs/cdfs_ops.c (modified) (14 diffs)
-
fs/exfat/exfat.h (modified) (1 diff)
-
fs/exfat/exfat_idx.c (modified) (17 diffs)
-
fs/exfat/exfat_ops.c (modified) (1 diff)
-
fs/ext2fs/ext2fs_ops.c (modified) (8 diffs)
-
fs/ext4fs/ext4fs_ops.c (modified) (9 diffs)
-
fs/fat/fat.h (modified) (1 diff)
-
fs/fat/fat_idx.c (modified) (18 diffs)
-
fs/locfs/locfs_ops.c (modified) (16 diffs)
-
fs/mfs/mfs.h (modified) (1 diff)
-
fs/mfs/mfs_ops.c (modified) (9 diffs)
-
fs/tmpfs/tmpfs.h (modified) (1 diff)
-
fs/tmpfs/tmpfs_ops.c (modified) (14 diffs)
-
hid/input/gsp.c (modified) (5 diffs)
-
hid/input/gsp.h (modified) (1 diff)
-
ns/service.c (modified) (8 diffs)
-
ns/task.c (modified) (16 diffs)
-
vfs/vfs.h (modified) (2 diffs)
-
vfs/vfs_node.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r87e9392 r062d900 66 66 /* hash table operations */ 67 67 68 static hash_index_t devices_hash(unsigned long key[]) 69 { 70 return key[0] % DEVICE_BUCKETS; 71 } 72 73 static int devman_devices_compare(unsigned long key[], hash_count_t keys, 74 link_t *item) 75 { 76 dev_node_t *dev = hash_table_get_instance(item, dev_node_t, devman_dev); 77 return (dev->handle == (devman_handle_t) key[0]); 78 } 79 80 static int devman_functions_compare(unsigned long key[], hash_count_t keys, 81 link_t *item) 82 { 83 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devman_fun); 84 return (fun->handle == (devman_handle_t) key[0]); 85 } 86 87 static int loc_functions_compare(unsigned long key[], hash_count_t keys, 88 link_t *item) 89 { 90 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, loc_fun); 91 return (fun->service_id == (service_id_t) key[0]); 92 } 93 94 static void devices_remove_callback(link_t *item) 95 { 96 } 97 98 static hash_table_operations_t devman_devices_ops = { 99 .hash = devices_hash, 100 .compare = devman_devices_compare, 101 .remove_callback = devices_remove_callback 68 static inline size_t handle_key_hash(void *key) 69 { 70 devman_handle_t handle = *(devman_handle_t*)key; 71 return handle; 72 } 73 74 static size_t devman_devices_hash(const ht_link_t *item) 75 { 76 dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev); 77 return handle_key_hash(&dev->handle); 78 } 79 80 static size_t devman_functions_hash(const ht_link_t *item) 81 { 82 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun); 83 return handle_key_hash(&fun->handle); 84 } 85 86 static bool devman_devices_key_equal(void *key, const ht_link_t *item) 87 { 88 devman_handle_t handle = *(devman_handle_t*)key; 89 dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev); 90 return dev->handle == handle; 91 } 92 93 static bool devman_functions_key_equal(void *key, const ht_link_t *item) 94 { 95 devman_handle_t handle = *(devman_handle_t*)key; 96 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun); 97 return fun->handle == handle; 98 } 99 100 static inline size_t service_id_key_hash(void *key) 101 { 102 service_id_t service_id = *(service_id_t*)key; 103 return service_id; 104 } 105 106 static size_t loc_functions_hash(const ht_link_t *item) 107 { 108 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun); 109 return service_id_key_hash(&fun->service_id); 110 } 111 112 static bool loc_functions_key_equal(void *key, const ht_link_t *item) 113 { 114 service_id_t service_id = *(service_id_t*)key; 115 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun); 116 return fun->service_id == service_id; 117 } 118 119 120 static hash_table_ops_t devman_devices_ops = { 121 .hash = devman_devices_hash, 122 .key_hash = handle_key_hash, 123 .key_equal = devman_devices_key_equal, 124 .equal = 0, 125 .remove_callback = 0 102 126 }; 103 127 104 static hash_table_operations_t devman_functions_ops = { 105 .hash = devices_hash, 106 .compare = devman_functions_compare, 107 .remove_callback = devices_remove_callback 128 static hash_table_ops_t devman_functions_ops = { 129 .hash = devman_functions_hash, 130 .key_hash = handle_key_hash, 131 .key_equal = devman_functions_key_equal, 132 .equal = 0, 133 .remove_callback = 0 108 134 }; 109 135 110 static hash_table_operations_t loc_devices_ops = { 111 .hash = devices_hash, 112 .compare = loc_functions_compare, 113 .remove_callback = devices_remove_callback 136 static hash_table_ops_t loc_devices_ops = { 137 .hash = loc_functions_hash, 138 .key_hash = service_id_key_hash, 139 .key_equal = loc_functions_key_equal, 140 .equal = 0, 141 .remove_callback = 0 114 142 }; 115 143 … … 974 1002 tree->current_handle = 0; 975 1003 976 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, 977 &devman_devices_ops); 978 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 979 &devman_functions_ops); 980 hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1, 981 &loc_devices_ops); 1004 hash_table_create(&tree->devman_devices, 0, 0, &devman_devices_ops); 1005 hash_table_create(&tree->devman_functions, 0, 0, &devman_functions_ops); 1006 hash_table_create(&tree->loc_functions, 0, 0, &loc_devices_ops); 982 1007 983 1008 fibril_rwlock_initialize(&tree->rwlock); … … 1013 1038 list_initialize(&dev->functions); 1014 1039 link_initialize(&dev->driver_devices); 1015 link_initialize(&dev->devman_dev);1016 1040 1017 1041 return dev; … … 1060 1084 dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 1061 1085 { 1062 unsigned long key = handle;1063 link_t *link;1064 1065 1086 assert(fibril_rwlock_is_locked(&tree->rwlock)); 1066 1087 1067 link = hash_table_find(&tree->devman_devices, &key);1088 ht_link_t *link = hash_table_find(&tree->devman_devices, &handle); 1068 1089 if (link == NULL) 1069 1090 return NULL; 1070 1091 1071 return hash_table_get_inst ance(link, dev_node_t, devman_dev);1092 return hash_table_get_inst(link, dev_node_t, devman_dev); 1072 1093 } 1073 1094 … … 1144 1165 link_initialize(&fun->dev_functions); 1145 1166 list_initialize(&fun->match_ids.ids); 1146 link_initialize(&fun->devman_fun);1147 link_initialize(&fun->loc_fun);1148 1167 1149 1168 return fun; … … 1206 1225 fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 1207 1226 { 1208 unsigned long key = handle;1209 link_t *link;1210 1227 fun_node_t *fun; 1211 1228 1212 1229 assert(fibril_rwlock_is_locked(&tree->rwlock)); 1213 1230 1214 link = hash_table_find(&tree->devman_functions, &key);1231 ht_link_t *link = hash_table_find(&tree->devman_functions, &handle); 1215 1232 if (link == NULL) 1216 1233 return NULL; 1217 1234 1218 fun = hash_table_get_inst ance(link, fun_node_t, devman_fun);1235 fun = hash_table_get_inst(link, fun_node_t, devman_fun); 1219 1236 1220 1237 return fun; … … 1294 1311 /* Add the node to the handle-to-node map. */ 1295 1312 dev->handle = ++tree->current_handle; 1296 unsigned long key = dev->handle; 1297 hash_table_insert(&tree->devman_devices, &key, &dev->devman_dev); 1313 hash_table_insert(&tree->devman_devices, &dev->devman_dev); 1298 1314 1299 1315 /* Add the node to the list of its parent's children. */ … … 1316 1332 1317 1333 /* Remove node from the handle-to-node map. */ 1318 unsigned long key = dev->handle; 1319 hash_table_remove(&tree->devman_devices, &key, 1); 1334 hash_table_remove(&tree->devman_devices, &dev->handle); 1320 1335 1321 1336 /* Unlink from parent function. */ … … 1358 1373 /* Add the node to the handle-to-node map. */ 1359 1374 fun->handle = ++tree->current_handle; 1360 unsigned long key = fun->handle; 1361 hash_table_insert(&tree->devman_functions, &key, &fun->devman_fun); 1375 hash_table_insert(&tree->devman_functions, &fun->devman_fun); 1362 1376 1363 1377 /* Add the node to the list of its parent's children. */ … … 1379 1393 1380 1394 /* Remove the node from the handle-to-node map. */ 1381 unsigned long key = fun->handle; 1382 hash_table_remove(&tree->devman_functions, &key, 1); 1395 hash_table_remove(&tree->devman_functions, &fun->handle); 1383 1396 1384 1397 /* Remove the node from the list of its parent's children. */ … … 1493 1506 { 1494 1507 fun_node_t *fun = NULL; 1495 link_t *link;1496 unsigned long key = (unsigned long) service_id;1497 1508 1498 1509 fibril_rwlock_read_lock(&tree->rwlock); 1499 link = hash_table_find(&tree->loc_functions, &key);1510 ht_link_t *link = hash_table_find(&tree->loc_functions, &service_id); 1500 1511 if (link != NULL) { 1501 fun = hash_table_get_inst ance(link, fun_node_t, loc_fun);1512 fun = hash_table_get_inst(link, fun_node_t, loc_fun); 1502 1513 fun_add_ref(fun); 1503 1514 } … … 1511 1522 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 1512 1523 1513 unsigned long key = (unsigned long) fun->service_id; 1514 hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun); 1524 hash_table_insert(&tree->loc_functions, &fun->loc_fun); 1515 1525 } 1516 1526 -
uspace/srv/devman/devman.h
r87e9392 r062d900 52 52 53 53 #define MATCH_EXT ".ma" 54 #define DEVICE_BUCKETS 25655 54 56 55 #define LOC_DEVICE_NAMESPACE "devices" … … 151 150 * Used by the hash table of devices indexed by devman device handles. 152 151 */ 153 link_t devman_dev;152 ht_link_t devman_dev; 154 153 155 154 /** … … 204 203 * Used by the hash table of functions indexed by devman device handles. 205 204 */ 206 link_t devman_fun;205 ht_link_t devman_fun; 207 206 208 207 /** 209 208 * Used by the hash table of functions indexed by service IDs. 210 209 */ 211 link_t loc_fun;210 ht_link_t loc_fun; 212 211 }; 213 212 -
uspace/srv/fs/cdfs/cdfs_ops.c
r87e9392 r062d900 37 37 */ 38 38 39 #include "cdfs_ops.h" 39 40 #include <bool.h> 40 41 #include <adt/hash_table.h> 42 #include <adt/hash.h> 41 43 #include <malloc.h> 42 44 #include <mem.h> … … 50 52 #include "cdfs.h" 51 53 #include "cdfs_endian.h" 52 #include "cdfs_ops.h"53 54 54 55 /** Standard CD-ROM block size */ 55 56 #define BLOCK_SIZE 2048 56 57 57 /** Implicit node cache size 58 * 59 * More nodes can be actually cached if the files remain 60 * opended. 61 * 62 */ 63 #define NODE_CACHE_SIZE 200 64 65 #define NODES_BUCKETS 256 66 67 #define NODES_KEY_SRVC 0 68 #define NODES_KEY_INDEX 1 58 #define NODE_CACHE_SIZE 200 69 59 70 60 /** All root nodes have index 0 */ … … 205 195 service_id_t service_id; /**< Service ID of block device */ 206 196 207 link_t nh_link;/**< Nodes hash table link */197 ht_link_t nh_link; /**< Nodes hash table link */ 208 198 cdfs_dentry_type_t type; /**< Dentry type */ 209 199 … … 226 216 static hash_table_t nodes; 227 217 228 static hash_index_t nodes_hash(unsigned long key[]) 229 { 230 return key[NODES_KEY_INDEX] % NODES_BUCKETS; 231 } 232 233 static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item) 234 { 235 cdfs_node_t *node = 236 hash_table_get_instance(item, cdfs_node_t, nh_link); 237 238 switch (keys) { 239 case 1: 240 return (node->service_id == key[NODES_KEY_SRVC]); 241 case 2: 242 return ((node->service_id == key[NODES_KEY_SRVC]) && 243 (node->index == key[NODES_KEY_INDEX])); 244 default: 245 assert((keys == 1) || (keys == 2)); 246 } 247 248 return 0; 249 } 250 251 static void nodes_remove_callback(link_t *item) 252 { 253 cdfs_node_t *node = 254 hash_table_get_instance(item, cdfs_node_t, nh_link); 218 /* 219 * Hash table support functions. 220 */ 221 222 typedef struct { 223 service_id_t service_id; 224 fs_index_t index; 225 } ht_key_t; 226 227 static size_t nodes_key_hash(void *k) 228 { 229 ht_key_t *key = (ht_key_t*)k; 230 return hash_combine(key->service_id, key->index); 231 } 232 233 static size_t nodes_hash(const ht_link_t *item) 234 { 235 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 236 return hash_combine(node->service_id, node->index); 237 } 238 239 static bool nodes_key_equal(void *k, const ht_link_t *item) 240 { 241 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 242 ht_key_t *key = (ht_key_t*)k; 243 244 return key->service_id == node->service_id && key->index == node->index; 245 } 246 247 static void nodes_remove_callback(ht_link_t *item) 248 { 249 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 255 250 256 251 assert(node->type == CDFS_DIRECTORY); … … 268 263 269 264 /** Nodes hash table operations */ 270 static hash_table_op erations_t nodes_ops = {265 static hash_table_ops_t nodes_ops = { 271 266 .hash = nodes_hash, 272 .compare = nodes_compare, 267 .key_hash = nodes_key_hash, 268 .key_equal = nodes_key_equal, 269 .equal = 0, 273 270 .remove_callback = nodes_remove_callback 274 271 }; … … 277 274 fs_index_t index) 278 275 { 279 unsigned long key[]= {280 [NODES_KEY_SRVC] = service_id,281 [NODES_KEY_INDEX] = index276 ht_key_t key = { 277 .index = index, 278 .service_id = service_id 282 279 }; 283 280 284 link_t *link = hash_table_find(&nodes,key);281 ht_link_t *link = hash_table_find(&nodes, &key); 285 282 if (link) { 286 283 cdfs_node_t *node = 287 hash_table_get_inst ance(link, cdfs_node_t, nh_link);284 hash_table_get_inst(link, cdfs_node_t, nh_link); 288 285 289 286 *rfn = FS_NODE(node); … … 311 308 node->opened = 0; 312 309 313 link_initialize(&node->nh_link);314 310 list_initialize(&node->cs_list); 315 311 } … … 353 349 354 350 /* Insert the new node into the nodes hash table. */ 355 unsigned long key[] = { 356 [NODES_KEY_SRVC] = node->service_id, 357 [NODES_KEY_INDEX] = node->index 358 }; 359 360 hash_table_insert(&nodes, key, &node->nh_link); 351 hash_table_insert(&nodes, &node->nh_link); 361 352 362 353 *rfn = FS_NODE(node); … … 508 499 static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index) 509 500 { 510 unsigned long key[]= {511 [NODES_KEY_SRVC] = service_id,512 [NODES_KEY_INDEX] = index501 ht_key_t key = { 502 .index = index, 503 .service_id = service_id 513 504 }; 514 505 515 link_t *link = hash_table_find(&nodes,key);506 ht_link_t *link = hash_table_find(&nodes, &key); 516 507 if (link) { 517 508 cdfs_node_t *node = 518 hash_table_get_inst ance(link, cdfs_node_t, nh_link);509 hash_table_get_inst(link, cdfs_node_t, nh_link); 519 510 return FS_NODE(node); 520 511 } … … 802 793 } 803 794 795 static bool rm_service_id_nodes(ht_link_t *item, void *arg) 796 { 797 service_id_t service_id = *(service_id_t*)arg; 798 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 799 800 if (node->service_id == service_id) { 801 hash_table_remove_item(&nodes, &node->nh_link); 802 } 803 804 return true; 805 } 806 804 807 static void cdfs_instance_done(service_id_t service_id) 805 808 { 806 unsigned long key[] = { 807 [NODES_KEY_SRVC] = service_id 808 }; 809 810 hash_table_remove(&nodes, key, 1); 809 hash_table_apply(&nodes, rm_service_id_nodes, &service_id); 811 810 block_cache_fini(service_id); 812 811 block_fini(service_id); … … 822 821 size_t *rbytes) 823 822 { 824 unsigned long key[]= {825 [NODES_KEY_SRVC] = service_id,826 [NODES_KEY_INDEX] = index823 ht_key_t key = { 824 .index = index, 825 .service_id = service_id 827 826 }; 828 827 829 link_t *link = hash_table_find(&nodes,key);828 ht_link_t *link = hash_table_find(&nodes, &key); 830 829 if (link == NULL) 831 830 return ENOENT; 832 831 833 832 cdfs_node_t *node = 834 hash_table_get_inst ance(link, cdfs_node_t, nh_link);833 hash_table_get_inst(link, cdfs_node_t, nh_link); 835 834 836 835 if (!node->processed) { … … 912 911 } 913 912 913 static bool cache_remove_closed(ht_link_t *item, void *arg) 914 { 915 size_t *premove_cnt = (size_t*)arg; 916 917 /* Some nodes were requested to be removed from the cache. */ 918 if (0 < *premove_cnt) { 919 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 920 921 if (!node->opened) { 922 hash_table_remove_item(&nodes, item); 923 924 --nodes_cached; 925 --*premove_cnt; 926 } 927 } 928 929 /* Only continue if more nodes were requested to be removed. */ 930 return 0 < *premove_cnt; 931 } 932 914 933 static void cleanup_cache(service_id_t service_id) 915 934 { 916 935 if (nodes_cached > NODE_CACHE_SIZE) { 917 size_t remove = nodes_cached - NODE_CACHE_SIZE; 918 919 // FIXME: this accesses the internals of the hash table 920 // and should be rewritten in a clean way 921 922 for (hash_index_t chain = 0; chain < nodes.entries; chain++) { 923 for (link_t *link = nodes.entry[chain].head.next; 924 link != &nodes.entry[chain].head; 925 link = link->next) { 926 if (remove == 0) 927 return; 928 929 cdfs_node_t *node = 930 hash_table_get_instance(link, cdfs_node_t, nh_link); 931 if (node->opened == 0) { 932 link_t *tmp = link; 933 link = link->prev; 934 935 list_remove(tmp); 936 nodes.op->remove_callback(tmp); 937 nodes_cached--; 938 remove--; 939 940 continue; 941 } 942 } 943 } 936 size_t remove_cnt = nodes_cached - NODE_CACHE_SIZE; 937 938 if (0 < remove_cnt) 939 hash_table_apply(&nodes, cache_remove_closed, &remove_cnt); 944 940 } 945 941 } … … 951 947 return EOK; 952 948 953 unsigned long key[]= {954 [NODES_KEY_SRVC] = service_id,955 [NODES_KEY_INDEX] = index949 ht_key_t key = { 950 .index = index, 951 .service_id = service_id 956 952 }; 957 953 958 link_t *link = hash_table_find(&nodes,key);954 ht_link_t *link = hash_table_find(&nodes, &key); 959 955 if (link == 0) 960 956 return ENOENT; 961 957 962 958 cdfs_node_t *node = 963 hash_table_get_inst ance(link, cdfs_node_t, nh_link);959 hash_table_get_inst(link, cdfs_node_t, nh_link); 964 960 965 961 assert(node->opened > 0); … … 1007 1003 bool cdfs_init(void) 1008 1004 { 1009 if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))1005 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 1010 1006 return false; 1011 1007 -
uspace/srv/fs/exfat/exfat.h
r87e9392 r062d900 106 106 typedef struct { 107 107 /** Used indices (position) hash table link. */ 108 link_t uph_link;108 ht_link_t uph_link; 109 109 /** Used indices (index) hash table link. */ 110 link_t uih_link;110 ht_link_t uih_link; 111 111 112 112 fibril_mutex_t lock; -
uspace/srv/fs/exfat/exfat_idx.c
r87e9392 r062d900 41 41 #include <str.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <adt/list.h> 44 45 #include <assert.h> … … 91 92 if (lock) 92 93 fibril_mutex_lock(&unused_lock); 94 93 95 list_foreach(unused_list, l) { 94 96 u = list_get_instance(l, unused_t, link); … … 112 114 static hash_table_t up_hash; 113 115 114 #define UPH_BUCKETS_LOG 12 115 #define UPH_BUCKETS (1 << UPH_BUCKETS_LOG) 116 117 #define UPH_SID_KEY 0 118 #define UPH_PFC_KEY 1 119 #define UPH_PDI_KEY 2 120 121 static hash_index_t pos_hash(unsigned long key[]) 122 { 123 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 124 exfat_cluster_t pfc = (exfat_cluster_t)key[UPH_PFC_KEY]; 125 unsigned pdi = (unsigned)key[UPH_PDI_KEY]; 126 127 hash_index_t h; 128 129 /* 130 * The least significant half of all bits are the least significant bits 131 * of the parent node's first cluster. 132 * 133 * The least significant half of the most significant half of all bits 134 * are the least significant bits of the node's dentry index within the 135 * parent directory node. 136 * 137 * The most significant half of the most significant half of all bits 138 * are the least significant bits of the device handle. 139 */ 140 h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1); 141 h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 142 (UPH_BUCKETS_LOG / 2); 143 h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 144 (3 * (UPH_BUCKETS_LOG / 4)); 145 146 return h; 147 } 148 149 static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item) 150 { 151 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 116 typedef struct { 117 service_id_t service_id; 152 118 exfat_cluster_t pfc; 153 119 unsigned pdi; 154 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uph_link); 155 156 switch (keys) { 157 case 1: 158 return (service_id == fidx->service_id); 159 case 3: 160 pfc = (exfat_cluster_t) key[UPH_PFC_KEY]; 161 pdi = (unsigned) key[UPH_PDI_KEY]; 162 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 163 (pdi == fidx->pdi); 164 default: 165 assert((keys == 1) || (keys == 3)); 166 } 167 168 return 0; 169 } 170 171 static void pos_remove_callback(link_t *item) 172 { 173 /* nothing to do */ 174 } 175 176 static hash_table_operations_t uph_ops = { 120 } pos_key_t; 121 122 static inline size_t pos_key_hash(void *key) 123 { 124 pos_key_t *pos = (pos_key_t*)key; 125 126 size_t hash = 0; 127 hash = hash_combine(pos->pfc, pos->pdi); 128 return hash_combine(hash, pos->service_id); 129 } 130 131 static size_t pos_hash(const ht_link_t *item) 132 { 133 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 134 135 pos_key_t pkey = { 136 .service_id = fidx->service_id, 137 .pfc = fidx->pfc, 138 .pdi = fidx->pdi, 139 }; 140 141 return pos_key_hash(&pkey); 142 } 143 144 static bool pos_key_equal(void *key, const ht_link_t *item) 145 { 146 pos_key_t *pos = (pos_key_t*)key; 147 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 148 149 return pos->service_id == fidx->service_id 150 && pos->pdi == fidx->pdi 151 && pos->pfc == fidx->pfc; 152 } 153 154 static hash_table_ops_t uph_ops = { 177 155 .hash = pos_hash, 178 .compare = pos_compare, 179 .remove_callback = pos_remove_callback, 156 .key_hash = pos_key_hash, 157 .key_equal = pos_key_equal, 158 .equal = 0, 159 .remove_callback = 0, 180 160 }; 181 161 … … 186 166 static hash_table_t ui_hash; 187 167 188 #define UIH_BUCKETS_LOG 12 189 #define UIH_BUCKETS (1 << UIH_BUCKETS_LOG) 190 191 #define UIH_SID_KEY 0 192 #define UIH_INDEX_KEY 1 193 194 static hash_index_t idx_hash(unsigned long key[]) 195 { 196 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 197 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 198 199 hash_index_t h; 200 201 h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1); 202 h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) << 203 (UIH_BUCKETS_LOG / 2); 204 205 return h; 206 } 207 208 static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) 209 { 210 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 168 typedef struct { 169 service_id_t service_id; 211 170 fs_index_t index; 212 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link); 213 214 switch (keys) { 215 case 1: 216 return (service_id == fidx->service_id); 217 case 2: 218 index = (fs_index_t) key[UIH_INDEX_KEY]; 219 return (service_id == fidx->service_id) && 220 (index == fidx->index); 221 default: 222 assert((keys == 1) || (keys == 2)); 223 } 224 225 return 0; 226 } 227 228 static void idx_remove_callback(link_t *item) 229 { 230 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link); 171 } idx_key_t; 172 173 static size_t idx_key_hash(void *key_arg) 174 { 175 idx_key_t *key = (idx_key_t*)key_arg; 176 return hash_combine(key->service_id, key->index); 177 } 178 179 static size_t idx_hash(const ht_link_t *item) 180 { 181 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 182 return hash_combine(fidx->service_id, fidx->index); 183 } 184 185 static bool idx_key_equal(void *key_arg, const ht_link_t *item) 186 { 187 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 188 idx_key_t *key = (idx_key_t*)key_arg; 189 190 return key->index == fidx->index && key->service_id == fidx->service_id; 191 } 192 193 static void idx_remove_callback(ht_link_t *item) 194 { 195 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 231 196 232 197 free(fidx); 233 198 } 234 199 235 static hash_table_op erations_t uih_ops = {200 static hash_table_ops_t uih_ops = { 236 201 .hash = idx_hash, 237 .compare = idx_compare, 202 .key_hash = idx_key_hash, 203 .key_equal = idx_key_equal, 204 .equal = 0, 238 205 .remove_callback = idx_remove_callback, 239 206 }; … … 376 343 } 377 344 378 link_initialize(&fidx->uph_link);379 link_initialize(&fidx->uih_link);380 345 fibril_mutex_initialize(&fidx->lock); 381 346 fidx->service_id = service_id; … … 400 365 } 401 366 402 unsigned long ikey[] = { 403 [UIH_SID_KEY] = service_id, 404 [UIH_INDEX_KEY] = fidx->index, 405 }; 406 407 hash_table_insert(&ui_hash, ikey, &fidx->uih_link); 367 hash_table_insert(&ui_hash, &fidx->uih_link); 408 368 fibril_mutex_lock(&fidx->lock); 409 369 fibril_mutex_unlock(&used_lock); … … 417 377 { 418 378 exfat_idx_t *fidx; 419 link_t *l;420 unsigned long pkey[]= {421 [UPH_SID_KEY]= service_id,422 [UPH_PFC_KEY]= pfc,423 [UPH_PDI_KEY]= pdi,379 380 pos_key_t pos_key = { 381 .service_id = service_id, 382 .pfc = pfc, 383 .pdi = pdi, 424 384 }; 425 385 426 386 fibril_mutex_lock(&used_lock); 427 l = hash_table_find(&up_hash, pkey);387 ht_link_t *l = hash_table_find(&up_hash, &pos_key); 428 388 if (l) { 429 fidx = hash_table_get_inst ance(l, exfat_idx_t, uph_link);389 fidx = hash_table_get_inst(l, exfat_idx_t, uph_link); 430 390 } else { 431 391 int rc; … … 437 397 } 438 398 439 unsigned long ikey[] = {440 [UIH_SID_KEY] = service_id,441 [UIH_INDEX_KEY] = fidx->index,442 };443 444 399 fidx->pfc = pfc; 445 400 fidx->pdi = pdi; 446 401 447 hash_table_insert(&up_hash, pkey,&fidx->uph_link);448 hash_table_insert(&ui_hash, ikey,&fidx->uih_link);402 hash_table_insert(&up_hash, &fidx->uph_link); 403 hash_table_insert(&ui_hash, &fidx->uih_link); 449 404 } 450 405 fibril_mutex_lock(&fidx->lock); … … 456 411 void exfat_idx_hashin(exfat_idx_t *idx) 457 412 { 458 unsigned long pkey[] = { 459 [UPH_SID_KEY] = idx->service_id, 460 [UPH_PFC_KEY] = idx->pfc, 461 [UPH_PDI_KEY] = idx->pdi, 462 }; 463 464 fibril_mutex_lock(&used_lock); 465 hash_table_insert(&up_hash, pkey, &idx->uph_link); 413 fibril_mutex_lock(&used_lock); 414 hash_table_insert(&up_hash, &idx->uph_link); 466 415 fibril_mutex_unlock(&used_lock); 467 416 } … … 469 418 void exfat_idx_hashout(exfat_idx_t *idx) 470 419 { 471 unsigned long pkey[] = { 472 [UPH_SID_KEY] = idx->service_id, 473 [UPH_PFC_KEY] = idx->pfc, 474 [UPH_PDI_KEY] = idx->pdi, 475 }; 476 477 fibril_mutex_lock(&used_lock); 478 hash_table_remove(&up_hash, pkey, 3); 420 fibril_mutex_lock(&used_lock); 421 hash_table_remove_item(&up_hash, &idx->uph_link); 479 422 fibril_mutex_unlock(&used_lock); 480 423 } … … 484 427 { 485 428 exfat_idx_t *fidx = NULL; 486 link_t *l; 487 unsigned long ikey[]= {488 [UIH_SID_KEY]= service_id,489 [UIH_INDEX_KEY]= index,429 430 idx_key_t idx_key = { 431 .service_id = service_id, 432 .index = index, 490 433 }; 491 434 492 435 fibril_mutex_lock(&used_lock); 493 l = hash_table_find(&ui_hash, ikey);436 ht_link_t *l = hash_table_find(&ui_hash, &idx_key); 494 437 if (l) { 495 fidx = hash_table_get_inst ance(l, exfat_idx_t, uih_link);438 fidx = hash_table_get_inst(l, exfat_idx_t, uih_link); 496 439 fibril_mutex_lock(&fidx->lock); 497 440 } … … 507 450 void exfat_idx_destroy(exfat_idx_t *idx) 508 451 { 509 unsigned long ikey[]= {510 [UIH_SID_KEY]= idx->service_id,511 [UIH_INDEX_KEY]= idx->index,452 idx_key_t idx_key = { 453 .service_id = idx->service_id, 454 .index = idx->index, 512 455 }; 513 service_id_t service_id = idx->service_id;514 fs_index_t index = idx->index;515 456 516 457 /* TODO: assert(idx->pfc == FAT_CLST_RES0); */ … … 523 464 * the index hash only. 524 465 */ 525 hash_table_remove(&ui_hash, ikey, 2);466 hash_table_remove(&ui_hash, &idx_key); 526 467 fibril_mutex_unlock(&used_lock); 527 468 /* Release the VFS index. */ 528 exfat_index_free( service_id,index);469 exfat_index_free(idx_key.service_id, idx_key.index); 529 470 /* The index structure itself is freed in idx_remove_callback(). */ 530 471 } … … 532 473 int exfat_idx_init(void) 533 474 { 534 if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))475 if (!hash_table_create(&up_hash, 0, 0, &uph_ops)) 535 476 return ENOMEM; 536 if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {477 if (!hash_table_create(&ui_hash, 0, 0, &uih_ops)) { 537 478 hash_table_destroy(&up_hash); 538 479 return ENOMEM; … … 544 485 { 545 486 /* We assume the hash tables are empty. */ 487 assert(hash_table_empty(&up_hash) && hash_table_empty(&ui_hash)); 546 488 hash_table_destroy(&up_hash); 547 489 hash_table_destroy(&ui_hash); … … 568 510 } 569 511 512 static bool rm_pos_service_id(ht_link_t *item, void *arg) 513 { 514 service_id_t service_id = *(service_id_t*)arg; 515 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 516 517 if (fidx->service_id == service_id) { 518 hash_table_remove_item(&up_hash, item); 519 } 520 521 return true; 522 } 523 524 static bool rm_idx_service_id(ht_link_t *item, void *arg) 525 { 526 service_id_t service_id = *(service_id_t*)arg; 527 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 528 529 if (fidx->service_id == service_id) { 530 hash_table_remove_item(&ui_hash, item); 531 } 532 533 return true; 534 } 535 570 536 void exfat_idx_fini_by_service_id(service_id_t service_id) 571 537 { 572 unsigned long ikey[] = {573 [UIH_SID_KEY] = service_id574 };575 unsigned long pkey[] = {576 [UPH_SID_KEY] = service_id577 };578 579 538 /* 580 539 * Remove this instance's index structure from up_hash and ui_hash. … … 583 542 */ 584 543 fibril_mutex_lock(&used_lock); 585 hash_table_ remove(&up_hash, pkey, 1);586 hash_table_ remove(&ui_hash, ikey, 1);544 hash_table_apply(&up_hash, rm_pos_service_id, &service_id); 545 hash_table_apply(&ui_hash, rm_idx_service_id, &service_id); 587 546 fibril_mutex_unlock(&used_lock); 588 547 -
uspace/srv/fs/exfat/exfat_ops.c
r87e9392 r062d900 54 54 #include <byteorder.h> 55 55 #include <adt/hash_table.h> 56 #include <adt/hash.h> 56 57 #include <adt/list.h> 57 58 #include <assert.h> -
uspace/srv/fs/ext2fs/ext2fs_ops.c
r87e9392 r062d900 49 49 #include <byteorder.h> 50 50 #include <adt/hash_table.h> 51 #include <adt/hash.h> 51 52 #include <adt/list.h> 52 53 #include <assert.h> … … 62 63 #define EXT2FS_NODE(node) ((node) ? (ext2fs_node_t *) (node)->data : NULL) 63 64 #define EXT2FS_DBG(format, ...) {if (false) printf("ext2fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);} 64 #define OPEN_NODES_KEYS 265 #define OPEN_NODES_DEV_HANDLE_KEY 066 #define OPEN_NODES_INODE_KEY 167 #define OPEN_NODES_BUCKETS 25668 65 69 66 typedef struct ext2fs_instance { … … 78 75 ext2_inode_ref_t *inode_ref; 79 76 fs_node_t *fs_node; 80 link_t link;77 ht_link_t link; 81 78 unsigned int references; 82 79 } ext2fs_node_t; … … 122 119 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 123 120 124 /* Hash table interface for open nodes hash table */ 125 static hash_index_t open_nodes_hash(unsigned long key[]) 126 { 127 /* TODO: This is very simple and probably can be improved */ 128 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS; 129 } 130 131 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 132 link_t *item) 133 { 134 ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link); 135 assert(keys > 0); 136 if (enode->instance->service_id != 137 ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) { 138 return false; 139 } 140 if (keys == 1) { 141 return true; 142 } 143 assert(keys == 2); 144 return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]); 145 } 146 147 static void open_nodes_remove_cb(link_t *link) 148 { 149 /* We don't use remove callback for this hash table */ 150 } 151 152 static hash_table_operations_t open_nodes_ops = { 121 /* 122 * Hash table interface for open nodes hash table 123 */ 124 125 typedef struct { 126 service_id_t service_id; 127 fs_index_t index; 128 } node_key_t; 129 130 static size_t open_nodes_key_hash(void *key) 131 { 132 node_key_t *node_key = (node_key_t*)key; 133 return hash_combine(node_key->service_id, node_key->index); 134 } 135 136 static size_t open_nodes_hash(const ht_link_t *item) 137 { 138 ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link); 139 140 assert(enode->instance); 141 assert(enode->inode_ref); 142 143 return hash_combine(enode->instance->service_id, enode->inode_ref->index); 144 } 145 146 static bool open_nodes_key_equal(void *key, const ht_link_t *item) 147 { 148 node_key_t *node_key = (node_key_t*)key; 149 ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link); 150 151 return node_key->service_id == enode->instance->service_id 152 && node_key->index == enode->inode_ref->index; 153 } 154 155 static hash_table_ops_t open_nodes_ops = { 153 156 .hash = open_nodes_hash, 154 .compare = open_nodes_compare, 155 .remove_callback = open_nodes_remove_cb, 157 .key_hash = open_nodes_key_hash, 158 .key_equal = open_nodes_key_equal, 159 .equal = 0, 160 .remove_callback = 0, 156 161 }; 157 162 … … 161 166 int ext2fs_global_init(void) 162 167 { 163 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 164 OPEN_NODES_KEYS, &open_nodes_ops)) { 168 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 165 169 return ENOMEM; 166 170 } … … 316 320 317 321 /* Check if the node is not already open */ 318 unsigned long key[]= {319 [OPEN_NODES_DEV_HANDLE_KEY]= inst->service_id,320 [OPEN_NODES_INODE_KEY] = index,322 node_key_t key = { 323 .service_id = inst->service_id, 324 .index = index 321 325 }; 322 link_t *already_open = hash_table_find(&open_nodes,key);326 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 323 327 324 328 if (already_open) { 325 enode = hash_table_get_inst ance(already_open, ext2fs_node_t, link);329 enode = hash_table_get_inst(already_open, ext2fs_node_t, link); 326 330 *rfn = enode->fs_node; 327 331 enode->references++; … … 357 361 enode->references = 1; 358 362 enode->fs_node = node; 359 link_initialize(&enode->link);360 363 361 364 node->data = enode; 362 365 *rfn = node; 363 366 364 hash_table_insert(&open_nodes, key,&enode->link);367 hash_table_insert(&open_nodes, &enode->link); 365 368 inst->open_nodes_count++; 366 369 … … 408 411 int ext2fs_node_put_core(ext2fs_node_t *enode) 409 412 { 410 int rc; 411 412 unsigned long key[] = { 413 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id, 414 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index, 413 node_key_t key = { 414 .service_id = enode->instance->service_id, 415 .index = enode->inode_ref->index 415 416 }; 416 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 417 418 hash_table_remove(&open_nodes, &key); 419 417 420 assert(enode->instance->open_nodes_count > 0); 418 421 enode->instance->open_nodes_count--; 419 422 420 rc = ext2_filesystem_put_inode_ref(enode->inode_ref);423 int rc = ext2_filesystem_put_inode_ref(enode->inode_ref); 421 424 if (rc != EOK) { 422 425 EXT2FS_DBG("ext2_filesystem_put_inode_ref failed"); -
uspace/srv/fs/ext4fs/ext4fs_ops.c
r87e9392 r062d900 42 42 #include <malloc.h> 43 43 #include <adt/hash_table.h> 44 #include <adt/hash.h> 44 45 #include <ipc/loc.h> 45 46 #include "ext4fs.h" … … 48 49 #define EXT4FS_NODE(node) \ 49 50 ((node) ? (ext4fs_node_t *) (node)->data : NULL) 50 51 #define OPEN_NODES_KEYS 252 53 #define OPEN_NODES_DEV_HANDLE_KEY 054 #define OPEN_NODES_INODE_KEY 155 56 #define OPEN_NODES_BUCKETS 25657 51 58 52 /** … … 73 67 ext4_inode_ref_t *inode_ref; 74 68 fs_node_t *fs_node; 75 link_t link;69 ht_link_t link; 76 70 unsigned int references; 77 71 } ext4fs_node_t; … … 115 109 116 110 /* Hash table interface for open nodes hash table */ 117 static hash_index_t open_nodes_hash(unsigned long key[]) 118 { 119 /* TODO: This is very simple and probably can be improved */ 120 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS; 121 } 122 123 /** Compare given item with values in hash table. 124 * 125 */ 126 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 127 link_t *item) 128 { 129 assert(keys > 0); 130 131 ext4fs_node_t *enode = 132 hash_table_get_instance(item, ext4fs_node_t, link); 133 134 if (enode->instance->service_id != 135 ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) 136 return false; 137 138 if (keys == 1) 139 return true; 140 141 assert(keys == 2); 142 143 return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]); 144 } 145 146 /** Empty callback to correct hash table initialization. 147 * 148 */ 149 static void open_nodes_remove_cb(link_t *link) 150 { 151 /* We don't use remove callback for this hash table */ 152 } 153 154 static hash_table_operations_t open_nodes_ops = { 111 112 typedef struct { 113 service_id_t service_id; 114 fs_index_t index; 115 } node_key_t; 116 117 static size_t open_nodes_key_hash(void *key_arg) 118 { 119 node_key_t *key = (node_key_t *)key_arg; 120 return hash_combine(key->service_id, key->index); 121 } 122 123 static size_t open_nodes_hash(const ht_link_t *item) 124 { 125 ext4fs_node_t *enode = hash_table_get_inst(item, ext4fs_node_t, link); 126 return hash_combine(enode->instance->service_id, enode->inode_ref->index); 127 } 128 129 static bool open_nodes_key_equal(void *key_arg, const ht_link_t *item) 130 { 131 node_key_t *key = (node_key_t *)key_arg; 132 ext4fs_node_t *enode = hash_table_get_inst(item, ext4fs_node_t, link); 133 134 return key->service_id == enode->instance->service_id 135 && key->index == enode->inode_ref->index; 136 } 137 138 static hash_table_ops_t open_nodes_ops = { 155 139 .hash = open_nodes_hash, 156 .compare = open_nodes_compare, 157 .remove_callback = open_nodes_remove_cb, 140 .key_hash = open_nodes_key_hash, 141 .key_equal = open_nodes_key_equal, 142 .equal = NULL, 143 .remove_callback = NULL, 158 144 }; 159 145 … … 168 154 int ext4fs_global_init(void) 169 155 { 170 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 171 OPEN_NODES_KEYS, &open_nodes_ops)) 156 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) 172 157 return ENOMEM; 173 158 … … 315 300 316 301 /* Check if the node is not already open */ 317 unsigned long key[]= {318 [OPEN_NODES_DEV_HANDLE_KEY]= inst->service_id,319 [OPEN_NODES_INODE_KEY]= index302 node_key_t key = { 303 .service_id = inst->service_id, 304 .index = index 320 305 }; 321 306 322 link_t *already_open = hash_table_find(&open_nodes,key);307 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 323 308 ext4fs_node_t *enode = NULL; 324 309 if (already_open) { 325 enode = hash_table_get_inst ance(already_open, ext4fs_node_t, link);310 enode = hash_table_get_inst(already_open, ext4fs_node_t, link); 326 311 *rfn = enode->fs_node; 327 312 enode->references++; … … 364 349 enode->references = 1; 365 350 enode->fs_node = fs_node; 366 link_initialize(&enode->link);367 351 368 352 fs_node->data = enode; 369 353 *rfn = fs_node; 370 354 371 hash_table_insert(&open_nodes, key,&enode->link);355 hash_table_insert(&open_nodes, &enode->link); 372 356 inst->open_nodes_count++; 373 357 … … 386 370 int ext4fs_node_put_core(ext4fs_node_t *enode) 387 371 { 388 unsigned long key[] = { 389 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id, 390 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index 391 }; 392 393 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 372 hash_table_remove_item(&open_nodes, &enode->link); 394 373 assert(enode->instance->open_nodes_count > 0); 395 374 enode->instance->open_nodes_count--; … … 498 477 enode->references = 1; 499 478 500 link_initialize(&enode->link);501 502 unsigned long key[] = {503 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,504 [OPEN_NODES_INODE_KEY] = inode_ref->index505 };506 507 479 fibril_mutex_lock(&open_nodes_lock); 508 hash_table_insert(&open_nodes, key,&enode->link);480 hash_table_insert(&open_nodes, &enode->link); 509 481 fibril_mutex_unlock(&open_nodes_lock); 510 482 inst->open_nodes_count++; -
uspace/srv/fs/fat/fat.h
r87e9392 r062d900 190 190 typedef struct { 191 191 /** Used indices (position) hash table link. */ 192 link_t uph_link;192 ht_link_t uph_link; 193 193 /** Used indices (index) hash table link. */ 194 link_t uih_link;194 ht_link_t uih_link; 195 195 196 196 fibril_mutex_t lock; -
uspace/srv/fs/fat/fat_idx.c
r87e9392 r062d900 41 41 #include <str.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <adt/list.h> 44 45 #include <assert.h> … … 58 59 */ 59 60 typedef struct { 60 link_t link;61 service_id_t service_id;61 link_t link; 62 service_id_t service_id; 62 63 63 64 /** Next unassigned index. */ … … 97 98 return u; 98 99 } 99 100 100 101 if (lock) 101 102 fibril_mutex_unlock(&unused_lock); … … 113 114 static hash_table_t up_hash; 114 115 115 #define UPH_BUCKETS_LOG 12 116 #define UPH_BUCKETS (1 << UPH_BUCKETS_LOG) 117 118 #define UPH_SID_KEY 0 119 #define UPH_PFC_KEY 1 120 #define UPH_PDI_KEY 2 121 122 static hash_index_t pos_hash(unsigned long key[]) 123 { 124 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 125 fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY]; 126 unsigned pdi = (unsigned)key[UPH_PDI_KEY]; 127 128 hash_index_t h; 129 130 /* 131 * The least significant half of all bits are the least significant bits 132 * of the parent node's first cluster. 133 * 134 * The least significant half of the most significant half of all bits 135 * are the least significant bits of the node's dentry index within the 136 * parent directory node. 137 * 138 * The most significant half of the most significant half of all bits 139 * are the least significant bits of the device handle. 140 */ 141 h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1); 142 h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 143 (UPH_BUCKETS_LOG / 2); 144 h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 145 (3 * (UPH_BUCKETS_LOG / 4)); 146 147 return h; 148 } 149 150 static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item) 151 { 152 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 116 typedef struct { 117 service_id_t service_id; 153 118 fat_cluster_t pfc; 154 119 unsigned pdi; 155 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 156 157 switch (keys) { 158 case 1: 159 return (service_id == fidx->service_id); 160 case 3: 161 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 162 pdi = (unsigned) key[UPH_PDI_KEY]; 163 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 164 (pdi == fidx->pdi); 165 default: 166 assert((keys == 1) || (keys == 3)); 167 } 168 169 return 0; 170 } 171 172 static void pos_remove_callback(link_t *item) 173 { 174 /* nothing to do */ 175 } 176 177 static hash_table_operations_t uph_ops = { 120 } pos_key_t; 121 122 static inline size_t pos_key_hash(void *key) 123 { 124 pos_key_t *pos = (pos_key_t*)key; 125 126 size_t hash = 0; 127 hash = hash_combine(pos->pfc, pos->pdi); 128 return hash_combine(hash, pos->service_id); 129 } 130 131 static size_t pos_hash(const ht_link_t *item) 132 { 133 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 134 135 pos_key_t pkey = { 136 .service_id = fidx->service_id, 137 .pfc = fidx->pfc, 138 .pdi = fidx->pdi, 139 }; 140 141 return pos_key_hash(&pkey); 142 } 143 144 static bool pos_key_equal(void *key, const ht_link_t *item) 145 { 146 pos_key_t *pos = (pos_key_t*)key; 147 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 148 149 return pos->service_id == fidx->service_id 150 && pos->pdi == fidx->pdi 151 && pos->pfc == fidx->pfc; 152 } 153 154 static hash_table_ops_t uph_ops = { 178 155 .hash = pos_hash, 179 .compare = pos_compare, 180 .remove_callback = pos_remove_callback, 156 .key_hash = pos_key_hash, 157 .key_equal = pos_key_equal, 158 .equal = 0, 159 .remove_callback = 0, 181 160 }; 182 161 … … 187 166 static hash_table_t ui_hash; 188 167 189 #define UIH_BUCKETS_LOG 12 190 #define UIH_BUCKETS (1 << UIH_BUCKETS_LOG) 191 192 #define UIH_SID_KEY 0 193 #define UIH_INDEX_KEY 1 194 195 static hash_index_t idx_hash(unsigned long key[]) 196 { 197 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 198 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 199 200 hash_index_t h; 201 202 h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1); 203 h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) << 204 (UIH_BUCKETS_LOG / 2); 205 206 return h; 207 } 208 209 static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) 210 { 211 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 168 typedef struct { 169 service_id_t service_id; 212 170 fs_index_t index; 213 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 214 215 switch (keys) { 216 case 1: 217 return (service_id == fidx->service_id); 218 case 2: 219 index = (fs_index_t) key[UIH_INDEX_KEY]; 220 return (service_id == fidx->service_id) && 221 (index == fidx->index); 222 default: 223 assert((keys == 1) || (keys == 2)); 224 } 225 226 return 0; 227 } 228 229 static void idx_remove_callback(link_t *item) 230 { 231 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 171 } idx_key_t; 172 173 static size_t idx_key_hash(void *key_arg) 174 { 175 idx_key_t *key = (idx_key_t*)key_arg; 176 return hash_combine(key->service_id, key->index); 177 } 178 179 static size_t idx_hash(const ht_link_t *item) 180 { 181 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 182 return hash_combine(fidx->service_id, fidx->index); 183 } 184 185 static bool idx_key_equal(void *key_arg, const ht_link_t *item) 186 { 187 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 188 idx_key_t *key = (idx_key_t*)key_arg; 189 190 return key->index == fidx->index && key->service_id == fidx->service_id; 191 } 192 193 static void idx_remove_callback(ht_link_t *item) 194 { 195 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 232 196 233 197 free(fidx); 234 198 } 235 199 236 static hash_table_op erations_t uih_ops = {200 static hash_table_ops_t uih_ops = { 237 201 .hash = idx_hash, 238 .compare = idx_compare, 202 .key_hash = idx_key_hash, 203 .key_equal = idx_key_equal, 204 .equal = 0, 239 205 .remove_callback = idx_remove_callback, 240 206 }; … … 377 343 } 378 344 379 link_initialize(&fidx->uph_link);380 link_initialize(&fidx->uih_link);381 345 fibril_mutex_initialize(&fidx->lock); 382 346 fidx->service_id = service_id; … … 401 365 } 402 366 403 unsigned long ikey[] = { 404 [UIH_SID_KEY] = service_id, 405 [UIH_INDEX_KEY] = fidx->index, 406 }; 407 408 hash_table_insert(&ui_hash, ikey, &fidx->uih_link); 367 hash_table_insert(&ui_hash, &fidx->uih_link); 409 368 fibril_mutex_lock(&fidx->lock); 410 369 fibril_mutex_unlock(&used_lock); … … 418 377 { 419 378 fat_idx_t *fidx; 420 link_t *l; 421 unsigned long pkey[]= {422 [UPH_SID_KEY]= service_id,423 [UPH_PFC_KEY]= pfc,424 [UPH_PDI_KEY]= pdi,379 380 pos_key_t pos_key = { 381 .service_id = service_id, 382 .pfc = pfc, 383 .pdi = pdi, 425 384 }; 426 385 427 386 fibril_mutex_lock(&used_lock); 428 l = hash_table_find(&up_hash, pkey);387 ht_link_t *l = hash_table_find(&up_hash, &pos_key); 429 388 if (l) { 430 fidx = hash_table_get_inst ance(l, fat_idx_t, uph_link);389 fidx = hash_table_get_inst(l, fat_idx_t, uph_link); 431 390 } else { 432 391 int rc; … … 438 397 } 439 398 440 unsigned long ikey[] = {441 [UIH_SID_KEY] = service_id,442 [UIH_INDEX_KEY] = fidx->index,443 };444 445 399 fidx->pfc = pfc; 446 400 fidx->pdi = pdi; 447 401 448 hash_table_insert(&up_hash, pkey,&fidx->uph_link);449 hash_table_insert(&ui_hash, ikey,&fidx->uih_link);402 hash_table_insert(&up_hash, &fidx->uph_link); 403 hash_table_insert(&ui_hash, &fidx->uih_link); 450 404 } 451 405 fibril_mutex_lock(&fidx->lock); … … 457 411 void fat_idx_hashin(fat_idx_t *idx) 458 412 { 459 unsigned long pkey[] = { 460 [UPH_SID_KEY] = idx->service_id, 461 [UPH_PFC_KEY] = idx->pfc, 462 [UPH_PDI_KEY] = idx->pdi, 463 }; 464 465 fibril_mutex_lock(&used_lock); 466 hash_table_insert(&up_hash, pkey, &idx->uph_link); 413 fibril_mutex_lock(&used_lock); 414 hash_table_insert(&up_hash, &idx->uph_link); 467 415 fibril_mutex_unlock(&used_lock); 468 416 } … … 470 418 void fat_idx_hashout(fat_idx_t *idx) 471 419 { 472 unsigned long pkey[] = { 473 [UPH_SID_KEY] = idx->service_id, 474 [UPH_PFC_KEY] = idx->pfc, 475 [UPH_PDI_KEY] = idx->pdi, 476 }; 477 478 fibril_mutex_lock(&used_lock); 479 hash_table_remove(&up_hash, pkey, 3); 420 fibril_mutex_lock(&used_lock); 421 hash_table_remove_item(&up_hash, &idx->uph_link); 480 422 fibril_mutex_unlock(&used_lock); 481 423 } … … 485 427 { 486 428 fat_idx_t *fidx = NULL; 487 link_t *l; 488 unsigned long ikey[]= {489 [UIH_SID_KEY]= service_id,490 [UIH_INDEX_KEY]= index,429 430 idx_key_t idx_key = { 431 .service_id = service_id, 432 .index = index, 491 433 }; 492 434 493 435 fibril_mutex_lock(&used_lock); 494 l = hash_table_find(&ui_hash, ikey);436 ht_link_t *l = hash_table_find(&ui_hash, &idx_key); 495 437 if (l) { 496 fidx = hash_table_get_inst ance(l, fat_idx_t, uih_link);438 fidx = hash_table_get_inst(l, fat_idx_t, uih_link); 497 439 fibril_mutex_lock(&fidx->lock); 498 440 } … … 508 450 void fat_idx_destroy(fat_idx_t *idx) 509 451 { 510 unsigned long ikey[]= {511 [UIH_SID_KEY]= idx->service_id,512 [UIH_INDEX_KEY]= idx->index,452 idx_key_t idx_key = { 453 .service_id = idx->service_id, 454 .index = idx->index, 513 455 }; 514 service_id_t service_id = idx->service_id;515 fs_index_t index = idx->index;516 456 517 457 assert(idx->pfc == FAT_CLST_RES0); … … 523 463 * the index hash only. 524 464 */ 525 hash_table_remove(&ui_hash, ikey, 2);465 hash_table_remove(&ui_hash, &idx_key); 526 466 fibril_mutex_unlock(&used_lock); 527 467 /* Release the VFS index. */ 528 fat_index_free( service_id,index);468 fat_index_free(idx_key.service_id, idx_key.index); 529 469 /* The index structure itself is freed in idx_remove_callback(). */ 530 470 } … … 532 472 int fat_idx_init(void) 533 473 { 534 if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))474 if (!hash_table_create(&up_hash, 0, 0, &uph_ops)) 535 475 return ENOMEM; 536 if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {476 if (!hash_table_create(&ui_hash, 0, 0, &uih_ops)) { 537 477 hash_table_destroy(&up_hash); 538 478 return ENOMEM; … … 544 484 { 545 485 /* We assume the hash tables are empty. */ 486 assert(hash_table_empty(&up_hash) && hash_table_empty(&ui_hash)); 546 487 hash_table_destroy(&up_hash); 547 488 hash_table_destroy(&ui_hash); … … 568 509 } 569 510 511 static bool rm_pos_service_id(ht_link_t *item, void *arg) 512 { 513 service_id_t service_id = *(service_id_t*)arg; 514 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 515 516 if (fidx->service_id == service_id) { 517 hash_table_remove_item(&up_hash, item); 518 } 519 520 return true; 521 } 522 523 static bool rm_idx_service_id(ht_link_t *item, void *arg) 524 { 525 service_id_t service_id = *(service_id_t*)arg; 526 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 527 528 if (fidx->service_id == service_id) { 529 hash_table_remove_item(&ui_hash, item); 530 } 531 532 return true; 533 } 534 570 535 void fat_idx_fini_by_service_id(service_id_t service_id) 571 536 { 572 unsigned long ikey[] = {573 [UIH_SID_KEY] = service_id574 };575 unsigned long pkey[] = {576 [UPH_SID_KEY] = service_id577 };578 579 537 /* 580 538 * Remove this instance's index structure from up_hash and ui_hash. … … 583 541 */ 584 542 fibril_mutex_lock(&used_lock); 585 hash_table_ remove(&up_hash, pkey, 1);586 hash_table_ remove(&ui_hash, ikey, 1);543 hash_table_apply(&up_hash, rm_pos_service_id, &service_id); 544 hash_table_apply(&ui_hash, rm_idx_service_id, &service_id); 587 545 fibril_mutex_unlock(&used_lock); 588 546 -
uspace/srv/fs/locfs/locfs_ops.c
r87e9392 r062d900 61 61 async_sess_t *sess; /**< If NULL, the structure is incomplete. */ 62 62 size_t refcount; 63 link_t link;63 ht_link_t link; 64 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } service_t; … … 71 71 static FIBRIL_MUTEX_INITIALIZE(services_mutex); 72 72 73 #define SERVICES_KEYS 174 #define SERVICES_KEY_HANDLE 075 #define SERVICES_BUCKETS 25676 77 73 /* Implementation of hash table interface for the nodes hash table. */ 78 static hash_index_t services_hash(unsigned long key[]) 79 { 80 return key[SERVICES_KEY_HANDLE] % SERVICES_BUCKETS; 81 } 82 83 static int services_compare(unsigned long key[], hash_count_t keys, link_t *item) 84 { 85 service_t *dev = hash_table_get_instance(item, service_t, link); 86 return (dev->service_id == (service_id_t) key[SERVICES_KEY_HANDLE]); 87 } 88 89 static void services_remove_callback(link_t *item) 90 { 91 free(hash_table_get_instance(item, service_t, link)); 92 } 93 94 static hash_table_operations_t services_ops = { 74 75 static size_t services_key_hash(void *key) 76 { 77 return *(service_id_t*)key; 78 } 79 80 static size_t services_hash(const ht_link_t *item) 81 { 82 service_t *dev = hash_table_get_inst(item, service_t, link); 83 return dev->service_id; 84 } 85 86 static bool services_key_equal(void *key, const ht_link_t *item) 87 { 88 service_t *dev = hash_table_get_inst(item, service_t, link); 89 return (dev->service_id == *(service_id_t*)key); 90 } 91 92 static void services_remove_callback(ht_link_t *item) 93 { 94 free(hash_table_get_inst(item, service_t, link)); 95 } 96 97 static hash_table_ops_t services_ops = { 95 98 .hash = services_hash, 96 .compare = services_compare, 99 .key_hash = services_key_hash, 100 .key_equal = services_key_equal, 101 .equal = 0, 97 102 .remove_callback = services_remove_callback 98 103 }; … … 229 234 /* Device node */ 230 235 231 unsigned long key[] = {232 [SERVICES_KEY_HANDLE] = (unsigned long) node->service_id233 };234 link_t *lnk;235 236 236 fibril_mutex_lock(&services_mutex); 237 ht_link_t *lnk; 237 238 restart: 238 lnk = hash_table_find(&services, key);239 lnk = hash_table_find(&services, &node->service_id); 239 240 if (lnk == NULL) { 240 241 service_t *dev = (service_t *) malloc(sizeof(service_t)); … … 256 257 * below. 257 258 */ 258 hash_table_insert(&services, key,&dev->link);259 hash_table_insert(&services, &dev->link); 259 260 260 261 /* … … 279 280 * entry and free the device structure. 280 281 */ 281 hash_table_remove(&services, key, SERVICES_KEYS);282 hash_table_remove(&services, &node->service_id); 282 283 fibril_mutex_unlock(&services_mutex); 283 284 … … 288 289 dev->sess = sess; 289 290 } else { 290 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);291 service_t *dev = hash_table_get_inst(lnk, service_t, link); 291 292 292 293 if (!dev->sess) { … … 450 451 bool locfs_init(void) 451 452 { 452 if (!hash_table_create(&services, SERVICES_BUCKETS, 453 SERVICES_KEYS, &services_ops)) 453 if (!hash_table_create(&services, 0, 0, &services_ops)) 454 454 return false; 455 455 … … 555 555 /* Device node */ 556 556 557 unsigned long key[] = {558 [SERVICES_KEY_HANDLE] = (unsigned long) index559 };560 561 557 fibril_mutex_lock(&services_mutex); 562 link_t *lnk = hash_table_find(&services, key); 558 service_id_t service_index = index; 559 ht_link_t *lnk = hash_table_find(&services, &service_index); 563 560 if (lnk == NULL) { 564 561 fibril_mutex_unlock(&services_mutex); … … 566 563 } 567 564 568 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);565 service_t *dev = hash_table_get_inst(lnk, service_t, link); 569 566 assert(dev->sess); 570 567 … … 621 618 if (type == LOC_OBJECT_SERVICE) { 622 619 /* Device node */ 623 unsigned long key[] = {624 [SERVICES_KEY_HANDLE] = (unsigned long) index625 };626 620 627 621 fibril_mutex_lock(&services_mutex); 628 link_t *lnk = hash_table_find(&services, key); 622 service_id_t service_index = index; 623 ht_link_t *lnk = hash_table_find(&services, &service_index); 629 624 if (lnk == NULL) { 630 625 fibril_mutex_unlock(&services_mutex); … … 632 627 } 633 628 634 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);629 service_t *dev = hash_table_get_inst(lnk, service_t, link); 635 630 assert(dev->sess); 636 631 … … 691 686 692 687 if (type == LOC_OBJECT_SERVICE) { 693 unsigned long key[] = {694 [SERVICES_KEY_HANDLE] = (unsigned long) index695 };696 688 697 689 fibril_mutex_lock(&services_mutex); 698 link_t *lnk = hash_table_find(&services, key); 690 service_id_t service_index = index; 691 ht_link_t *lnk = hash_table_find(&services, &service_index); 699 692 if (lnk == NULL) { 700 693 fibril_mutex_unlock(&services_mutex); … … 702 695 } 703 696 704 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);697 service_t *dev = hash_table_get_inst(lnk, service_t, link); 705 698 assert(dev->sess); 706 699 dev->refcount--; … … 708 701 if (dev->refcount == 0) { 709 702 async_hangup(dev->sess); 710 hash_table_remove(&services, key, SERVICES_KEYS); 703 service_id_t service_index = index; 704 hash_table_remove(&services, &service_index); 711 705 } 712 706 … … 732 726 733 727 if (type == LOC_OBJECT_SERVICE) { 734 unsigned long key[] = { 735 [SERVICES_KEY_HANDLE] = (unsigned long) index 736 }; 737 728 738 729 fibril_mutex_lock(&services_mutex); 739 link_t *lnk = hash_table_find(&services, key); 730 service_id_t service_index = index; 731 ht_link_t *lnk = hash_table_find(&services, &service_index); 740 732 if (lnk == NULL) { 741 733 fibril_mutex_unlock(&services_mutex); … … 743 735 } 744 736 745 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);737 service_t *dev = hash_table_get_inst(lnk, service_t, link); 746 738 assert(dev->sess); 747 739 -
uspace/srv/fs/mfs/mfs.h
r87e9392 r062d900 142 142 unsigned refcnt; 143 143 fs_node_t *fsnode; 144 link_t link;144 ht_link_t link; 145 145 }; 146 146 -
uspace/srv/fs/mfs/mfs_ops.c
r87e9392 r062d900 35 35 #include <align.h> 36 36 #include <adt/hash_table.h> 37 #include <adt/hash.h> 37 38 #include "mfs.h" 38 39 39 #define OPEN_NODES_KEYS 240 #define OPEN_NODES_SERVICE_KEY 041 #define OPEN_NODES_INODE_KEY 142 #define OPEN_NODES_BUCKETS 25643 40 44 41 static bool check_magic_number(uint16_t magic, bool *native, … … 61 58 static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name); 62 59 static int mfs_destroy_node(fs_node_t *fn); 63 static hash_index_t open_nodes_hash(unsigned long key[]);64 static int open_nodes_compare(unsigned long key[], hash_count_t keys,65 link_t *item);66 static void open_nodes_remove_cb(link_t *link);67 60 static int mfs_node_get(fs_node_t **rfn, service_id_t service_id, 68 61 fs_index_t index); … … 95 88 96 89 /* Hash table interface for open nodes hash table */ 97 static hash_index_t 98 open_nodes_hash(unsigned long key[]) 99 { 100 /* TODO: This is very simple and probably can be improved */101 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;102 } 103 104 static int 105 open_nodes_compare(unsigned long key[], hash_count_t keys, 106 link_t *item) 107 { 108 struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link); 109 assert(keys > 0); 110 if (mnode->instance->service_id != 111 ((service_id_t) key[OPEN_NODES_SERVICE_KEY])) { 112 return false; 113 }114 if (keys == 1) {115 return true; 116 } 117 assert(keys == 2); 118 return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]); 119 } 120 121 static void 122 open_nodes_remove_cb(link_t *link) 123 { 124 /* We don't use remove callback for this hash table */125 } 126 127 static hash_table_op erations_t open_nodes_ops = {90 91 typedef struct { 92 service_id_t service_id; 93 fs_index_t index; 94 } node_key_t; 95 96 static size_t 97 open_nodes_key_hash(void *key) 98 { 99 node_key_t *node_key = (node_key_t*)key; 100 return hash_combine(node_key->service_id, node_key->index); 101 } 102 103 static size_t 104 open_nodes_hash(const ht_link_t *item) 105 { 106 struct mfs_node *m = hash_table_get_inst(item, struct mfs_node, link); 107 return hash_combine(m->instance->service_id, m->ino_i->index); 108 } 109 110 static bool 111 open_nodes_key_equal(void *key, const ht_link_t *item) 112 { 113 node_key_t *node_key = (node_key_t*)key; 114 struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link); 115 116 return node_key->service_id == mnode->instance->service_id 117 && node_key->index == mnode->ino_i->index; 118 } 119 120 static hash_table_ops_t open_nodes_ops = { 128 121 .hash = open_nodes_hash, 129 .compare = open_nodes_compare, 130 .remove_callback = open_nodes_remove_cb, 122 .key_hash = open_nodes_key_hash, 123 .key_equal = open_nodes_key_equal, 124 .equal = 0, 125 .remove_callback = 0, 131 126 }; 132 127 … … 134 129 mfs_global_init(void) 135 130 { 136 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 137 OPEN_NODES_KEYS, &open_nodes_ops)) { 131 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 138 132 return ENOMEM; 139 133 } … … 406 400 mnode->refcnt = 1; 407 401 408 link_initialize(&mnode->link);409 410 unsigned long key[] = {411 [OPEN_NODES_SERVICE_KEY] = inst->service_id,412 [OPEN_NODES_INODE_KEY] = inum,413 };414 415 402 fibril_mutex_lock(&open_nodes_lock); 416 hash_table_insert(&open_nodes, key,&mnode->link);403 hash_table_insert(&open_nodes, &mnode->link); 417 404 fibril_mutex_unlock(&open_nodes_lock); 418 405 inst->open_nodes_cnt++; … … 513 500 mnode->refcnt--; 514 501 if (mnode->refcnt == 0) { 515 unsigned long key[] = { 516 [OPEN_NODES_SERVICE_KEY] = mnode->instance->service_id, 517 [OPEN_NODES_INODE_KEY] = mnode->ino_i->index 518 }; 519 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 502 hash_table_remove_item(&open_nodes, &mnode->link); 520 503 assert(mnode->instance->open_nodes_cnt > 0); 521 504 mnode->instance->open_nodes_cnt--; … … 576 559 577 560 /* Check if the node is not already open */ 578 unsigned long key[]= {579 [OPEN_NODES_SERVICE_KEY]= inst->service_id,580 [OPEN_NODES_INODE_KEY] = index,561 node_key_t key = { 562 .service_id = inst->service_id, 563 .index = index 581 564 }; 582 link_t *already_open = hash_table_find(&open_nodes, key); 565 566 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 583 567 584 568 if (already_open) { 585 mnode = hash_table_get_inst ance(already_open, struct mfs_node, link);569 mnode = hash_table_get_inst(already_open, struct mfs_node, link); 586 570 *rfn = mnode->fsnode; 587 571 mnode->refcnt++; … … 614 598 mnode->ino_i = ino_i; 615 599 mnode->refcnt = 1; 616 link_initialize(&mnode->link);617 600 618 601 mnode->instance = inst; … … 621 604 *rfn = node; 622 605 623 hash_table_insert(&open_nodes, key,&mnode->link);606 hash_table_insert(&open_nodes, &mnode->link); 624 607 inst->open_nodes_cnt++; 625 608 -
uspace/srv/fs/tmpfs/tmpfs.h
r87e9392 r062d900 62 62 fs_index_t index; /**< TMPFS node index. */ 63 63 service_id_t service_id;/**< Service ID of block device. */ 64 link_t nh_link; /**< Nodes hash table link. */64 ht_link_t nh_link; /**< Nodes hash table link. */ 65 65 tmpfs_dentry_type_t type; 66 66 unsigned lnkcnt; /**< Link count. */ -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r87e9392 r062d900 50 50 #include <sys/types.h> 51 51 #include <adt/hash_table.h> 52 #include <adt/hash.h> 52 53 #include <as.h> 53 54 #include <libfs.h> … … 55 56 #define min(a, b) ((a) < (b) ? (a) : (b)) 56 57 #define max(a, b) ((a) > (b) ? (a) : (b)) 57 58 #define NODES_BUCKETS 25659 58 60 59 /** All root nodes have index 0. */ … … 142 141 hash_table_t nodes; 143 142 144 #define NODES_KEY_DEV 0 145 #define NODES_KEY_INDEX 1 146 147 /* Implementation of hash table interface for the nodes hash table. */ 148 static hash_index_t nodes_hash(unsigned long key[]) 149 { 150 return key[NODES_KEY_INDEX] % NODES_BUCKETS; 151 } 152 153 static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item) 154 { 155 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 156 nh_link); 157 158 switch (keys) { 159 case 1: 160 return (nodep->service_id == key[NODES_KEY_DEV]); 161 case 2: 162 return ((nodep->service_id == key[NODES_KEY_DEV]) && 163 (nodep->index == key[NODES_KEY_INDEX])); 164 default: 165 assert((keys == 1) || (keys == 2)); 166 } 167 168 return 0; 169 } 170 171 static void nodes_remove_callback(link_t *item) 172 { 173 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 174 nh_link); 143 /* 144 * Implementation of hash table interface for the nodes hash table. 145 */ 146 147 typedef struct { 148 service_id_t service_id; 149 fs_index_t index; 150 } node_key_t; 151 152 static size_t nodes_key_hash(void *k) 153 { 154 node_key_t *key = (node_key_t *)k; 155 return hash_combine(key->service_id, key->index); 156 } 157 158 static size_t nodes_hash(const ht_link_t *item) 159 { 160 tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link); 161 return hash_combine(nodep->service_id, nodep->index); 162 } 163 164 static bool nodes_key_equal(void *key_arg, const ht_link_t *item) 165 { 166 tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link); 167 node_key_t *key = (node_key_t *)key_arg; 168 169 return key->service_id == node->service_id && key->index == node->index; 170 } 171 172 static void nodes_remove_callback(ht_link_t *item) 173 { 174 tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link); 175 175 176 176 while (!list_empty(&nodep->cs_list)) { … … 192 192 193 193 /** TMPFS nodes hash table operations. */ 194 hash_table_op erations_t nodes_ops = {194 hash_table_ops_t nodes_ops = { 195 195 .hash = nodes_hash, 196 .compare = nodes_compare, 196 .key_hash = nodes_key_hash, 197 .key_equal = nodes_key_equal, 198 .equal = 0, 197 199 .remove_callback = nodes_remove_callback 198 200 }; … … 207 209 nodep->size = 0; 208 210 nodep->data = NULL; 209 link_initialize(&nodep->nh_link);210 211 list_initialize(&nodep->cs_list); 211 212 } … … 220 221 bool tmpfs_init(void) 221 222 { 222 if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))223 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 223 224 return false; 224 225 … … 238 239 } 239 240 241 static bool rm_service_id_nodes(ht_link_t *item, void *arg) 242 { 243 service_id_t sid = *(service_id_t*)arg; 244 tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link); 245 246 if (node->service_id == sid) { 247 hash_table_remove_item(&nodes, &node->nh_link); 248 } 249 return true; 250 } 251 240 252 static void tmpfs_instance_done(service_id_t service_id) 241 { 242 unsigned long key[] = { 243 [NODES_KEY_DEV] = service_id 244 }; 245 /* 246 * Here we are making use of one special feature of our hash table 247 * implementation, which allows to remove more items based on a partial 248 * key match. In the following, we are going to remove all nodes 249 * matching our device handle. The nodes_remove_callback() function will 250 * take care of resource deallocation. 251 */ 252 hash_table_remove(&nodes, key, 1); 253 { 254 hash_table_apply(&nodes, rm_service_id_nodes, &service_id); 253 255 } 254 256 … … 272 274 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 273 275 { 274 unsigned long key[]= {275 [NODES_KEY_DEV]= service_id,276 [NODES_KEY_INDEX]= index276 node_key_t key = { 277 .service_id = service_id, 278 .index = index 277 279 }; 278 link_t *lnk = hash_table_find(&nodes, key); 280 281 ht_link_t *lnk = hash_table_find(&nodes, &key); 282 279 283 if (lnk) { 280 284 tmpfs_node_t *nodep; 281 nodep = hash_table_get_inst ance(lnk, tmpfs_node_t, nh_link);285 nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link); 282 286 *rfn = FS_NODE(nodep); 283 287 } else { … … 331 335 332 336 /* Insert the new node into the nodes hash table. */ 333 unsigned long key[] = { 334 [NODES_KEY_DEV] = nodep->service_id, 335 [NODES_KEY_INDEX] = nodep->index 336 }; 337 hash_table_insert(&nodes, key, &nodep->nh_link); 337 hash_table_insert(&nodes, &nodep->nh_link); 338 338 *rfn = FS_NODE(nodep); 339 339 return EOK; … … 346 346 assert(!nodep->lnkcnt); 347 347 assert(list_empty(&nodep->cs_list)); 348 349 unsigned long key[] = { 350 [NODES_KEY_DEV] = nodep->service_id, 351 [NODES_KEY_INDEX] = nodep->index 352 }; 353 hash_table_remove(&nodes, key, 2); 348 349 hash_table_remove_item(&nodes, &nodep->nh_link); 354 350 355 351 /* … … 476 472 * Lookup the respective TMPFS node. 477 473 */ 478 link_t *hlp; 479 unsigned long key[] = { 480 [NODES_KEY_DEV] = service_id, 481 [NODES_KEY_INDEX] = index 474 node_key_t key = { 475 .service_id = service_id, 476 .index = index 482 477 }; 483 hlp = hash_table_find(&nodes, key); 478 479 ht_link_t *hlp = hash_table_find(&nodes, &key); 484 480 if (!hlp) 485 481 return ENOENT; 486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,487 nh_link);482 483 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 488 484 489 485 /* … … 538 534 * Lookup the respective TMPFS node. 539 535 */ 540 link_t *hlp; 541 unsigned long key[] = { 542 [NODES_KEY_DEV] = service_id, 543 [NODES_KEY_INDEX] = index 536 node_key_t key = { 537 .service_id = service_id, 538 .index = index 544 539 }; 545 hlp = hash_table_find(&nodes, key); 540 541 ht_link_t *hlp = hash_table_find(&nodes, &key); 542 546 543 if (!hlp) 547 544 return ENOENT; 548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,549 nh_link);545 546 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 550 547 551 548 /* … … 600 597 * Lookup the respective TMPFS node. 601 598 */ 602 unsigned long key[]= {603 [NODES_KEY_DEV]= service_id,604 [NODES_KEY_INDEX]= index599 node_key_t key = { 600 .service_id = service_id, 601 .index = index 605 602 }; 606 link_t *hlp = hash_table_find(&nodes, key); 603 604 ht_link_t *hlp = hash_table_find(&nodes, &key); 605 607 606 if (!hlp) 608 607 return ENOENT; 609 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t, nh_link);608 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 610 609 611 610 if (size == nodep->size) … … 636 635 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 637 636 { 638 link_t *hlp; 639 unsigned long key[] = { 640 [NODES_KEY_DEV] = service_id, 641 [NODES_KEY_INDEX] = index 637 node_key_t key = { 638 .service_id = service_id, 639 .index = index 642 640 }; 643 hlp = hash_table_find(&nodes, key); 641 642 ht_link_t *hlp = hash_table_find(&nodes, &key); 644 643 if (!hlp) 645 644 return ENOENT; 646 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t,645 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, 647 646 nh_link); 648 647 return tmpfs_destroy_node(FS_NODE(nodep)); -
uspace/srv/hid/input/gsp.c
r87e9392 r062d900 50 50 51 51 #include <adt/hash_table.h> 52 #include <adt/hash.h> 52 53 #include <stdlib.h> 53 54 #include <stdio.h> 54 55 #include "gsp.h" 55 56 56 #define TRANS_TABLE_CHAINS 25657 58 57 /* 59 * Hash table operations for the transition function. 60 */ 61 62 static hash_index_t trans_op_hash(unsigned long key[]); 63 static int trans_op_compare(unsigned long key[], hash_count_t keys, 64 link_t *item); 65 static void trans_op_remove_callback(link_t *item); 66 67 static hash_table_operations_t trans_ops = { 68 .hash = trans_op_hash, 69 .compare = trans_op_compare, 70 .remove_callback = trans_op_remove_callback 58 * Transition function hash table operations. 59 */ 60 typedef struct { 61 int old_state; 62 int input; 63 } trans_key_t; 64 65 static size_t trans_key_hash(void *key) 66 { 67 trans_key_t *trans_key = (trans_key_t *)key; 68 return hash_combine(trans_key->input, trans_key->old_state); 69 } 70 71 static size_t trans_hash(const ht_link_t *item) 72 { 73 gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link); 74 return hash_combine(t->input, t->old_state); 75 } 76 77 static bool trans_key_equal(void *key, const ht_link_t *item) 78 { 79 trans_key_t *trans_key = (trans_key_t *)key; 80 gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link); 81 82 return trans_key->input == t->input && trans_key->old_state == t->old_state; 83 } 84 85 static hash_table_ops_t trans_ops = { 86 .hash = trans_hash, 87 .key_hash = trans_key_hash, 88 .key_equal = trans_key_equal, 89 .equal = 0, 90 .remove_callback = 0 71 91 }; 92 72 93 73 94 static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input); … … 75 96 static gsp_trans_t *trans_new(void); 76 97 77 /** Initiali se scancode parser. */98 /** Initialize scancode parser. */ 78 99 void gsp_init(gsp_t *p) 79 100 { 80 101 p->states = 1; 81 hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);102 hash_table_create(&p->trans, 0, 0, &trans_ops); 82 103 } 83 104 … … 223 244 static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input) 224 245 { 225 link_t *item; 226 unsigned long key[2]; 227 228 key[0] = state; 229 key[1] = input; 230 231 item = hash_table_find(&p->trans, key); 246 ht_link_t *item; 247 248 trans_key_t key = { 249 .input = input, 250 .old_state = state 251 }; 252 253 item = hash_table_find(&p->trans, &key); 232 254 if (item == NULL) return NULL; 233 255 234 return hash_table_get_inst ance(item, gsp_trans_t, link);256 return hash_table_get_inst(item, gsp_trans_t, link); 235 257 } 236 258 … … 242 264 static void trans_insert(gsp_t *p, gsp_trans_t *t) 243 265 { 244 unsigned long key[2]; 245 246 key[0] = t->old_state; 247 key[1] = t->input; 248 249 hash_table_insert(&p->trans, key, &t->link); 266 hash_table_insert(&p->trans, &t->link); 250 267 } 251 268 … … 264 281 } 265 282 266 /*267 * Transition function hash table operations.268 */269 270 static hash_index_t trans_op_hash(unsigned long key[])271 {272 return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;273 }274 275 static int trans_op_compare(unsigned long key[], hash_count_t keys,276 link_t *item)277 {278 gsp_trans_t *t;279 280 t = hash_table_get_instance(item, gsp_trans_t, link);281 return ((key[0] == (unsigned long) t->old_state)282 && (key[1] == (unsigned long) t->input));283 }284 285 static void trans_op_remove_callback(link_t *item)286 {287 }288 283 289 284 /** -
uspace/srv/hid/input/gsp.h
r87e9392 r062d900 56 56 /** Scancode parser transition. */ 57 57 typedef struct { 58 link_t link; /**< Link to hash table in @c gsp_t */58 ht_link_t link; /**< Link to hash table in @c gsp_t */ 59 59 60 60 /* Preconditions */ -
uspace/srv/ns/service.c
r87e9392 r062d900 40 40 #include "ns.h" 41 41 42 #define SERVICE_HASH_TABLE_CHAINS 2043 42 44 43 /** Service hash table item. */ 45 44 typedef struct { 46 link_t link;45 ht_link_t link; 47 46 sysarg_t service; /**< Service ID. */ 48 47 sysarg_t phone; /**< Phone registered with the service. */ … … 50 49 } hashed_service_t; 51 50 52 /** Compute hash index into service hash table. 53 * 54 * @param key Pointer keys. However, only the first key (i.e. service number) 55 * is used to compute the hash index. 56 * 57 * @return Hash index corresponding to key[0]. 58 * 59 */ 60 static hash_index_t service_hash(unsigned long key[]) 51 52 static size_t service_key_hash(void *key) 61 53 { 62 assert(key); 63 return (key[0] % SERVICE_HASH_TABLE_CHAINS); 54 return *(sysarg_t*)key; 64 55 } 65 56 66 /** Compare a key with hashed item. 67 * 68 * This compare function always ignores the third key. 69 * It exists only to make it possible to remove records 70 * originating from connection with key[1] in_phone_hash 71 * value. Note that this is close to being classified 72 * as a nasty hack. 73 * 74 * @param key Array of keys. 75 * @param keys Must be lesser or equal to 3. 76 * @param item Pointer to a hash table item. 77 * 78 * @return Non-zero if the key matches the item, zero otherwise. 79 * 80 */ 81 static int service_compare(unsigned long key[], hash_count_t keys, link_t *item) 57 static size_t service_hash(const ht_link_t *item) 82 58 { 83 assert(key); 84 assert(keys <= 3); 85 assert(item); 86 87 hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link); 88 89 if (keys == 2) 90 return ((key[0] == hs->service) && (key[1] == hs->in_phone_hash)); 91 else 92 return (key[0] == hs->service); 59 hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link); 60 return hs->service; 93 61 } 94 62 95 /** Perform actions after removal of item from the hash table. 96 * 97 * @param item Item that was removed from the hash table. 98 * 99 */ 100 static void service_remove(link_t *item) 63 static bool service_key_equal(void *key, const ht_link_t *item) 101 64 { 102 assert(item);103 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; 104 67 } 105 68 106 69 /** Operations for service hash table. */ 107 static hash_table_op erations_t service_hash_table_ops = {70 static hash_table_ops_t service_hash_table_ops = { 108 71 .hash = service_hash, 109 .compare = service_compare, 110 .remove_callback = service_remove 72 .key_hash = service_key_hash, 73 .key_equal = service_key_equal, 74 .equal = 0, 75 .remove_callback = 0 111 76 }; 112 77 … … 127 92 int service_init(void) 128 93 { 129 if (!hash_table_create(&service_hash_table, SERVICE_HASH_TABLE_CHAINS, 130 3, &service_hash_table_ops)) { 94 if (!hash_table_create(&service_hash_table, 0, 0, &service_hash_table_ops)) { 131 95 printf(NAME ": No memory available for services\n"); 132 96 return ENOMEM; … … 145 109 pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link); 146 110 147 unsigned long keys[3] = { 148 pr->service, 149 0, 150 0 151 }; 152 153 link_t *link = hash_table_find(&service_hash_table, keys); 111 ht_link_t *link = hash_table_find(&service_hash_table, &pr->service); 154 112 if (!link) 155 113 continue; 156 114 157 hashed_service_t *hs = hash_table_get_inst ance(link, hashed_service_t, link);115 hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link); 158 116 (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2, 159 117 pr->arg3, 0, IPC_FF_NONE); … … 176 134 int register_service(sysarg_t service, sysarg_t phone, ipc_call_t *call) 177 135 { 178 unsigned long keys[3] = { 179 service, 180 call->in_phone_hash, 181 0 182 }; 183 184 if (hash_table_find(&service_hash_table, keys)) 136 if (hash_table_find(&service_hash_table, &service)) 185 137 return EEXISTS; 186 138 … … 189 141 return ENOMEM; 190 142 191 link_initialize(&hs->link);192 143 hs->service = service; 193 144 hs->phone = phone; 194 145 hs->in_phone_hash = call->in_phone_hash; 195 hash_table_insert(&service_hash_table, keys,&hs->link);146 hash_table_insert(&service_hash_table, &hs->link); 196 147 197 148 return EOK; … … 210 161 { 211 162 sysarg_t retval; 212 unsigned long keys[3] = {213 service,214 0,215 0216 };217 163 218 link_t *link = hash_table_find(&service_hash_table, keys);164 ht_link_t *link = hash_table_find(&service_hash_table, &service); 219 165 if (!link) { 220 166 if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) { … … 239 185 } 240 186 241 hashed_service_t *hs = hash_table_get_inst ance(link, hashed_service_t, link);187 hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link); 242 188 (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 243 189 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); -
uspace/srv/ns/task.c
r87e9392 r062d900 43 43 #include "ns.h" 44 44 45 #define TASK_HASH_TABLE_CHAINS 25646 #define P2I_HASH_TABLE_CHAINS 25647 45 48 46 /* TODO: … … 55 53 /** Task hash table item. */ 56 54 typedef struct { 57 link_t link;55 ht_link_t link; 58 56 59 57 task_id_t id; /**< Task ID. */ … … 63 61 } hashed_task_t; 64 62 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 */ 73 static 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 */ 88 static 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 */ 108 static void task_remove(link_t *item) 109 { 110 assert(item); 111 free(hash_table_get_instance(item, hashed_task_t, link)); 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)); 112 85 } 113 86 114 87 /** Operations for task hash table. */ 115 static hash_table_op erations_t task_hash_table_ops = {88 static hash_table_ops_t task_hash_table_ops = { 116 89 .hash = task_hash, 117 .compare = task_compare, 90 .key_hash = task_key_hash, 91 .key_equal = task_key_equal, 92 .equal = 0, 118 93 .remove_callback = task_remove 119 94 }; … … 123 98 124 99 typedef struct { 125 link_t link;100 ht_link_t link; 126 101 sysarg_t in_phone_hash; /**< Incoming phone hash. */ 127 102 task_id_t id; /**< Task ID. */ 128 103 } p2i_entry_t; 129 104 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 */ 137 static 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 */ 152 static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item) 153 { 154 assert(key); 155 assert(keys == 1); 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); 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 */ 132 static void p2i_remove(ht_link_t *item) 133 { 156 134 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); 161 } 162 163 /** Perform actions after removal of item from the hash table. 164 * 165 * @param item Item that was removed from the hash table. 166 * 167 */ 168 static void p2i_remove(link_t *item) 169 { 170 assert(item); 171 free(hash_table_get_instance(item, p2i_entry_t, link)); 135 free(hash_table_get_inst(item, p2i_entry_t, link)); 172 136 } 173 137 174 138 /** Operations for task hash table. */ 175 static hash_table_op erations_t p2i_ops = {139 static hash_table_ops_t p2i_ops = { 176 140 .hash = p2i_hash, 177 .compare = p2i_compare, 141 .key_hash = p2i_key_hash, 142 .key_equal = p2i_key_equal, 143 .equal = 0, 178 144 .remove_callback = p2i_remove 179 145 }; … … 193 159 int task_init(void) 194 160 { 195 if (!hash_table_create(&task_hash_table, TASK_HASH_TABLE_CHAINS, 196 2, &task_hash_table_ops)) { 161 if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) { 197 162 printf(NAME ": No memory available for tasks\n"); 198 163 return ENOMEM; 199 164 } 200 165 201 if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS, 202 1, &p2i_ops)) { 166 if (!hash_table_create(&phone_to_id, 0, 0, &p2i_ops)) { 203 167 printf(NAME ": No memory available for tasks\n"); 204 168 return ENOMEM; … … 218 182 pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); 219 183 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); 184 ht_link_t *link = hash_table_find(&task_hash_table, &pr->id); 226 185 if (!link) 227 186 continue; 228 187 229 hashed_task_t *ht = hash_table_get_inst ance(link, hashed_task_t, link);188 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link); 230 189 if (!ht->finished) 231 190 continue; … … 238 197 } 239 198 240 hash_table_remove(&task_hash_table, keys, 2);199 hash_table_remove(&task_hash_table, &pr->id); 241 200 list_remove(cur); 242 201 free(pr); … … 250 209 task_exit_t texit; 251 210 252 unsigned long keys[2] = { 253 LOWER32(id), 254 UPPER32(id) 255 }; 256 257 link_t *link = hash_table_find(&task_hash_table, keys); 211 ht_link_t *link = hash_table_find(&task_hash_table, &id); 258 212 hashed_task_t *ht = (link != NULL) ? 259 hash_table_get_inst ance(link, hashed_task_t, link) : NULL;213 hash_table_get_inst(link, hashed_task_t, link) : NULL; 260 214 261 215 if (ht == NULL) { … … 281 235 } 282 236 283 hash_table_remove (&task_hash_table, keys, 2);237 hash_table_remove_item(&task_hash_table, link); 284 238 retval = EOK; 285 239 … … 293 247 int ns_task_id_intro(ipc_call_t *call) 294 248 { 295 unsigned long keys[2];296 249 297 250 task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 298 keys[0] = call->in_phone_hash; 299 300 link_t *link = hash_table_find(&phone_to_id, keys); 251 252 ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash); 301 253 if (link != NULL) 302 254 return EEXISTS; … … 314 266 */ 315 267 316 link_initialize(&entry->link);317 268 entry->in_phone_hash = call->in_phone_hash; 318 269 entry->id = id; 319 hash_table_insert(&phone_to_id, keys,&entry->link);270 hash_table_insert(&phone_to_id, &entry->link); 320 271 321 272 /* … … 323 274 */ 324 275 325 keys[0] = LOWER32(id);326 keys[1] = UPPER32(id);327 328 link_initialize(&ht->link);329 276 ht->id = id; 330 277 ht->finished = false; 331 278 ht->have_rval = false; 332 279 ht->retval = -1; 333 hash_table_insert(&task_hash_table, keys,&ht->link);280 hash_table_insert(&task_hash_table, &ht->link); 334 281 335 282 return EOK; … … 338 285 static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id) 339 286 { 340 unsigned long keys[1] = {phone_hash}; 341 342 link_t *link = hash_table_find(&phone_to_id, keys); 287 ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash); 343 288 if (link == NULL) 344 289 return ENOENT; 345 290 346 p2i_entry_t *entry = hash_table_get_inst ance(link, p2i_entry_t, link);291 p2i_entry_t *entry = hash_table_get_inst(link, p2i_entry_t, link); 347 292 *id = entry->id; 348 293 … … 357 302 return rc; 358 303 359 unsigned long keys[2] = { 360 LOWER32(id), 361 UPPER32(id) 362 }; 363 364 link_t *link = hash_table_find(&task_hash_table, keys); 304 ht_link_t *link = hash_table_find(&task_hash_table, &id); 365 305 hashed_task_t *ht = (link != NULL) ? 366 hash_table_get_inst ance(link, hashed_task_t, link) : NULL;306 hash_table_get_inst(link, hashed_task_t, link) : NULL; 367 307 368 308 if ((ht == NULL) || (ht->finished)) … … 378 318 int ns_task_disconnect(ipc_call_t *call) 379 319 { 380 unsigned long keys[2];381 382 320 task_id_t id; 383 321 int rc = get_id_by_phone(call->in_phone_hash, &id); … … 386 324 387 325 /* Delete from phone-to-id map. */ 388 keys[0] = call->in_phone_hash; 389 hash_table_remove(&phone_to_id, keys, 1); 326 hash_table_remove(&phone_to_id, &call->in_phone_hash); 390 327 391 328 /* Mark task as finished. */ 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) 329 ht_link_t *link = hash_table_find(&task_hash_table, &id); 330 if (link == NULL) 399 331 return EOK; 332 333 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link); 400 334 401 335 ht->finished = true; -
uspace/srv/vfs/vfs.h
r87e9392 r062d900 36 36 #include <async.h> 37 37 #include <adt/list.h> 38 #include <adt/hash_table.h> 38 39 #include <fibril_synch.h> 39 40 #include <sys/types.h> … … 112 113 unsigned lnkcnt; 113 114 114 link_t nh_link; /**< Node hash-table link. */115 ht_link_t nh_link; /**< Node hash-table link. */ 115 116 116 117 vfs_node_type_t type; /**< Partial info about the node type. */ -
uspace/srv/vfs/vfs_node.c
r87e9392 r062d900 41 41 #include <fibril_synch.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <assert.h> 44 45 #include <async.h> … … 58 59 #define KEY_INDEX 2 59 60 60 static hash_index_t nodes_hash(unsigned long []); 61 static int nodes_compare(unsigned long [], hash_count_t, link_t *); 62 static void nodes_remove_callback(link_t *); 61 static size_t nodes_key_hash(void *); 62 static size_t nodes_hash(const ht_link_t *); 63 static bool nodes_key_equal(void *, const ht_link_t *); 64 static vfs_triplet_t node_triplet(vfs_node_t *node); 63 65 64 66 /** VFS node hash table operations. */ 65 hash_table_op erations_t nodes_ops = {67 hash_table_ops_t nodes_ops = { 66 68 .hash = nodes_hash, 67 .compare = nodes_compare, 68 .remove_callback = nodes_remove_callback 69 .key_hash = nodes_key_hash, 70 .key_equal = nodes_key_equal, 71 .equal = 0, 72 .remove_callback = 0, 69 73 }; 70 74 … … 75 79 bool vfs_nodes_init(void) 76 80 { 77 return hash_table_create(&nodes, NODES_BUCKETS, 3, &nodes_ops);81 return hash_table_create(&nodes, 0, 0, &nodes_ops); 78 82 } 79 83 … … 114 118 */ 115 119 116 unsigned long key[] = { 117 [KEY_FS_HANDLE] = node->fs_handle, 118 [KEY_DEV_HANDLE] = node->service_id, 119 [KEY_INDEX] = node->index 120 }; 121 122 hash_table_remove(&nodes, key, 3); 120 hash_table_remove_item(&nodes, &node->nh_link); 123 121 free_vfs_node = true; 124 122 … … 158 156 { 159 157 fibril_mutex_lock(&nodes_mutex); 160 unsigned long key[] = { 161 [KEY_FS_HANDLE] = node->fs_handle, 162 [KEY_DEV_HANDLE] = node->service_id, 163 [KEY_INDEX] = node->index 164 }; 165 hash_table_remove(&nodes, key, 3); 158 hash_table_remove_item(&nodes, &node->nh_link); 166 159 fibril_mutex_unlock(&nodes_mutex); 167 160 free(node); … … 182 175 vfs_node_t *vfs_node_get(vfs_lookup_res_t *result) 183 176 { 184 unsigned long key[] = {185 [KEY_FS_HANDLE] = result->triplet.fs_handle,186 [KEY_DEV_HANDLE] = result->triplet.service_id,187 [KEY_INDEX] = result->triplet.index188 };189 link_t *tmp;190 177 vfs_node_t *node; 191 178 192 179 fibril_mutex_lock(&nodes_mutex); 193 tmp = hash_table_find(&nodes, key);180 ht_link_t *tmp = hash_table_find(&nodes, &result->triplet); 194 181 if (!tmp) { 195 182 node = (vfs_node_t *) malloc(sizeof(vfs_node_t)); … … 205 192 node->lnkcnt = result->lnkcnt; 206 193 node->type = result->type; 207 link_initialize(&node->nh_link);208 194 fibril_rwlock_initialize(&node->contents_rwlock); 209 hash_table_insert(&nodes, key,&node->nh_link);195 hash_table_insert(&nodes, &node->nh_link); 210 196 } else { 211 node = hash_table_get_inst ance(tmp, vfs_node_t, nh_link);197 node = hash_table_get_inst(tmp, vfs_node_t, nh_link); 212 198 if (node->type == VFS_NODE_UNKNOWN && 213 199 result->type != VFS_NODE_UNKNOWN) { … … 240 226 } 241 227 242 hash_index_t nodes_hash(unsigned long key[])243 {244 hash_index_t a = key[KEY_FS_HANDLE] << (NODES_BUCKETS_LOG / 4);245 hash_index_t b = (a | key[KEY_DEV_HANDLE]) << (NODES_BUCKETS_LOG / 2);246 247 return (b | key[KEY_INDEX]) & (NODES_BUCKETS - 1);248 }249 250 int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item)251 {252 vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);253 return (node->fs_handle == (fs_handle_t) key[KEY_FS_HANDLE]) &&254 (node->service_id == key[KEY_DEV_HANDLE]) &&255 (node->index == key[KEY_INDEX]);256 }257 258 void nodes_remove_callback(link_t *item)259 {260 }261 262 228 struct refcnt_data { 263 229 /** Sum of all reference counts for this file system instance. */ … … 267 233 }; 268 234 269 static void refcnt_visitor(link_t *item, void *arg)270 { 271 vfs_node_t *node = hash_table_get_inst ance(item, vfs_node_t, nh_link);235 static bool refcnt_visitor(ht_link_t *item, void *arg) 236 { 237 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 272 238 struct refcnt_data *rd = (void *) arg; 273 239 … … 275 241 (node->service_id == rd->service_id)) 276 242 rd->refcnt += node->refcnt; 243 244 return true; 277 245 } 278 246 … … 315 283 } 316 284 285 286 static size_t nodes_key_hash(void *key) 287 { 288 vfs_triplet_t *tri = key; 289 size_t hash = hash_combine(tri->fs_handle, tri->index); 290 return hash_combine(hash, tri->service_id); 291 } 292 293 static size_t nodes_hash(const ht_link_t *item) 294 { 295 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 296 vfs_triplet_t tri = node_triplet(node); 297 return nodes_key_hash(&tri); 298 } 299 300 static bool nodes_key_equal(void *key, const ht_link_t *item) 301 { 302 vfs_triplet_t *tri = key; 303 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 304 return node->fs_handle == tri->fs_handle 305 && node->service_id == tri->service_id 306 && node->index == tri->index; 307 } 308 309 static inline vfs_triplet_t node_triplet(vfs_node_t *node) 310 { 311 vfs_triplet_t tri = { 312 .fs_handle = node->fs_handle, 313 .service_id = node->service_id, 314 .index = node->index 315 }; 316 317 return tri; 318 } 319 317 320 /** 318 321 * @}
Note:
See TracChangeset
for help on using the changeset viewer.
