Changeset 5d96851 in mainline
- Timestamp:
- 2009-07-06T19:17:49Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0315679
- Parents:
- 7114d83
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/task.c
r7114d83 r5d96851 163 163 int task_retval(int val) 164 164 { 165 task_id_t id; 166 167 id = task_get_id(); 168 return (int) async_req_3_0(PHONE_NS, NS_RETVAL, LOWER32(id), 169 UPPER32(id), val); 165 return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val); 170 166 } 171 167 -
uspace/lib/libc/include/ipc/ns.h
r7114d83 r5d96851 41 41 NS_PING = IPC_FIRST_USER_METHOD, 42 42 NS_TASK_WAIT, 43 NS_ID_INTRO, 43 44 NS_RETVAL 44 45 } ns_request_t; -
uspace/srv/loader/main.c
r7114d83 r5d96851 53 53 #include <ipc/services.h> 54 54 #include <ipc/loader.h> 55 #include <ipc/ns.h> 56 #include <macros.h> 55 57 #include <loader/pcb.h> 56 58 #include <errno.h> … … 438 440 { 439 441 ipcarg_t phonead; 440 442 task_id_t id; 443 int rc; 444 441 445 connected = false; 442 446 447 /* Introduce this task to the NS (give it our task ID). */ 448 id = task_get_id(); 449 rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id)); 450 if (rc != EOK) 451 return -1; 452 443 453 /* Set a handler of incomming connections. */ 444 454 async_set_client_connection(ldr_connection); … … 446 456 /* Register at naming service. */ 447 457 if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0) 448 return - 1;449 458 return -2; 459 450 460 async_manager(); 451 461 -
uspace/srv/ns/ns.c
r7114d83 r5d96851 134 134 continue; 135 135 case IPC_M_PHONE_HUNGUP: 136 retval = EOK;136 retval = ns_task_disconnect(&call); 137 137 break; 138 138 case IPC_M_CONNECT_TO_ME: … … 171 171 wait_for_task(id, &call, callid); 172 172 continue; 173 case NS_ID_INTRO: 174 retval = ns_task_id_intro(&call); 175 break; 173 176 case NS_RETVAL: 174 177 retval = ns_task_retval(&call); -
uspace/srv/ns/task.c
r7114d83 r5d96851 1 1 /* 2 2 * Copyright (c) 2009 Martin Decky 3 * Copyright (c) 2009 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 42 43 43 44 #define TASK_HASH_TABLE_CHAINS 256 45 #define P2I_HASH_TABLE_CHAINS 256 46 47 static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id); 44 48 45 49 /* TODO: 46 50 * 47 51 * The current implementation of waiting on a task is not perfect. If somebody 48 * wants to wait on a task which has already finished before the NS asked 49 * the kernel to receive notifications, it would block indefinitively. 50 * 51 * A solution to this is to fail immediately on a task for which no creation 52 * notification was received yet. However, there is a danger of a race condition 53 * in this solution -- the caller has to make sure that it is not trying to wait 52 * The caller has to make sure that it is not trying to wait 54 53 * before the NS has a change to receive the task creation notification. This 55 54 * can be assured by waiting for this event in task_spawn(). … … 85 84 * 86 85 * @param key Array of keys. 87 * @param keys Must be less eror equal to 2.86 * @param keys Must be less than or equal to 2. 88 87 * @param item Pointer to a hash table item. 89 88 * … … 127 126 static hash_table_t task_hash_table; 128 127 128 typedef struct { 129 link_t link; 130 ipcarg_t phash; /**< Task ID. */ 131 task_id_t id; /**< Task ID. */ 132 } p2i_entry_t; 133 134 /** Compute hash index into task hash table. 135 * 136 * @param key Array of keys. 137 * @return Hash index corresponding to key[0]. 138 * 139 */ 140 static hash_index_t p2i_hash(unsigned long *key) 141 { 142 assert(key); 143 return (*key % TASK_HASH_TABLE_CHAINS); 144 } 145 146 /** Compare a key with hashed item. 147 * 148 * @param key Array of keys. 149 * @param keys Must be less than or equal to 1. 150 * @param item Pointer to a hash table item. 151 * 152 * @return Non-zero if the key matches the item, zero otherwise. 153 * 154 */ 155 static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item) 156 { 157 assert(key); 158 assert(keys == 1); 159 assert(item); 160 161 p2i_entry_t *e = hash_table_get_instance(item, p2i_entry_t, link); 162 163 return (key[0] == e->phash); 164 } 165 166 /** Perform actions after removal of item from the hash table. 167 * 168 * @param item Item that was removed from the hash table. 169 * 170 */ 171 static void p2i_remove(link_t *item) 172 { 173 assert(item); 174 free(hash_table_get_instance(item, p2i_entry_t, link)); 175 } 176 177 /** Operations for task hash table. */ 178 static hash_table_operations_t p2i_ops = { 179 .hash = p2i_hash, 180 .compare = p2i_compare, 181 .remove_callback = p2i_remove 182 }; 183 184 /** Map phone hash to task ID */ 185 static hash_table_t phone_to_id; 186 129 187 /** Pending task wait structure. */ 130 188 typedef struct { … … 140 198 if (!hash_table_create(&task_hash_table, TASK_HASH_TABLE_CHAINS, 141 199 2, &task_hash_table_ops)) { 200 printf(NAME ": No memory available for tasks\n"); 201 return ENOMEM; 202 } 203 204 if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS, 205 1, &p2i_ops)) { 142 206 printf(NAME ": No memory available for tasks\n"); 143 207 return ENOMEM; … … 239 303 UPPER32(id) 240 304 }; 241 305 242 306 link_t *link = hash_table_find(&task_hash_table, keys); 243 307 hashed_task_t *ht = (link != NULL) ? 244 308 hash_table_get_instance(link, hashed_task_t, link) : NULL; 245 246 if ((ht == NULL) || (!ht->destroyed)) { 309 310 if (ht == NULL) { 311 retval = ENOENT; 312 goto out; 313 } 314 315 if (!ht->destroyed) { 247 316 /* Add to pending list */ 248 317 pending_wait_t *pr = … … 267 336 } 268 337 338 int ns_task_id_intro(ipc_call_t *call) 339 { 340 task_id_t id; 341 unsigned long keys[1]; 342 link_t *link; 343 p2i_entry_t *e; 344 345 id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 346 347 keys[0] = call->in_phone_hash; 348 349 link = hash_table_find(&phone_to_id, keys); 350 if (link != NULL) 351 return EEXISTS; 352 353 e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t)); 354 if (e == NULL) 355 return ENOMEM; 356 357 link_initialize(&e->link); 358 e->phash = call->in_phone_hash; 359 e->id = id; 360 hash_table_insert(&phone_to_id, keys, &e->link); 361 362 return EOK; 363 } 364 269 365 int ns_task_retval(ipc_call_t *call) 270 366 { 271 367 task_id_t id; 272 368 unsigned long keys[2]; 273 274 id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 369 int rc; 370 371 rc = get_id_by_phone(call->in_phone_hash, &id); 372 if (rc != EOK) 373 return rc; 275 374 276 375 keys[0] = LOWER32(id); … … 284 383 return EINVAL; 285 384 286 ht->retval = IPC_GET_ARG3(*call); 385 ht->retval = IPC_GET_ARG1(*call); 386 387 return EOK; 388 } 389 390 int ns_task_disconnect(ipc_call_t *call) 391 { 392 unsigned long keys[1]; 393 394 keys[0] = call->in_phone_hash; 395 hash_table_remove(&phone_to_id, keys, 1); 396 397 return EOK; 398 } 399 400 static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id) 401 { 402 unsigned long keys[1]; 403 link_t *link; 404 p2i_entry_t *e; 405 406 keys[0] = phone_hash; 407 link = hash_table_find(&phone_to_id, keys); 408 if (link == NULL) 409 return ENOENT; 410 411 e = hash_table_get_instance(link, p2i_entry_t, link); 412 *id = e->id; 287 413 288 414 return EOK; -
uspace/srv/ns/task.h
r7114d83 r5d96851 43 43 extern void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid); 44 44 45 extern int ns_task_id_intro(ipc_call_t *call); 46 extern int ns_task_disconnect(ipc_call_t *call); 45 47 extern int ns_task_retval(ipc_call_t *call); 48 46 49 47 50 #endif
Note:
See TracChangeset
for help on using the changeset viewer.