Changeset 062d900 in mainline for uspace/srv/ns
- 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/ns
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
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;
Note:
See TracChangeset
for help on using the changeset viewer.
