Changes in uspace/srv/ns/task.c [166a1f57:b72efe8] in mainline
- File:
-
- 1 edited
-
uspace/srv/ns/task.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/task.c
r166a1f57 rb72efe8 34 34 #include <ipc/ipc.h> 35 35 #include <adt/hash_table.h> 36 #include < stdbool.h>36 #include <bool.h> 37 37 #include <errno.h> 38 38 #include <assert.h> … … 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); … … 208 249 sysarg_t retval; 209 250 task_exit_t texit; 210 bool remove = false; 211 212 ht_link_t *link = hash_table_find(&task_hash_table, &id); 251 252 unsigned long keys[2] = { 253 LOWER32(id), 254 UPPER32(id) 255 }; 256 257 link_t *link = hash_table_find(&task_hash_table, keys); 213 258 hashed_task_t *ht = (link != NULL) ? 214 hash_table_get_inst (link, hashed_task_t, link) : NULL;259 hash_table_get_instance(link, hashed_task_t, link) : NULL; 215 260 216 261 if (ht == NULL) { … … 236 281 } 237 282 238 remove = true;283 hash_table_remove(&task_hash_table, keys, 2); 239 284 retval = EOK; 240 285 … … 244 289 ipc_answer_2(callid, retval, texit, ht->retval); 245 290 } 246 if (remove)247 hash_table_remove_item(&task_hash_table, link);248 291 } 249 292 250 293 int ns_task_id_intro(ipc_call_t *call) 251 294 { 295 unsigned long keys[2]; 252 296 253 297 task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 254 255 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); 256 301 if (link != NULL) 257 302 return EEXISTS; … … 269 314 */ 270 315 316 link_initialize(&entry->link); 271 317 entry->in_phone_hash = call->in_phone_hash; 272 318 entry->id = id; 273 hash_table_insert(&phone_to_id, &entry->link);319 hash_table_insert(&phone_to_id, keys, &entry->link); 274 320 275 321 /* … … 277 323 */ 278 324 325 keys[0] = LOWER32(id); 326 keys[1] = UPPER32(id); 327 328 link_initialize(&ht->link); 279 329 ht->id = id; 280 330 ht->finished = false; 281 331 ht->have_rval = false; 282 332 ht->retval = -1; 283 hash_table_insert(&task_hash_table, &ht->link);333 hash_table_insert(&task_hash_table, keys, &ht->link); 284 334 285 335 return EOK; … … 288 338 static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id) 289 339 { 290 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); 291 343 if (link == NULL) 292 344 return ENOENT; 293 345 294 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); 295 347 *id = entry->id; 296 348 … … 305 357 return rc; 306 358 307 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); 308 365 hashed_task_t *ht = (link != NULL) ? 309 hash_table_get_inst (link, hashed_task_t, link) : NULL;366 hash_table_get_instance(link, hashed_task_t, link) : NULL; 310 367 311 368 if ((ht == NULL) || (ht->finished)) … … 321 378 int ns_task_disconnect(ipc_call_t *call) 322 379 { 380 unsigned long keys[2]; 381 323 382 task_id_t id; 324 383 int rc = get_id_by_phone(call->in_phone_hash, &id); … … 327 386 328 387 /* Delete from phone-to-id map. */ 329 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); 330 390 331 391 /* Mark task as finished. */ 332 ht_link_t *link = hash_table_find(&task_hash_table, &id); 333 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) 334 399 return EOK; 335 336 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);337 400 338 401 ht->finished = true;
Note:
See TracChangeset
for help on using the changeset viewer.
