Changes in uspace/srv/ns/task.c [4e00f87:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/task.c
r4e00f87 r9d58539 43 43 #include "ns.h" 44 44 45 #define TASK_HASH_TABLE_CHAINS 256 46 #define P2I_HASH_TABLE_CHAINS 256 45 47 46 48 /* TODO: … … 53 55 /** Task hash table item. */ 54 56 typedef struct { 55 ht_link_t link;57 link_t link; 56 58 57 59 task_id_t id; /**< Task ID. */ … … 61 63 } hashed_task_t; 62 64 63 64 static size_t task_key_hash(void *key) 65 { 66 return *(task_id_t*)key; 67 } 68 69 static size_t task_hash(const ht_link_t *item) 70 { 71 hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link); 72 return ht->id; 73 } 74 75 static bool task_key_equal(void *key, const ht_link_t *item) 76 { 77 hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link); 78 return ht->id == *(task_id_t*)key; 79 } 80 81 /** Perform actions after removal of item from the hash table. */ 82 static void task_remove(ht_link_t *item) 83 { 84 free(hash_table_get_inst(item, hashed_task_t, link)); 65 /** Compute hash index into task hash table. 66 * 67 * @param key Pointer keys. However, only the first key (i.e. truncated task 68 * number) is used to compute the hash index. 69 * 70 * @return Hash index corresponding to key[0]. 71 * 72 */ 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)); 85 112 } 86 113 87 114 /** Operations for task hash table. */ 88 static hash_table_op s_t task_hash_table_ops = {115 static hash_table_operations_t task_hash_table_ops = { 89 116 .hash = task_hash, 90 .key_hash = task_key_hash, 91 .key_equal = task_key_equal, 92 .equal = NULL, 117 .compare = task_compare, 93 118 .remove_callback = task_remove 94 119 }; … … 98 123 99 124 typedef struct { 100 ht_link_t link;125 link_t link; 101 126 sysarg_t in_phone_hash; /**< Incoming phone hash. */ 102 127 task_id_t id; /**< Task ID. */ 103 128 } p2i_entry_t; 104 129 105 /* phone-to-id hash table operations */ 106 107 static size_t p2i_key_hash(void *key) 108 { 109 sysarg_t in_phone_hash = *(sysarg_t*)key; 110 return in_phone_hash; 111 } 112 113 static size_t p2i_hash(const ht_link_t *item) 114 { 115 p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link); 116 return entry->in_phone_hash; 117 } 118 119 static bool p2i_key_equal(void *key, const ht_link_t *item) 120 { 121 sysarg_t in_phone_hash = *(sysarg_t*)key; 122 p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link); 123 124 return (in_phone_hash == entry->in_phone_hash); 130 /** Compute hash index into task hash table. 131 * 132 * @param key Array of keys. 133 * 134 * @return Hash index corresponding to key[0]. 135 * 136 */ 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); 156 assert(item); 157 158 p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link); 159 160 return (key[0] == entry->in_phone_hash); 125 161 } 126 162 … … 130 166 * 131 167 */ 132 static void p2i_remove( ht_link_t *item)168 static void p2i_remove(link_t *item) 133 169 { 134 170 assert(item); 135 free(hash_table_get_inst (item, p2i_entry_t, link));171 free(hash_table_get_instance(item, p2i_entry_t, link)); 136 172 } 137 173 138 174 /** Operations for task hash table. */ 139 static hash_table_op s_t p2i_ops = {175 static hash_table_operations_t p2i_ops = { 140 176 .hash = p2i_hash, 141 .key_hash = p2i_key_hash, 142 .key_equal = p2i_key_equal, 143 .equal = NULL, 177 .compare = p2i_compare, 144 178 .remove_callback = p2i_remove 145 179 }; … … 159 193 int task_init(void) 160 194 { 161 if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) { 195 if (!hash_table_create(&task_hash_table, TASK_HASH_TABLE_CHAINS, 196 2, &task_hash_table_ops)) { 162 197 printf(NAME ": No memory available for tasks\n"); 163 198 return ENOMEM; 164 199 } 165 200 166 if (!hash_table_create(&phone_to_id, 0, 0, &p2i_ops)) { 201 if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS, 202 1, &p2i_ops)) { 167 203 printf(NAME ": No memory available for tasks\n"); 168 204 return ENOMEM; … … 182 218 pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); 183 219 184 ht_link_t *link = hash_table_find(&task_hash_table, &pr->id); 220 unsigned long keys[2] = { 221 LOWER32(pr->id), 222 UPPER32(pr->id) 223 }; 224 225 link_t *link = hash_table_find(&task_hash_table, keys); 185 226 if (!link) 186 227 continue; 187 228 188 hashed_task_t *ht = hash_table_get_inst (link, hashed_task_t, link);229 hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link); 189 230 if (!ht->finished) 190 231 continue; … … 197 238 } 198 239 199 hash_table_remove(&task_hash_table, &pr->id);240 hash_table_remove(&task_hash_table, keys, 2); 200 241 list_remove(cur); 201 242 free(pr); … … 209 250 task_exit_t texit; 210 251 211 ht_link_t *link = hash_table_find(&task_hash_table, &id); 252 unsigned long keys[2] = { 253 LOWER32(id), 254 UPPER32(id) 255 }; 256 257 link_t *link = hash_table_find(&task_hash_table, keys); 212 258 hashed_task_t *ht = (link != NULL) ? 213 hash_table_get_inst (link, hashed_task_t, link) : NULL;259 hash_table_get_instance(link, hashed_task_t, link) : NULL; 214 260 215 261 if (ht == NULL) { … … 235 281 } 236 282 237 hash_table_remove _item(&task_hash_table, link);283 hash_table_remove(&task_hash_table, keys, 2); 238 284 retval = EOK; 239 285 … … 247 293 int ns_task_id_intro(ipc_call_t *call) 248 294 { 295 unsigned long keys[2]; 249 296 250 297 task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 251 252 ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash); 298 keys[0] = call->in_phone_hash; 299 300 link_t *link = hash_table_find(&phone_to_id, keys); 253 301 if (link != NULL) 254 302 return EEXISTS; … … 266 314 */ 267 315 316 link_initialize(&entry->link); 268 317 entry->in_phone_hash = call->in_phone_hash; 269 318 entry->id = id; 270 hash_table_insert(&phone_to_id, &entry->link);319 hash_table_insert(&phone_to_id, keys, &entry->link); 271 320 272 321 /* … … 274 323 */ 275 324 325 keys[0] = LOWER32(id); 326 keys[1] = UPPER32(id); 327 328 link_initialize(&ht->link); 276 329 ht->id = id; 277 330 ht->finished = false; 278 331 ht->have_rval = false; 279 332 ht->retval = -1; 280 hash_table_insert(&task_hash_table, &ht->link);333 hash_table_insert(&task_hash_table, keys, &ht->link); 281 334 282 335 return EOK; … … 285 338 static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id) 286 339 { 287 ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash); 340 unsigned long keys[1] = {phone_hash}; 341 342 link_t *link = hash_table_find(&phone_to_id, keys); 288 343 if (link == NULL) 289 344 return ENOENT; 290 345 291 p2i_entry_t *entry = hash_table_get_inst (link, p2i_entry_t, link);346 p2i_entry_t *entry = hash_table_get_instance(link, p2i_entry_t, link); 292 347 *id = entry->id; 293 348 … … 302 357 return rc; 303 358 304 ht_link_t *link = hash_table_find(&task_hash_table, &id); 359 unsigned long keys[2] = { 360 LOWER32(id), 361 UPPER32(id) 362 }; 363 364 link_t *link = hash_table_find(&task_hash_table, keys); 305 365 hashed_task_t *ht = (link != NULL) ? 306 hash_table_get_inst (link, hashed_task_t, link) : NULL;366 hash_table_get_instance(link, hashed_task_t, link) : NULL; 307 367 308 368 if ((ht == NULL) || (ht->finished)) … … 318 378 int ns_task_disconnect(ipc_call_t *call) 319 379 { 380 unsigned long keys[2]; 381 320 382 task_id_t id; 321 383 int rc = get_id_by_phone(call->in_phone_hash, &id); … … 324 386 325 387 /* Delete from phone-to-id map. */ 326 hash_table_remove(&phone_to_id, &call->in_phone_hash); 388 keys[0] = call->in_phone_hash; 389 hash_table_remove(&phone_to_id, keys, 1); 327 390 328 391 /* Mark task as finished. */ 329 ht_link_t *link = hash_table_find(&task_hash_table, &id); 330 if (link == NULL) 392 keys[0] = LOWER32(id); 393 keys[1] = UPPER32(id); 394 395 link_t *link = hash_table_find(&task_hash_table, keys); 396 hashed_task_t *ht = 397 hash_table_get_instance(link, hashed_task_t, link); 398 if (ht == NULL) 331 399 return EOK; 332 333 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);334 400 335 401 ht->finished = true;
Note:
See TracChangeset
for help on using the changeset viewer.