Changeset a33f0a6 in mainline for uspace/lib/c/generic
- Timestamp:
- 2011-08-03T17:34:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1940326
- Parents:
- 52a79081 (diff), 3fab770 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/c/generic
- Files:
-
- 11 added
- 1 deleted
- 34 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
r52a79081 ra33f0a6 54 54 * 55 55 */ 56 inthash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,56 bool hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys, 57 57 hash_table_operations_t *op) 58 58 { … … 61 61 assert(max_keys > 0); 62 62 63 h->entry = malloc(m * sizeof(li nk_t));63 h->entry = malloc(m * sizeof(list_t)); 64 64 if (!h->entry) 65 65 return false; 66 66 67 memset((void *) h->entry, 0, m * sizeof(li nk_t));67 memset((void *) h->entry, 0, m * sizeof(list_t)); 68 68 69 69 hash_count_t i; … … 123 123 assert(chain < h->entries); 124 124 125 link_t *cur; 126 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 127 cur = cur->next) { 125 list_foreach(h->entry[chain], cur) { 128 126 if (h->op->compare(key, h->max_keys, cur)) { 129 127 /* … … 153 151 assert(keys <= h->max_keys); 154 152 155 link_t *cur;156 157 153 if (keys == h->max_keys) { 154 link_t *cur; 155 158 156 /* 159 157 * All keys are known, hash_table_find() can be used to find the … … 176 174 hash_index_t chain; 177 175 for (chain = 0; chain < h->entries; chain++) { 178 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 176 link_t *cur; 177 178 for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head; 179 179 cur = cur->next) { 180 180 if (h->op->compare(key, keys, cur)) { … … 203 203 { 204 204 hash_index_t bucket; 205 link_t *cur;206 205 207 206 for (bucket = 0; bucket < h->entries; bucket++) { 208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket]; 209 cur = cur->next) { 207 list_foreach(h->entry[bucket], cur) { 210 208 f(cur, arg); 211 209 } -
uspace/lib/c/generic/adt/list.c
r52a79081 ra33f0a6 30 30 * @{ 31 31 */ 32 /** @file 32 33 /** 34 * @file 35 * @brief Functions completing doubly linked circular list implementaion. 36 * 37 * This file contains some of the functions implementing doubly linked circular lists. 38 * However, this ADT is mostly implemented in @ref list.h. 33 39 */ 34 40 35 41 #include <adt/list.h> 36 42 #include <bool.h> 37 43 38 44 /** Check for membership 39 45 * 40 * Check whether link is contained in the list head.41 * The membership is defined as pointer equivalence.46 * Check whether link is contained in a list. 47 * Membership is defined as pointer equivalence. 42 48 * 43 * @param link 44 * @param headList to look in.49 * @param link Item to look for. 50 * @param list List to look in. 45 51 * 46 52 * @return true if link is contained in head, false otherwise. 47 53 * 48 54 */ 49 int list_member(const link_t *link, const li nk_t *head)55 int list_member(const link_t *link, const list_t *list) 50 56 { 51 int found = 0;52 link_t *hlp = head->next;57 bool found = false; 58 link_t *hlp = list->head.next; 53 59 54 while (hlp != head) {60 while (hlp != &list->head) { 55 61 if (hlp == link) { 56 found = 1;62 found = true; 57 63 break; 58 64 } … … 63 69 } 64 70 65 66 71 /** Concatenate two lists 67 72 * 68 * Concatenate lists head1 and head2, producing a single69 * list head1 containing items from both (in head1, head270 * order) and empty list head2.73 * Concatenate lists @a list1 and @a list2, producing a single 74 * list @a list1 containing items from both (in @a list1, @a list2 75 * order) and empty list @a list2. 71 76 * 72 * @param head1First list and concatenated output73 * @param head2Second list and empty output.77 * @param list1 First list and concatenated output 78 * @param list2 Second list and empty output. 74 79 * 75 80 */ 76 void list_concat(li nk_t *head1, link_t *head2)81 void list_concat(list_t *list1, list_t *list2) 77 82 { 78 if (list_empty( head2))83 if (list_empty(list2)) 79 84 return; 80 81 head2->next->prev = head1->prev;82 head2->prev->next = head1;83 head1->prev->next = head2->next;84 head1->prev = head2->prev;85 list_initialize( head2);85 86 list2->head.next->prev = list1->head.prev; 87 list2->head.prev->next = &list1->head; 88 list1->head.prev->next = list2->head.next; 89 list1->head.prev = list2->head.prev; 90 list_initialize(list2); 86 91 } 87 88 92 89 93 /** Count list items … … 91 95 * Return the number of items in the list. 92 96 * 93 * @param link List to count. 94 * 95 * @return Number of items in the list. 96 * 97 * @param list List to count. 98 * @return Number of items in the list. 97 99 */ 98 unsigned int list_count(const li nk_t *link)100 unsigned int list_count(const list_t *list) 99 101 { 100 102 unsigned int count = 0; 101 link_t *hlp = link->next;102 103 103 while (hlp !=link) {104 list_foreach(*list, link) { 104 105 count++; 105 hlp = hlp->next;106 106 } 107 107 -
uspace/lib/c/generic/adt/measured_strings.c
r52a79081 ra33f0a6 297 297 * size has to be negotiated in advance. 298 298 * 299 * @param[in] phone The other module phone.299 * @param[in] exch Exchange. 300 300 * @param[out] strings The returned measured strings array. 301 301 * @param[out] data The measured strings data. This memory block stores the … … 304 304 * @return EOK on success. 305 305 * @return EINVAL if the strings or data parameter is NULL. 306 * @return EINVAL if the phone or count parameter is not positive.306 * @return EINVAL if the exch or count parameter is invalid. 307 307 * @return EINVAL if the sent array differs in size. 308 308 * @return ENOMEM if there is not enough memory left. … … 310 310 * async_data_read_start() function. 311 311 */ 312 int 313 measured_strings_return(int phone, measured_string_t **strings, uint8_t **data, 314 size_t count) 312 int measured_strings_return(async_exch_t *exch, measured_string_t **strings, 313 uint8_t **data, size_t count) 315 314 { 316 315 size_t *lengths; … … 319 318 int rc; 320 319 321 if (( phone < 0) || (!strings) || (!data) || (count <= 0))320 if ((exch == NULL) || (!strings) || (!data) || (count <= 0)) 322 321 return EINVAL; 323 322 … … 326 325 return ENOMEM; 327 326 328 rc = async_data_read_start( phone, lengths,327 rc = async_data_read_start(exch, lengths, 329 328 sizeof(size_t) * (count + 1)); 330 329 if (rc != EOK) { … … 351 350 (*strings)[index].length = lengths[index]; 352 351 if (lengths[index] > 0) { 353 rc = async_data_read_start( phone, next, lengths[index]);352 rc = async_data_read_start(exch, next, lengths[index]); 354 353 if (rc != EOK) { 355 354 free(lengths); … … 375 374 * size has to be negotiated in advance. 376 375 * 377 * @param[in] phone The other module phone.376 * @param[in] exch Exchange. 378 377 * @param[in] strings The measured strings array to be transferred. 379 378 * @param[in] count The measured strings array size. 380 379 * @return EOK on success. 381 380 * @return EINVAL if the strings parameter is NULL. 382 * @return EINVAL if the phone or count parameter is not positive.381 * @return EINVAL if the exch or count parameter is invalid. 383 382 * @return Other error codes as defined for the 384 383 * async_data_write_start() function. 385 384 */ 386 int 387 measured_strings_send(int phone, const measured_string_t *strings, 385 int measured_strings_send(async_exch_t *exch, const measured_string_t *strings, 388 386 size_t count) 389 387 { … … 392 390 int rc; 393 391 394 if (( phone < 0) || (!strings) || (count <= 0))392 if ((exch == NULL) || (!strings) || (count <= 0)) 395 393 return EINVAL; 396 394 … … 399 397 return ENOMEM; 400 398 401 rc = async_data_write_start( phone, lengths,399 rc = async_data_write_start(exch, lengths, 402 400 sizeof(size_t) * (count + 1)); 403 401 if (rc != EOK) { … … 410 408 for (index = 0; index < count; index++) { 411 409 if (strings[index].length > 0) { 412 rc = async_data_write_start( phone, strings[index].value,410 rc = async_data_write_start(exch, strings[index].value, 413 411 strings[index].length); 414 412 if (rc != EOK) … … 422 420 /** @} 423 421 */ 424 -
uspace/lib/c/generic/as.c
r52a79081 ra33f0a6 35 35 #include <as.h> 36 36 #include <libc.h> 37 #include <errno.h> 37 38 #include <unistd.h> 38 39 #include <align.h> … … 51 52 * 52 53 */ 53 void *as_area_create(void *address, size_t size, int flags)54 void *as_area_create(void *address, size_t size, unsigned int flags) 54 55 { 55 56 return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address, … … 67 68 * 68 69 */ 69 int as_area_resize(void *address, size_t size, int flags)70 int as_area_resize(void *address, size_t size, unsigned int flags) 70 71 { 71 72 return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address, … … 95 96 * 96 97 */ 97 int as_area_change_flags(void *address, int flags)98 int as_area_change_flags(void *address, unsigned int flags) 98 99 { 99 100 return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address, … … 114 115 } 115 116 117 /** Find mapping to physical address. 118 * 119 * @param address Virtual address in question (virtual). 120 * @param[out] frame Frame address (physical). 121 * @return Error code. 122 * @retval EOK No error, @p frame holds the translation. 123 * @retval ENOENT Mapping not found. 124 */ 125 int as_get_physical_mapping(void *address, uintptr_t *frame) 126 { 127 uintptr_t tmp_frame; 128 uintptr_t virt = (uintptr_t) address; 129 130 int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING, 131 (sysarg_t) virt, (sysarg_t) &tmp_frame); 132 if (rc != EOK) { 133 return rc; 134 } 135 136 if (frame != NULL) { 137 *frame = tmp_frame; 138 } 139 140 return EOK; 141 } 142 116 143 /** @} 117 144 */ -
uspace/lib/c/generic/assert.c
r52a79081 ra33f0a6 33 33 #include <assert.h> 34 34 #include <stdio.h> 35 #include <io/klog.h> 35 36 #include <stdlib.h> 37 #include <atomic.h> 36 38 #include <stacktrace.h> 39 #include <stdint.h> 40 41 static atomic_t failed_asserts = {0}; 37 42 38 43 void assert_abort(const char *cond, const char *file, unsigned int line) 39 44 { 45 /* 46 * Send the message safely to klog. Nested asserts should not occur. 47 */ 48 klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n", 49 cond, file, line); 50 51 /* 52 * Check if this is a nested or parallel assert. 53 */ 54 if (atomic_postinc(&failed_asserts)) 55 abort(); 56 57 /* 58 * Attempt to print the message to standard output and display 59 * the stack trace. These operations can theoretically trigger nested 60 * assertions. 61 */ 40 62 printf("Assertion failed (%s) in file \"%s\", line %u.\n", 41 63 cond, file, line); 42 64 stacktrace_print(); 65 43 66 abort(); 44 67 } -
uspace/lib/c/generic/async.c
r52a79081 ra33f0a6 40 40 * programming. 41 41 * 42 * You should be able to write very simple multithreaded programs, the async 43 * framework will automatically take care of most synchronization problems. 42 * You should be able to write very simple multithreaded programs. The async 43 * framework will automatically take care of most of the synchronization 44 * problems. 44 45 * 45 46 * Example of use (pseudo C): … … 53 54 * int fibril1(void *arg) 54 55 * { 55 * conn = async_connect_me_to(); 56 * c1 = async_send(conn); 57 * c2 = async_send(conn); 56 * conn = async_connect_me_to(...); 57 * 58 * exch = async_exchange_begin(conn); 59 * c1 = async_send(exch); 60 * async_exchange_end(exch); 61 * 62 * exch = async_exchange_begin(conn); 63 * c2 = async_send(exch); 64 * async_exchange_end(exch); 65 * 58 66 * async_wait_for(c1); 59 67 * async_wait_for(c2); … … 94 102 #include <futex.h> 95 103 #include <fibril.h> 96 #include <stdio.h>97 104 #include <adt/hash_table.h> 98 105 #include <adt/list.h> … … 102 109 #include <arch/barrier.h> 103 110 #include <bool.h> 111 #include <malloc.h> 112 #include <mem.h> 104 113 #include <stdlib.h> 105 #include <malloc.h>106 114 #include "private/async.h" 107 115 116 #define CLIENT_HASH_TABLE_BUCKETS 32 117 #define CONN_HASH_TABLE_BUCKETS 32 118 119 /** Async framework global futex */ 108 120 atomic_t async_futex = FUTEX_INITIALIZER; 109 121 … … 111 123 atomic_t threads_in_ipc_wait = { 0 }; 112 124 113 typedef struct { 114 awaiter_t wdata; 115 116 /** If reply was received. */ 117 bool done; 118 119 /** Pointer to where the answer data is stored. */ 120 ipc_call_t *dataptr; 121 122 sysarg_t retval; 123 } amsg_t; 124 125 /** 126 * Structures of this type are used to group information about 127 * a call and about a message queue link. 128 */ 125 /** Naming service session */ 126 async_sess_t *session_ns; 127 128 /** Call data */ 129 129 typedef struct { 130 130 link_t link; 131 131 132 ipc_callid_t callid; 132 133 ipc_call_t call; 133 134 } msg_t; 134 135 136 /* Client connection data */ 135 137 typedef struct { 138 link_t link; 139 136 140 sysarg_t in_task_hash; 137 link_t link; 138 int refcnt; 141 atomic_t refcnt; 139 142 void *data; 140 143 } client_t; 141 144 145 /* Server connection data */ 142 146 typedef struct { 143 147 awaiter_t wdata; … … 148 152 /** Incoming client task hash. */ 149 153 sysarg_t in_task_hash; 154 150 155 /** Incoming phone hash. */ 151 156 sysarg_t in_phone_hash; … … 155 160 156 161 /** Messages that should be delivered to this fibril. */ 157 li nk_t msg_queue;162 list_t msg_queue; 158 163 159 164 /** Identification of the opening call. */ … … 161 166 /** Call data of the opening call. */ 162 167 ipc_call_t call; 168 /** Local argument or NULL if none. */ 169 void *carg; 163 170 164 171 /** Identification of the closing call. */ … … 166 173 167 174 /** Fibril function that will be used to handle the connection. */ 168 void (*cfibril)(ipc_callid_t, ipc_call_t *);175 async_client_conn_t cfibril; 169 176 } connection_t; 170 177 171 178 /** Identifier of the incoming connection handled by the current fibril. */ 172 static fibril_local connection_t * FIBRIL_connection;179 static fibril_local connection_t *fibril_connection; 173 180 174 181 static void *default_client_data_constructor(void) … … 196 203 } 197 204 198 void *async_ client_data_get(void)199 { 200 assert( FIBRIL_connection);201 return FIBRIL_connection->client->data;205 void *async_get_client_data(void) 206 { 207 assert(fibril_connection); 208 return fibril_connection->client->data; 202 209 } 203 210 … … 208 215 * @param callid Hash of the incoming call. 209 216 * @param call Data of the incoming call. 210 * 211 */ 212 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 217 * @param arg Local argument 218 * 219 */ 220 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call, 221 void *arg) 213 222 { 214 223 ipc_answer_0(callid, ENOENT); 215 224 } 216 217 /**218 * Pointer to a fibril function that will be used to handle connections.219 */220 static async_client_conn_t client_connection = default_client_connection;221 225 222 226 /** Default fibril function that gets called to handle interrupt notifications. … … 226 230 * @param callid Hash of the incoming call. 227 231 * @param call Data of the incoming call. 232 * @param arg Local argument. 228 233 * 229 234 */ … … 232 237 } 233 238 234 /** 235 * Pointer to a fibril function that will be used to handle interrupt 236 * notifications. 237 */ 238 static async_client_conn_t interrupt_received = default_interrupt_received; 239 static async_client_conn_t client_connection = default_client_connection; 240 static async_interrupt_handler_t interrupt_received = default_interrupt_received; 241 242 /** Setter for client_connection function pointer. 243 * 244 * @param conn Function that will implement a new connection fibril. 245 * 246 */ 247 void async_set_client_connection(async_client_conn_t conn) 248 { 249 client_connection = conn; 250 } 251 252 /** Setter for interrupt_received function pointer. 253 * 254 * @param intr Function that will implement a new interrupt 255 * notification fibril. 256 */ 257 void async_set_interrupt_received(async_interrupt_handler_t intr) 258 { 259 interrupt_received = intr; 260 } 261 262 /** Mutex protecting inactive_exch_list and avail_phone_cv. 263 * 264 */ 265 static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex); 266 267 /** List of all currently inactive exchanges. 268 * 269 */ 270 static LIST_INITIALIZE(inactive_exch_list); 271 272 /** Condition variable to wait for a phone to become available. 273 * 274 */ 275 static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv); 239 276 240 277 static hash_table_t client_hash_table; … … 242 279 static LIST_INITIALIZE(timeout_list); 243 280 244 #define CLIENT_HASH_TABLE_BUCKETS 32245 #define CONN_HASH_TABLE_BUCKETS 32246 247 281 static hash_index_t client_hash(unsigned long key[]) 248 282 { 249 283 assert(key); 284 250 285 return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 251 286 } … … 253 288 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 254 289 { 290 assert(key); 291 assert(item); 292 255 293 client_t *client = hash_table_get_instance(item, client_t, link); 256 294 return (key[0] == client->in_task_hash); … … 278 316 { 279 317 assert(key); 318 280 319 return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS); 281 320 } … … 292 331 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 293 332 { 333 assert(key); 334 assert(item); 335 294 336 connection_t *conn = hash_table_get_instance(item, connection_t, link); 295 337 return (key[0] == conn->in_phone_hash); … … 314 356 void async_insert_timeout(awaiter_t *wd) 315 357 { 358 assert(wd); 359 316 360 wd->to_event.occurred = false; 317 361 wd->to_event.inlist = true; 318 362 319 link_t *tmp = timeout_list. next;320 while (tmp != &timeout_list ) {363 link_t *tmp = timeout_list.head.next; 364 while (tmp != &timeout_list.head) { 321 365 awaiter_t *cur 322 366 = list_get_instance(tmp, awaiter_t, to_event.link); … … 328 372 } 329 373 330 list_ append(&wd->to_event.link, tmp);374 list_insert_before(&wd->to_event.link, tmp); 331 375 } 332 376 … … 346 390 static bool route_call(ipc_callid_t callid, ipc_call_t *call) 347 391 { 392 assert(call); 393 348 394 futex_down(&async_futex); 349 395 … … 400 446 static int notification_fibril(void *arg) 401 447 { 448 assert(arg); 449 402 450 msg_t *msg = (msg_t *) arg; 403 451 interrupt_received(msg->callid, &msg->call); … … 420 468 static bool process_notification(ipc_callid_t callid, ipc_call_t *call) 421 469 { 470 assert(call); 471 422 472 futex_down(&async_futex); 423 473 … … 458 508 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs) 459 509 { 460 assert(FIBRIL_connection); 510 assert(call); 511 assert(fibril_connection); 461 512 462 513 /* Why doing this? 463 * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.514 * GCC 4.1.0 coughs on fibril_connection-> dereference. 464 515 * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot. 465 516 * I would never expect to find so many errors in 466 517 * a compiler. 467 518 */ 468 connection_t *conn = FIBRIL_connection;519 connection_t *conn = fibril_connection; 469 520 470 521 futex_down(&async_futex); … … 518 569 } 519 570 520 msg_t *msg = list_get_instance( conn->msg_queue.next, msg_t, link);571 msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link); 521 572 list_remove(&msg->link); 522 573 … … 541 592 static int connection_fibril(void *arg) 542 593 { 594 assert(arg); 595 543 596 /* 544 597 * Setup fibril-local connection pointer. 545 598 */ 546 FIBRIL_connection = (connection_t *) arg;599 fibril_connection = (connection_t *) arg; 547 600 548 601 futex_down(&async_futex); … … 554 607 */ 555 608 556 unsigned long key = FIBRIL_connection->in_task_hash;609 unsigned long key = fibril_connection->in_task_hash; 557 610 link_t *lnk = hash_table_find(&client_hash_table, &key); 558 611 … … 561 614 if (lnk) { 562 615 client = hash_table_get_instance(lnk, client_t, link); 563 client->refcnt++;616 atomic_inc(&client->refcnt); 564 617 } else { 565 618 client = malloc(sizeof(client_t)); 566 619 if (!client) { 567 ipc_answer_0( FIBRIL_connection->callid, ENOMEM);620 ipc_answer_0(fibril_connection->callid, ENOMEM); 568 621 futex_up(&async_futex); 569 622 return 0; 570 623 } 571 624 572 client->in_task_hash = FIBRIL_connection->in_task_hash; 573 574 async_serialize_start(); 625 client->in_task_hash = fibril_connection->in_task_hash; 575 626 client->data = async_client_data_create(); 576 async_serialize_end(); 577 578 client->refcnt = 1; 627 628 atomic_set(&client->refcnt, 1); 579 629 hash_table_insert(&client_hash_table, &key, &client->link); 580 630 } … … 582 632 futex_up(&async_futex); 583 633 584 FIBRIL_connection->client = client;634 fibril_connection->client = client; 585 635 586 636 /* 587 637 * Call the connection handler function. 588 638 */ 589 FIBRIL_connection->cfibril(FIBRIL_connection->callid,590 & FIBRIL_connection->call);639 fibril_connection->cfibril(fibril_connection->callid, 640 &fibril_connection->call, fibril_connection->carg); 591 641 592 642 /* … … 597 647 futex_down(&async_futex); 598 648 599 if ( --client->refcnt== 0) {649 if (atomic_predec(&client->refcnt) == 0) { 600 650 hash_table_remove(&client_hash_table, &key, 1); 601 651 destroy = true; … … 616 666 */ 617 667 futex_down(&async_futex); 618 key = FIBRIL_connection->in_phone_hash;668 key = fibril_connection->in_phone_hash; 619 669 hash_table_remove(&conn_hash_table, &key, 1); 620 670 futex_up(&async_futex); … … 623 673 * Answer all remaining messages with EHANGUP. 624 674 */ 625 while (!list_empty(& FIBRIL_connection->msg_queue)) {675 while (!list_empty(&fibril_connection->msg_queue)) { 626 676 msg_t *msg = 627 list_get_instance( FIBRIL_connection->msg_queue.next, msg_t,628 link);677 list_get_instance(list_first(&fibril_connection->msg_queue), 678 msg_t, link); 629 679 630 680 list_remove(&msg->link); … … 637 687 * i.e. IPC_M_PHONE_HUNGUP. 638 688 */ 639 if ( FIBRIL_connection->close_callid)640 ipc_answer_0( FIBRIL_connection->close_callid, EOK);641 642 free( FIBRIL_connection);689 if (fibril_connection->close_callid) 690 ipc_answer_0(fibril_connection->close_callid, EOK); 691 692 free(fibril_connection); 643 693 return 0; 644 694 } … … 646 696 /** Create a new fibril for a new connection. 647 697 * 648 * Create new fibril for connection, fill in connection structures and insert s698 * Create new fibril for connection, fill in connection structures and insert 649 699 * it into the hash table, so that later we can easily do routing of messages to 650 700 * particular fibrils. … … 659 709 * @param cfibril Fibril function that should be called upon opening the 660 710 * connection. 711 * @param carg Extra argument to pass to the connection fibril 661 712 * 662 713 * @return New fibril id or NULL on failure. … … 665 716 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash, 666 717 ipc_callid_t callid, ipc_call_t *call, 667 void (*cfibril)(ipc_callid_t, ipc_call_t *))718 async_client_conn_t cfibril, void *carg) 668 719 { 669 720 connection_t *conn = malloc(sizeof(*conn)); … … 680 731 conn->callid = callid; 681 732 conn->close_callid = 0; 733 conn->carg = carg; 682 734 683 735 if (call) … … 721 773 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 722 774 { 775 assert(call); 776 723 777 /* Unrouted call - take some default action */ 724 778 if ((callid & IPC_CALLID_NOTIFICATION)) { … … 732 786 /* Open new connection with fibril, etc. */ 733 787 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call), 734 callid, call, client_connection );788 callid, call, client_connection, NULL); 735 789 return; 736 790 } … … 752 806 futex_down(&async_futex); 753 807 754 link_t *cur = timeout_list.next;755 while (cur != &timeout_list) {808 link_t *cur = list_first(&timeout_list); 809 while (cur != NULL) { 756 810 awaiter_t *waiter = 757 811 list_get_instance(cur, awaiter_t, to_event.link); … … 759 813 if (tv_gt(&waiter->to_event.expires, &tv)) 760 814 break; 761 762 cur = cur->next;763 815 764 816 list_remove(&waiter->to_event.link); … … 774 826 fibril_add_ready(waiter->fid); 775 827 } 828 829 cur = list_first(&timeout_list); 776 830 } 777 831 … … 800 854 suseconds_t timeout; 801 855 if (!list_empty(&timeout_list)) { 802 awaiter_t *waiter = list_get_instance( timeout_list.next,803 awaiter_t, to_event.link);856 awaiter_t *waiter = list_get_instance( 857 list_first(&timeout_list), awaiter_t, to_event.link); 804 858 805 859 struct timeval tv; … … 878 932 void __async_init(void) 879 933 { 880 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,881 &client_hash_table_ops))934 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 935 1, &client_hash_table_ops)) 882 936 abort(); 883 937 884 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,885 &conn_hash_table_ops))938 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 939 1, &conn_hash_table_ops)) 886 940 abort(); 941 942 session_ns = (async_sess_t *) malloc(sizeof(async_sess_t)); 943 if (session_ns == NULL) 944 abort(); 945 946 session_ns->mgmt = EXCHANGE_ATOMIC; 947 session_ns->phone = PHONE_NS; 948 session_ns->arg1 = 0; 949 session_ns->arg2 = 0; 950 session_ns->arg3 = 0; 951 952 list_initialize(&session_ns->exch_list); 953 fibril_mutex_initialize(&session_ns->mutex); 954 atomic_set(&session_ns->refcnt, 0); 887 955 } 888 956 … … 899 967 * 900 968 */ 901 static void reply_received(void *arg, int retval, ipc_call_t *data) 902 { 969 void reply_received(void *arg, int retval, ipc_call_t *data) 970 { 971 assert(arg); 972 903 973 futex_down(&async_futex); 904 974 … … 930 1000 * completion. 931 1001 * 932 * @param phoneid Handle of the phone that will be used for the send.933 * @param method Service-defined method.1002 * @param exch Exchange for sending the message. 1003 * @param imethod Service-defined interface and method. 934 1004 * @param arg1 Service-defined payload argument. 935 1005 * @param arg2 Service-defined payload argument. … … 942 1012 * 943 1013 */ 944 aid_t async_send_fast( int phoneid, sysarg_tmethod, sysarg_t arg1,1014 aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 945 1015 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 946 1016 { 1017 if (exch == NULL) 1018 return 0; 1019 947 1020 amsg_t *msg = malloc(sizeof(amsg_t)); 948 949 if (!msg) 1021 if (msg == NULL) 950 1022 return 0; 951 1023 … … 961 1033 msg->wdata.active = true; 962 1034 963 ipc_call_async_4( phoneid,method, arg1, arg2, arg3, arg4, msg,1035 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg, 964 1036 reply_received, true); 965 1037 … … 972 1044 * completion. 973 1045 * 974 * @param phoneid Handle of the phone that will be used for the send.975 * @param method Service-defined method.1046 * @param exch Exchange for sending the message. 1047 * @param imethod Service-defined interface and method. 976 1048 * @param arg1 Service-defined payload argument. 977 1049 * @param arg2 Service-defined payload argument. … … 985 1057 * 986 1058 */ 987 aid_t async_send_slow( int phoneid, sysarg_tmethod, sysarg_t arg1,1059 aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 988 1060 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 989 1061 ipc_call_t *dataptr) 990 1062 { 1063 if (exch == NULL) 1064 return 0; 1065 991 1066 amsg_t *msg = malloc(sizeof(amsg_t)); 992 1067 993 if ( !msg)1068 if (msg == NULL) 994 1069 return 0; 995 1070 … … 1005 1080 msg->wdata.active = true; 1006 1081 1007 ipc_call_async_5( phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,1008 reply_received, true);1082 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5, 1083 msg, reply_received, true); 1009 1084 1010 1085 return (aid_t) msg; … … 1020 1095 void async_wait_for(aid_t amsgid, sysarg_t *retval) 1021 1096 { 1097 assert(amsgid); 1098 1022 1099 amsg_t *msg = (amsg_t *) amsgid; 1023 1100 … … 1056 1133 int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout) 1057 1134 { 1135 assert(amsgid); 1136 1058 1137 amsg_t *msg = (amsg_t *) amsgid; 1059 1138 … … 1124 1203 } 1125 1204 1126 /** Setter for client_connection function pointer.1127 *1128 * @param conn Function that will implement a new connection fibril.1129 *1130 */1131 void async_set_client_connection(async_client_conn_t conn)1132 {1133 client_connection = conn;1134 }1135 1136 /** Setter for interrupt_received function pointer.1137 *1138 * @param intr Function that will implement a new interrupt1139 * notification fibril.1140 */1141 void async_set_interrupt_received(async_client_conn_t intr)1142 {1143 interrupt_received = intr;1144 }1145 1146 1205 /** Pseudo-synchronous message sending - fast version. 1147 1206 * … … 1151 1210 * transferring more arguments, see the slower async_req_slow(). 1152 1211 * 1153 * @param phoneid Hash of the phone through which to make the call.1154 * @param method Method of the call.1212 * @param exch Exchange for sending the message. 1213 * @param imethod Interface and method of the call. 1155 1214 * @param arg1 Service-defined payload argument. 1156 1215 * @param arg2 Service-defined payload argument. … … 1166 1225 * 1167 1226 */ 1168 sysarg_t async_req_fast( int phoneid, sysarg_tmethod, sysarg_t arg1,1227 sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1169 1228 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, 1170 1229 sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) 1171 1230 { 1231 if (exch == NULL) 1232 return ENOENT; 1233 1172 1234 ipc_call_t result; 1173 aid_t eid = async_send_4(phoneid,method, arg1, arg2, arg3, arg4,1235 aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4, 1174 1236 &result); 1175 1237 1176 1238 sysarg_t rc; 1177 async_wait_for( eid, &rc);1239 async_wait_for(aid, &rc); 1178 1240 1179 1241 if (r1) … … 1199 1261 * Send message asynchronously and return only after the reply arrives. 1200 1262 * 1201 * @param phoneid Hash of the phone through which to make the call.1202 * @param method Method of the call.1263 * @param exch Exchange for sending the message. 1264 * @param imethod Interface and method of the call. 1203 1265 * @param arg1 Service-defined payload argument. 1204 1266 * @param arg2 Service-defined payload argument. … … 1215 1277 * 1216 1278 */ 1217 sysarg_t async_req_slow( int phoneid, sysarg_tmethod, sysarg_t arg1,1279 sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1218 1280 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, 1219 1281 sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) 1220 1282 { 1283 if (exch == NULL) 1284 return ENOENT; 1285 1221 1286 ipc_call_t result; 1222 aid_t eid = async_send_5(phoneid,method, arg1, arg2, arg3, arg4, arg5,1287 aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5, 1223 1288 &result); 1224 1289 1225 1290 sysarg_t rc; 1226 async_wait_for( eid, &rc);1291 async_wait_for(aid, &rc); 1227 1292 1228 1293 if (r1) … … 1244 1309 } 1245 1310 1246 void async_msg_0(int phone, sysarg_t imethod) 1247 { 1248 ipc_call_async_0(phone, imethod, NULL, NULL, true); 1249 } 1250 1251 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1) 1252 { 1253 ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true); 1254 } 1255 1256 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2) 1257 { 1258 ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true); 1259 } 1260 1261 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1262 sysarg_t arg3) 1263 { 1264 ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true); 1265 } 1266 1267 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1268 sysarg_t arg3, sysarg_t arg4) 1269 { 1270 ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL, 1271 true); 1272 } 1273 1274 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1275 sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1276 { 1277 ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL, 1278 NULL, true); 1311 void async_msg_0(async_exch_t *exch, sysarg_t imethod) 1312 { 1313 if (exch != NULL) 1314 ipc_call_async_0(exch->phone, imethod, NULL, NULL, true); 1315 } 1316 1317 void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1) 1318 { 1319 if (exch != NULL) 1320 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true); 1321 } 1322 1323 void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1324 sysarg_t arg2) 1325 { 1326 if (exch != NULL) 1327 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL, 1328 true); 1329 } 1330 1331 void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1332 sysarg_t arg2, sysarg_t arg3) 1333 { 1334 if (exch != NULL) 1335 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL, 1336 NULL, true); 1337 } 1338 1339 void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1340 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 1341 { 1342 if (exch != NULL) 1343 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, 1344 NULL, NULL, true); 1345 } 1346 1347 void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1348 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1349 { 1350 if (exch != NULL) 1351 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, 1352 arg5, NULL, NULL, true); 1279 1353 } 1280 1354 … … 1313 1387 } 1314 1388 1315 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1316 sysarg_t arg1, sysarg_t arg2, unsigned int mode) 1317 { 1318 return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode); 1319 } 1320 1321 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1322 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 1323 unsigned int mode) 1324 { 1325 return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4, 1326 arg5, mode); 1389 int async_forward_fast(ipc_callid_t callid, async_exch_t *exch, 1390 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode) 1391 { 1392 if (exch == NULL) 1393 return ENOENT; 1394 1395 return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode); 1396 } 1397 1398 int async_forward_slow(ipc_callid_t callid, async_exch_t *exch, 1399 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 1400 sysarg_t arg4, sysarg_t arg5, unsigned int mode) 1401 { 1402 if (exch == NULL) 1403 return ENOENT; 1404 1405 return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3, 1406 arg4, arg5, mode); 1327 1407 } 1328 1408 … … 1331 1411 * Ask through phone for a new connection to some service. 1332 1412 * 1333 * @param phone Phone handle used for contacting the other side.1413 * @param exch Exchange for sending the message. 1334 1414 * @param arg1 User defined argument. 1335 1415 * @param arg2 User defined argument. … … 1337 1417 * @param client_receiver Connection handing routine. 1338 1418 * 1339 * @return New phone handle on success or a negative error code. 1340 * 1341 */ 1342 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2, 1343 sysarg_t arg3, async_client_conn_t client_receiver) 1344 { 1419 * @return Zero on success or a negative error code. 1420 * 1421 */ 1422 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 1423 sysarg_t arg3, async_client_conn_t client_receiver, void *carg) 1424 { 1425 if (exch == NULL) 1426 return ENOENT; 1427 1345 1428 sysarg_t task_hash; 1346 1429 sysarg_t phone_hash; 1347 int rc = async_req_3_5( phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,1430 int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1348 1431 NULL, NULL, NULL, &task_hash, &phone_hash); 1349 1432 if (rc != EOK) … … 1352 1435 if (client_receiver != NULL) 1353 1436 async_new_connection(task_hash, phone_hash, 0, NULL, 1354 client_receiver );1437 client_receiver, carg); 1355 1438 1356 1439 return EOK; 1357 1440 } 1358 1441 1359 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1360 * 1361 * Ask through phone for a new connection to some service. 1362 * 1363 * @param phone Phone handle used for contacting the other side. 1364 * @param arg1 User defined argument. 1365 * @param arg2 User defined argument. 1366 * @param arg3 User defined argument. 1367 * 1368 * @return New phone handle on success or a negative error code. 1369 * 1370 */ 1371 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2, 1372 sysarg_t arg3) 1373 { 1374 sysarg_t newphid; 1375 int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1376 NULL, NULL, NULL, NULL, &newphid); 1442 /** Wrapper for making IPC_M_CONNECT_ME calls using the async framework. 1443 * 1444 * Ask through for a cloned connection to some service. 1445 * 1446 * @param mgmt Exchange management style. 1447 * @param exch Exchange for sending the message. 1448 * 1449 * @return New session on success or NULL on error. 1450 * 1451 */ 1452 async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch) 1453 { 1454 if (exch == NULL) { 1455 errno = ENOENT; 1456 return NULL; 1457 } 1458 1459 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1460 if (sess == NULL) { 1461 errno = ENOMEM; 1462 return NULL; 1463 } 1464 1465 ipc_call_t result; 1466 1467 amsg_t *msg = malloc(sizeof(amsg_t)); 1468 if (msg == NULL) { 1469 free(sess); 1470 errno = ENOMEM; 1471 return NULL; 1472 } 1473 1474 msg->done = false; 1475 msg->dataptr = &result; 1476 1477 msg->wdata.to_event.inlist = false; 1478 1479 /* 1480 * We may sleep in the next method, 1481 * but it will use its own means 1482 */ 1483 msg->wdata.active = true; 1484 1485 ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg, 1486 reply_received, true); 1487 1488 sysarg_t rc; 1489 async_wait_for((aid_t) msg, &rc); 1490 1491 if (rc != EOK) { 1492 errno = rc; 1493 free(sess); 1494 return NULL; 1495 } 1496 1497 int phone = (int) IPC_GET_ARG5(result); 1498 1499 if (phone < 0) { 1500 errno = phone; 1501 free(sess); 1502 return NULL; 1503 } 1504 1505 sess->mgmt = mgmt; 1506 sess->phone = phone; 1507 sess->arg1 = 0; 1508 sess->arg2 = 0; 1509 sess->arg3 = 0; 1510 1511 list_initialize(&sess->exch_list); 1512 fibril_mutex_initialize(&sess->mutex); 1513 atomic_set(&sess->refcnt, 0); 1514 1515 return sess; 1516 } 1517 1518 static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2, 1519 sysarg_t arg3, sysarg_t arg4) 1520 { 1521 ipc_call_t result; 1522 1523 amsg_t *msg = malloc(sizeof(amsg_t)); 1524 if (msg == NULL) 1525 return ENOENT; 1526 1527 msg->done = false; 1528 msg->dataptr = &result; 1529 1530 msg->wdata.to_event.inlist = false; 1531 1532 /* 1533 * We may sleep in the next method, 1534 * but it will use its own means 1535 */ 1536 msg->wdata.active = true; 1537 1538 ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4, 1539 msg, reply_received, true); 1540 1541 sysarg_t rc; 1542 async_wait_for((aid_t) msg, &rc); 1377 1543 1378 1544 if (rc != EOK) 1379 1545 return rc; 1380 1546 1381 return newphid; 1547 return (int) IPC_GET_ARG5(result); 1548 } 1549 1550 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1551 * 1552 * Ask through for a new connection to some service. 1553 * 1554 * @param mgmt Exchange management style. 1555 * @param exch Exchange for sending the message. 1556 * @param arg1 User defined argument. 1557 * @param arg2 User defined argument. 1558 * @param arg3 User defined argument. 1559 * 1560 * @return New session on success or NULL on error. 1561 * 1562 */ 1563 async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch, 1564 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 1565 { 1566 if (exch == NULL) { 1567 errno = ENOENT; 1568 return NULL; 1569 } 1570 1571 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1572 if (sess == NULL) { 1573 errno = ENOMEM; 1574 return NULL; 1575 } 1576 1577 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 1578 0); 1579 1580 if (phone < 0) { 1581 errno = phone; 1582 free(sess); 1583 return NULL; 1584 } 1585 1586 sess->mgmt = mgmt; 1587 sess->phone = phone; 1588 sess->arg1 = arg1; 1589 sess->arg2 = arg2; 1590 sess->arg3 = arg3; 1591 1592 list_initialize(&sess->exch_list); 1593 fibril_mutex_initialize(&sess->mutex); 1594 atomic_set(&sess->refcnt, 0); 1595 1596 return sess; 1382 1597 } 1383 1598 … … 1387 1602 * success. 1388 1603 * 1389 * @param phoneid Phone handle used for contacting the other side. 1390 * @param arg1 User defined argument. 1391 * @param arg2 User defined argument. 1392 * @param arg3 User defined argument. 1393 * 1394 * @return New phone handle on success or a negative error code. 1395 * 1396 */ 1397 int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2, 1398 sysarg_t arg3) 1399 { 1400 sysarg_t newphid; 1401 int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1402 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); 1403 1404 if (rc != EOK) 1405 return rc; 1406 1407 return newphid; 1604 * @param mgmt Exchange management style. 1605 * @param exch Exchange for sending the message. 1606 * @param arg1 User defined argument. 1607 * @param arg2 User defined argument. 1608 * @param arg3 User defined argument. 1609 * 1610 * @return New session on success or NULL on error. 1611 * 1612 */ 1613 async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch, 1614 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 1615 { 1616 if (exch == NULL) { 1617 errno = ENOENT; 1618 return NULL; 1619 } 1620 1621 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1622 if (sess == NULL) { 1623 errno = ENOMEM; 1624 return NULL; 1625 } 1626 1627 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 1628 IPC_FLAG_BLOCKING); 1629 1630 if (phone < 0) { 1631 errno = phone; 1632 free(sess); 1633 return NULL; 1634 } 1635 1636 sess->mgmt = mgmt; 1637 sess->phone = phone; 1638 sess->arg1 = arg1; 1639 sess->arg2 = arg2; 1640 sess->arg3 = arg3; 1641 1642 list_initialize(&sess->exch_list); 1643 fibril_mutex_initialize(&sess->mutex); 1644 atomic_set(&sess->refcnt, 0); 1645 1646 return sess; 1408 1647 } 1409 1648 … … 1411 1650 * 1412 1651 */ 1413 int async_connect_kbox(task_id_t id) 1414 { 1415 return ipc_connect_kbox(id); 1652 async_sess_t *async_connect_kbox(task_id_t id) 1653 { 1654 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1655 if (sess == NULL) { 1656 errno = ENOMEM; 1657 return NULL; 1658 } 1659 1660 int phone = ipc_connect_kbox(id); 1661 if (phone < 0) { 1662 errno = phone; 1663 free(sess); 1664 return NULL; 1665 } 1666 1667 sess->mgmt = EXCHANGE_ATOMIC; 1668 sess->phone = phone; 1669 sess->arg1 = 0; 1670 sess->arg2 = 0; 1671 sess->arg3 = 0; 1672 1673 list_initialize(&sess->exch_list); 1674 fibril_mutex_initialize(&sess->mutex); 1675 atomic_set(&sess->refcnt, 0); 1676 1677 return sess; 1678 } 1679 1680 static int async_hangup_internal(int phone) 1681 { 1682 return ipc_hangup(phone); 1416 1683 } 1417 1684 1418 1685 /** Wrapper for ipc_hangup. 1419 1686 * 1420 * @param phone Phone handleto hung up.1687 * @param sess Session to hung up. 1421 1688 * 1422 1689 * @return Zero on success or a negative error code. 1423 1690 * 1424 1691 */ 1425 int async_hangup(int phone) 1426 { 1427 return ipc_hangup(phone); 1692 int async_hangup(async_sess_t *sess) 1693 { 1694 assert(sess); 1695 1696 if (atomic_get(&sess->refcnt) > 0) 1697 return EBUSY; 1698 1699 int rc = async_hangup_internal(sess->phone); 1700 if (rc == EOK) 1701 free(sess); 1702 1703 return rc; 1428 1704 } 1429 1705 … … 1434 1710 } 1435 1711 1712 /** Start new exchange in a session. 1713 * 1714 * @param session Session. 1715 * 1716 * @return New exchange or NULL on error. 1717 * 1718 */ 1719 async_exch_t *async_exchange_begin(async_sess_t *sess) 1720 { 1721 if (sess == NULL) 1722 return NULL; 1723 1724 async_exch_t *exch; 1725 1726 fibril_mutex_lock(&async_sess_mutex); 1727 1728 if (!list_empty(&sess->exch_list)) { 1729 /* 1730 * There are inactive exchanges in the session. 1731 */ 1732 exch = (async_exch_t *) 1733 list_get_instance(list_first(&sess->exch_list), 1734 async_exch_t, sess_link); 1735 1736 list_remove(&exch->sess_link); 1737 list_remove(&exch->global_link); 1738 } else { 1739 /* 1740 * There are no available exchanges in the session. 1741 */ 1742 1743 if ((sess->mgmt == EXCHANGE_ATOMIC) || 1744 (sess->mgmt == EXCHANGE_SERIALIZE)) { 1745 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1746 if (exch != NULL) { 1747 link_initialize(&exch->sess_link); 1748 link_initialize(&exch->global_link); 1749 exch->sess = sess; 1750 exch->phone = sess->phone; 1751 } 1752 } else { /* EXCHANGE_PARALLEL */ 1753 /* 1754 * Make a one-time attempt to connect a new data phone. 1755 */ 1756 1757 int phone; 1758 1759 retry: 1760 phone = async_connect_me_to_internal(sess->phone, sess->arg1, 1761 sess->arg2, sess->arg3, 0); 1762 if (phone >= 0) { 1763 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1764 if (exch != NULL) { 1765 link_initialize(&exch->sess_link); 1766 link_initialize(&exch->global_link); 1767 exch->sess = sess; 1768 exch->phone = phone; 1769 } else 1770 async_hangup_internal(phone); 1771 } else if (!list_empty(&inactive_exch_list)) { 1772 /* 1773 * We did not manage to connect a new phone. But we 1774 * can try to close some of the currently inactive 1775 * connections in other sessions and try again. 1776 */ 1777 exch = (async_exch_t *) 1778 list_get_instance(list_first(&inactive_exch_list), 1779 async_exch_t, global_link); 1780 1781 list_remove(&exch->sess_link); 1782 list_remove(&exch->global_link); 1783 async_hangup_internal(exch->phone); 1784 free(exch); 1785 goto retry; 1786 } else { 1787 /* 1788 * Wait for a phone to become available. 1789 */ 1790 fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex); 1791 goto retry; 1792 } 1793 } 1794 } 1795 1796 fibril_mutex_unlock(&async_sess_mutex); 1797 1798 if (exch != NULL) { 1799 atomic_inc(&sess->refcnt); 1800 1801 if (sess->mgmt == EXCHANGE_SERIALIZE) 1802 fibril_mutex_lock(&sess->mutex); 1803 } 1804 1805 return exch; 1806 } 1807 1808 /** Finish an exchange. 1809 * 1810 * @param exch Exchange to finish. 1811 * 1812 */ 1813 void async_exchange_end(async_exch_t *exch) 1814 { 1815 if (exch == NULL) 1816 return; 1817 1818 async_sess_t *sess = exch->sess; 1819 1820 atomic_dec(&sess->refcnt); 1821 1822 if (sess->mgmt == EXCHANGE_SERIALIZE) 1823 fibril_mutex_unlock(&sess->mutex); 1824 1825 fibril_mutex_lock(&async_sess_mutex); 1826 1827 list_append(&exch->sess_link, &sess->exch_list); 1828 list_append(&exch->global_link, &inactive_exch_list); 1829 fibril_condvar_signal(&avail_phone_cv); 1830 1831 fibril_mutex_unlock(&async_sess_mutex); 1832 } 1833 1436 1834 /** Wrapper for IPC_M_SHARE_IN calls using the async framework. 1437 1835 * 1438 * @param phoneid Phone that will be used to contact the receiving side.1439 * @param dst 1440 * @param size 1441 * @param arg 1442 * @param flags 1836 * @param exch Exchange for sending the message. 1837 * @param dst Destination address space area base. 1838 * @param size Size of the destination address space area. 1839 * @param arg User defined argument. 1840 * @param flags Storage for the received flags. Can be NULL. 1443 1841 * 1444 1842 * @return Zero on success or a negative error code from errno.h. 1445 1843 * 1446 1844 */ 1447 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 1448 unsigned int *flags) 1449 { 1845 int async_share_in_start(async_exch_t *exch, void *dst, size_t size, 1846 sysarg_t arg, unsigned int *flags) 1847 { 1848 if (exch == NULL) 1849 return ENOENT; 1850 1450 1851 sysarg_t tmp_flags; 1451 int res = async_req_3_2( phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,1852 int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst, 1452 1853 (sysarg_t) size, arg, NULL, &tmp_flags); 1453 1854 … … 1507 1908 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework. 1508 1909 * 1509 * @param phoneid Phone that will be used to contact the receiving side.1510 * @param src 1511 * @param flags 1910 * @param exch Exchange for sending the message. 1911 * @param src Source address space area base address. 1912 * @param flags Flags to be used for sharing. Bits can be only cleared. 1512 1913 * 1513 1914 * @return Zero on success or a negative error code from errno.h. 1514 1915 * 1515 1916 */ 1516 int async_share_out_start(int phoneid, void *src, unsigned int flags) 1517 { 1518 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 1917 int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags) 1918 { 1919 if (exch == NULL) 1920 return ENOENT; 1921 1922 return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 1519 1923 (sysarg_t) flags); 1520 1924 } … … 1569 1973 } 1570 1974 1975 /** Start IPC_M_DATA_READ using the async framework. 1976 * 1977 * @param exch Exchange for sending the message. 1978 * @param dst Address of the beginning of the destination buffer. 1979 * @param size Size of the destination buffer (in bytes). 1980 * @param dataptr Storage of call data (arg 2 holds actual data size). 1981 * 1982 * @return Hash of the sent message or 0 on error. 1983 * 1984 */ 1985 aid_t async_data_read(async_exch_t *exch, void *dst, size_t size, 1986 ipc_call_t *dataptr) 1987 { 1988 return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst, 1989 (sysarg_t) size, dataptr); 1990 } 1991 1571 1992 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1572 1993 * 1573 * @param phoneid Phone that will be used to contact the receiving side. 1574 * @param dst Address of the beginning of the destination buffer. 1575 * @param size Size of the destination buffer. 1576 * @param flags Flags to control the data transfer. 1994 * @param exch Exchange for sending the message. 1995 * @param dst Address of the beginning of the destination buffer. 1996 * @param size Size of the destination buffer. 1577 1997 * 1578 1998 * @return Zero on success or a negative error code from errno.h. 1579 1999 * 1580 2000 */ 1581 int 1582 async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags) 1583 { 1584 return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 1585 (sysarg_t) size, (sysarg_t) flags); 2001 int async_data_read_start(async_exch_t *exch, void *dst, size_t size) 2002 { 2003 if (exch == NULL) 2004 return ENOENT; 2005 2006 return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst, 2007 (sysarg_t) size); 1586 2008 } 1587 2009 … … 1638 2060 * 1639 2061 */ 1640 int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1, 1641 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 1642 { 2062 int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod, 2063 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, 2064 ipc_call_t *dataptr) 2065 { 2066 if (exch == NULL) 2067 return ENOENT; 2068 1643 2069 ipc_callid_t callid; 1644 2070 if (!async_data_read_receive(&callid, NULL)) { … … 1647 2073 } 1648 2074 1649 aid_t msg = async_send_fast( phoneid,method, arg1, arg2, arg3, arg4,2075 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 1650 2076 dataptr); 1651 2077 if (msg == 0) { … … 1654 2080 } 1655 2081 1656 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,2082 int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0, 1657 2083 IPC_FF_ROUTE_FROM_ME); 1658 2084 if (retval != EOK) { … … 1670 2096 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework. 1671 2097 * 1672 * @param phoneid Phone that will be used to contact the receiving side. 1673 * @param src Address of the beginning of the source buffer. 1674 * @param size Size of the source buffer. 1675 * @param flags Flags to control the data transfer. 2098 * @param exch Exchange for sending the message. 2099 * @param src Address of the beginning of the source buffer. 2100 * @param size Size of the source buffer. 1676 2101 * 1677 2102 * @return Zero on success or a negative error code from errno.h. 1678 2103 * 1679 2104 */ 1680 int 1681 async_data_write_start_generic(int phoneid, const void *src, size_t size, 1682 int flags) 1683 { 1684 return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src, 1685 (sysarg_t) size, (sysarg_t) flags); 2105 int async_data_write_start(async_exch_t *exch, const void *src, size_t size) 2106 { 2107 if (exch == NULL) 2108 return ENOENT; 2109 2110 return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src, 2111 (sysarg_t) size); 1686 2112 } 1687 2113 … … 1759 2185 size_t *received) 1760 2186 { 2187 assert(data); 2188 1761 2189 ipc_callid_t callid; 1762 2190 size_t size; … … 1826 2254 * 1827 2255 */ 1828 int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1, 1829 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 1830 { 2256 int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod, 2257 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, 2258 ipc_call_t *dataptr) 2259 { 2260 if (exch == NULL) 2261 return ENOENT; 2262 1831 2263 ipc_callid_t callid; 1832 2264 if (!async_data_write_receive(&callid, NULL)) { … … 1835 2267 } 1836 2268 1837 aid_t msg = async_send_fast( phoneid,method, arg1, arg2, arg3, arg4,2269 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 1838 2270 dataptr); 1839 2271 if (msg == 0) { … … 1842 2274 } 1843 2275 1844 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,2276 int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0, 1845 2277 IPC_FF_ROUTE_FROM_ME); 1846 2278 if (retval != EOK) { … … 1856 2288 } 1857 2289 2290 /** Wrapper for sending an exchange over different exchange for cloning 2291 * 2292 * @param exch Exchange to be used for sending. 2293 * @param clone_exch Exchange to be cloned. 2294 * 2295 */ 2296 int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch) 2297 { 2298 return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone); 2299 } 2300 2301 /** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls. 2302 * 2303 * If the current call is IPC_M_CONNECTION_CLONE then a new 2304 * async session is created for the accepted phone. 2305 * 2306 * @param mgmt Exchange management style. 2307 * 2308 * @return New async session or NULL on failure. 2309 * 2310 */ 2311 async_sess_t *async_clone_receive(exch_mgmt_t mgmt) 2312 { 2313 /* Accept the phone */ 2314 ipc_call_t call; 2315 ipc_callid_t callid = async_get_call(&call); 2316 int phone = (int) IPC_GET_ARG1(call); 2317 2318 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) || 2319 (phone < 0)) { 2320 async_answer_0(callid, EINVAL); 2321 return NULL; 2322 } 2323 2324 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2325 if (sess == NULL) { 2326 async_answer_0(callid, ENOMEM); 2327 return NULL; 2328 } 2329 2330 sess->mgmt = mgmt; 2331 sess->phone = phone; 2332 sess->arg1 = 0; 2333 sess->arg2 = 0; 2334 sess->arg3 = 0; 2335 2336 list_initialize(&sess->exch_list); 2337 fibril_mutex_initialize(&sess->mutex); 2338 atomic_set(&sess->refcnt, 0); 2339 2340 /* Acknowledge the cloned phone */ 2341 async_answer_0(callid, EOK); 2342 2343 return sess; 2344 } 2345 2346 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls. 2347 * 2348 * If the current call is IPC_M_CONNECT_TO_ME then a new 2349 * async session is created for the accepted phone. 2350 * 2351 * @param mgmt Exchange management style. 2352 * 2353 * @return New async session. 2354 * @return NULL on failure. 2355 * 2356 */ 2357 async_sess_t *async_callback_receive(exch_mgmt_t mgmt) 2358 { 2359 /* Accept the phone */ 2360 ipc_call_t call; 2361 ipc_callid_t callid = async_get_call(&call); 2362 int phone = (int) IPC_GET_ARG5(call); 2363 2364 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) || 2365 (phone < 0)) { 2366 async_answer_0(callid, EINVAL); 2367 return NULL; 2368 } 2369 2370 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2371 if (sess == NULL) { 2372 async_answer_0(callid, ENOMEM); 2373 return NULL; 2374 } 2375 2376 sess->mgmt = mgmt; 2377 sess->phone = phone; 2378 sess->arg1 = 0; 2379 sess->arg2 = 0; 2380 sess->arg3 = 0; 2381 2382 list_initialize(&sess->exch_list); 2383 fibril_mutex_initialize(&sess->mutex); 2384 atomic_set(&sess->refcnt, 0); 2385 2386 /* Acknowledge the connected phone */ 2387 async_answer_0(callid, EOK); 2388 2389 return sess; 2390 } 2391 2392 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls. 2393 * 2394 * If the call is IPC_M_CONNECT_TO_ME then a new 2395 * async session is created. However, the phone is 2396 * not accepted automatically. 2397 * 2398 * @param mgmt Exchange management style. 2399 * @param call Call data. 2400 * 2401 * @return New async session. 2402 * @return NULL on failure. 2403 * @return NULL if the call is not IPC_M_CONNECT_TO_ME. 2404 * 2405 */ 2406 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call) 2407 { 2408 int phone = (int) IPC_GET_ARG5(*call); 2409 2410 if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) || 2411 (phone < 0)) 2412 return NULL; 2413 2414 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2415 if (sess == NULL) 2416 return NULL; 2417 2418 sess->mgmt = mgmt; 2419 sess->phone = phone; 2420 sess->arg1 = 0; 2421 sess->arg2 = 0; 2422 sess->arg3 = 0; 2423 2424 list_initialize(&sess->exch_list); 2425 fibril_mutex_initialize(&sess->mutex); 2426 atomic_set(&sess->refcnt, 0); 2427 2428 return sess; 2429 } 2430 1858 2431 /** @} 1859 2432 */ -
uspace/lib/c/generic/clipboard.c
r52a79081 ra33f0a6 39 39 40 40 #include <clipboard.h> 41 #include < ipc/ns.h>41 #include <ns.h> 42 42 #include <ipc/services.h> 43 43 #include <ipc/clipboard.h> 44 #include <fibril_synch.h> 44 45 #include <async.h> 45 46 #include <str.h> … … 47 48 #include <malloc.h> 48 49 49 static int clip_phone = -1; 50 51 /** Connect to clipboard server 52 * 53 */ 54 static void clip_connect(void) 55 { 56 while (clip_phone < 0) 57 clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0); 50 static FIBRIL_MUTEX_INITIALIZE(clip_mutex); 51 static async_sess_t *clip_sess = NULL; 52 53 /** Start an async exchange on the clipboard session. 54 * 55 * @return New exchange. 56 * 57 */ 58 static async_exch_t *clip_exchange_begin(void) 59 { 60 fibril_mutex_lock(&clip_mutex); 61 62 while (clip_sess == NULL) 63 clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 64 SERVICE_CLIPBOARD, 0, 0); 65 66 fibril_mutex_unlock(&clip_mutex); 67 68 return async_exchange_begin(clip_sess); 69 } 70 71 /** Finish an async exchange on the clipboard session. 72 * 73 * @param exch Exchange to be finished. 74 * 75 */ 76 static void clip_exchange_end(async_exch_t *exch) 77 { 78 async_exchange_end(exch); 58 79 } 59 80 … … 73 94 74 95 if (size == 0) { 75 async_serialize_start(); 76 clip_connect(); 77 78 sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE); 79 80 async_serialize_end(); 96 async_exch_t *exch = clip_exchange_begin(); 97 sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA, 98 CLIPBOARD_TAG_NONE); 99 clip_exchange_end(exch); 81 100 82 101 return (int) rc; 83 102 } else { 84 async_serialize_start(); 85 clip_connect(); 86 87 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL); 88 sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size); 103 async_exch_t *exch = clip_exchange_begin(); 104 aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, 105 NULL); 106 sysarg_t rc = async_data_write_start(exch, (void *) str, size); 107 clip_exchange_end(exch); 108 89 109 if (rc != EOK) { 90 110 sysarg_t rc_orig; 91 111 async_wait_for(req, &rc_orig); 92 async_serialize_end();93 112 if (rc_orig == EOK) 94 113 return (int) rc; … … 98 117 99 118 async_wait_for(req, &rc); 100 async_serialize_end();101 119 102 120 return (int) rc; … … 117 135 /* Loop until clipboard read succesful */ 118 136 while (true) { 119 async_serialize_start(); 120 clip_connect(); 137 async_exch_t *exch = clip_exchange_begin(); 121 138 122 139 sysarg_t size; 123 140 sysarg_t tag; 124 sysarg_t rc = async_req_0_2( clip_phone, CLIPBOARD_CONTENT, &size, &tag);125 126 async_serialize_end();141 sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag); 142 143 clip_exchange_end(exch); 127 144 128 145 if (rc != EOK) … … 145 162 return ENOMEM; 146 163 147 async_serialize_start(); 148 149 aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL); 150 rc = async_data_read_start(clip_phone, (void *) sbuf, size); 164 exch = clip_exchange_begin(); 165 aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL); 166 rc = async_data_read_start(exch, (void *) sbuf, size); 167 clip_exchange_end(exch); 168 151 169 if ((int) rc == EOVERFLOW) { 152 170 /* … … 154 172 * the last call of CLIPBOARD_CONTENT 155 173 */ 156 async_serialize_end();157 174 break; 158 175 } … … 161 178 sysarg_t rc_orig; 162 179 async_wait_for(req, &rc_orig); 163 async_serialize_end();164 180 if (rc_orig == EOK) 165 181 return (int) rc; … … 169 185 170 186 async_wait_for(req, &rc); 171 async_serialize_end();172 187 173 188 if (rc == EOK) { -
uspace/lib/c/generic/device/char_dev.c
r52a79081 ra33f0a6 45 45 * using its character interface. 46 46 * 47 * @param dev_phone Phoneto the device.48 * @param buf 49 * @param size 50 * @param read 47 * @param sess Session to the device. 48 * @param buf Buffer for the data read from or written to the device. 49 * @param size Maximum size of data (in bytes) to be read or written. 50 * @param read Read from the device if true, write to it otherwise. 51 51 * 52 * @return Non-negative number of bytes actually read from or 53 * written to the device on success, negative error number 54 * otherwise. 52 * @return Non-negative number of bytes actually read from or 53 * written to the device on success, negative error number 54 * otherwise. 55 * 55 56 */ 56 static ssize_t char_dev_rw( int dev_phone, void *buf, size_t size, bool read)57 static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read) 57 58 { 58 async_serialize_start();59 60 59 ipc_call_t answer; 61 60 aid_t req; 62 61 int ret; 63 62 63 async_exch_t *exch = async_exchange_begin(sess); 64 64 65 if (read) { 65 req = async_send_1( dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),66 req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), 66 67 CHAR_DEV_READ, &answer); 67 ret = async_data_read_start( dev_phone, buf, size);68 ret = async_data_read_start(exch, buf, size); 68 69 } else { 69 req = async_send_1( dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),70 req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), 70 71 CHAR_DEV_WRITE, &answer); 71 ret = async_data_write_start( dev_phone, buf, size);72 ret = async_data_write_start(exch, buf, size); 72 73 } 74 75 async_exchange_end(exch); 73 76 74 77 sysarg_t rc; 75 78 if (ret != EOK) { 76 79 async_wait_for(req, &rc); 77 async_serialize_end();78 80 if (rc == EOK) 79 81 return (ssize_t) ret; … … 83 85 84 86 async_wait_for(req, &rc); 85 async_serialize_end();86 87 87 88 ret = (int) rc; … … 94 95 /** Read from character device. 95 96 * 96 * @param dev_phone Phoneto the device.97 * @param buf 98 * @param size 97 * @param sess Session to the device. 98 * @param buf Output buffer for the data read from the device. 99 * @param size Maximum size (in bytes) of the data to be read. 99 100 * 100 * @return Non-negative number of bytes actually read from the 101 * device on success, negative error number otherwise. 101 * @return Non-negative number of bytes actually read from the 102 * device on success, negative error number otherwise. 103 * 102 104 */ 103 ssize_t char_dev_read( int dev_phone, void *buf, size_t size)105 ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size) 104 106 { 105 return char_dev_rw( dev_phone, buf, size, true);107 return char_dev_rw(sess, buf, size, true); 106 108 } 107 109 108 110 /** Write to character device. 109 111 * 110 * @param dev_phone Phoneto the device.111 * @param buf 112 * 113 * @param size 112 * @param sess Session to the device. 113 * @param buf Input buffer containg the data to be written to the 114 * device. 115 * @param size Maximum size (in bytes) of the data to be written. 114 116 * 115 * @return Non-negative number of bytes actually written to the 116 * device on success, negative error number otherwise. 117 * @return Non-negative number of bytes actually written to the 118 * device on success, negative error number otherwise. 119 * 117 120 */ 118 ssize_t char_dev_write( int dev_phone, void *buf, size_t size)121 ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size) 119 122 { 120 return char_dev_rw( dev_phone, buf, size, false);123 return char_dev_rw(sess, buf, size, false); 121 124 } 122 125 -
uspace/lib/c/generic/device/hw_res.c
r52a79081 ra33f0a6 38 38 #include <malloc.h> 39 39 40 int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources) 40 int hw_res_get_resource_list(async_sess_t *sess, 41 hw_resource_list_t *hw_resources) 41 42 { 42 43 sysarg_t count = 0; 43 44 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), 44 45 async_exch_t *exch = async_exchange_begin(sess); 46 int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 45 47 HW_RES_GET_RESOURCE_LIST, &count); 46 47 hw_resources->count = count;48 if (rc != EOK)48 49 if (rc != EOK) { 50 async_exchange_end(exch); 49 51 return rc; 52 } 50 53 51 54 size_t size = count * sizeof(hw_resource_t); 52 hw_resources->resources = (hw_resource_t *)malloc(size); 53 if (!hw_resources->resources) 55 hw_resource_t *resources = (hw_resource_t *) malloc(size); 56 if (resources == NULL) { 57 // FIXME: This is protocol violation 58 async_exchange_end(exch); 54 59 return ENOMEM; 60 } 55 61 56 rc = async_data_read_start(dev_phone, hw_resources->resources, size); 62 rc = async_data_read_start(exch, resources, size); 63 async_exchange_end(exch); 64 57 65 if (rc != EOK) { 58 free(hw_resources->resources); 59 hw_resources->resources = NULL; 66 free(resources); 60 67 return rc; 61 68 } 69 70 hw_resources->resources = resources; 71 hw_resources->count = count; 62 72 63 73 return EOK; 64 74 } 65 75 66 bool hw_res_enable_interrupt( int dev_phone)76 bool hw_res_enable_interrupt(async_sess_t *sess) 67 77 { 68 int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), 78 async_exch_t *exch = async_exchange_begin(sess); 79 int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 69 80 HW_RES_ENABLE_INTERRUPT); 70 71 return rc == EOK; 81 async_exchange_end(exch); 82 83 return (rc == EOK); 72 84 } 73 85 -
uspace/lib/c/generic/devman.c
r52a79081 ra33f0a6 35 35 */ 36 36 37 #include <adt/list.h> 37 38 #include <str.h> 38 #include <stdio.h>39 39 #include <ipc/services.h> 40 #include <ns.h> 40 41 #include <ipc/devman.h> 41 42 #include <devman.h> 43 #include <fibril_synch.h> 42 44 #include <async.h> 43 #include <fibril_synch.h>44 45 #include <errno.h> 45 46 #include <malloc.h> 46 47 #include <bool.h> 47 #include <adt/list.h> 48 49 static int devman_phone_driver = -1; 50 static int devman_phone_client = -1; 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex); 53 54 int devman_get_phone(devman_interface_t iface, unsigned int flags) 48 49 static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex); 50 static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex); 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex); 53 static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex); 54 55 static async_sess_t *devman_driver_block_sess = NULL; 56 static async_sess_t *devman_client_block_sess = NULL; 57 58 static async_sess_t *devman_driver_sess = NULL; 59 static async_sess_t *devman_client_sess = NULL; 60 61 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 62 async_sess_t **dst) 63 { 64 fibril_mutex_lock(mtx); 65 66 if ((*dst == NULL) && (src != NULL)) 67 *dst = src; 68 69 fibril_mutex_unlock(mtx); 70 } 71 72 /** Start an async exchange on the devman session (blocking). 73 * 74 * @param iface Device manager interface to choose 75 * 76 * @return New exchange. 77 * 78 */ 79 async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface) 55 80 { 56 81 switch (iface) { 57 82 case DEVMAN_DRIVER: 58 fibril_mutex_lock(&devman_phone_mutex); 59 if (devman_phone_driver >= 0) { 60 fibril_mutex_unlock(&devman_phone_mutex); 61 return devman_phone_driver; 83 fibril_mutex_lock(&devman_driver_block_mutex); 84 85 while (devman_driver_block_sess == NULL) { 86 clone_session(&devman_driver_mutex, devman_driver_sess, 87 &devman_driver_block_sess); 88 89 if (devman_driver_block_sess == NULL) 90 devman_driver_block_sess = 91 service_connect_blocking(EXCHANGE_SERIALIZE, 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 62 93 } 63 94 64 if (flags & IPC_FLAG_BLOCKING) 65 devman_phone_driver = async_connect_me_to_blocking( 66 PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 67 else 68 devman_phone_driver = async_connect_me_to(PHONE_NS, 69 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 70 71 fibril_mutex_unlock(&devman_phone_mutex); 72 return devman_phone_driver; 95 fibril_mutex_unlock(&devman_driver_block_mutex); 96 97 clone_session(&devman_driver_mutex, devman_driver_block_sess, 98 &devman_driver_sess); 99 100 return async_exchange_begin(devman_driver_block_sess); 73 101 case DEVMAN_CLIENT: 74 fibril_mutex_lock(&devman_phone_mutex); 75 if (devman_phone_client >= 0) { 76 fibril_mutex_unlock(&devman_phone_mutex); 77 return devman_phone_client; 102 fibril_mutex_lock(&devman_client_block_mutex); 103 104 while (devman_client_block_sess == NULL) { 105 clone_session(&devman_client_mutex, devman_client_sess, 106 &devman_client_block_sess); 107 108 if (devman_client_block_sess == NULL) 109 devman_client_block_sess = 110 service_connect_blocking(EXCHANGE_SERIALIZE, 111 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 78 112 } 79 113 80 if (flags & IPC_FLAG_BLOCKING) { 81 devman_phone_client = async_connect_me_to_blocking( 82 PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 83 } else { 84 devman_phone_client = async_connect_me_to(PHONE_NS, 85 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 86 } 87 88 fibril_mutex_unlock(&devman_phone_mutex); 89 return devman_phone_client; 114 fibril_mutex_unlock(&devman_client_block_mutex); 115 116 clone_session(&devman_client_mutex, devman_client_block_sess, 117 &devman_client_sess); 118 119 return async_exchange_begin(devman_client_block_sess); 90 120 default: 91 return -1; 92 } 121 return NULL; 122 } 123 } 124 125 /** Start an async exchange on the devman session. 126 * 127 * @param iface Device manager interface to choose 128 * 129 * @return New exchange. 130 * 131 */ 132 async_exch_t *devman_exchange_begin(devman_interface_t iface) 133 { 134 switch (iface) { 135 case DEVMAN_DRIVER: 136 fibril_mutex_lock(&devman_driver_mutex); 137 138 if (devman_driver_sess == NULL) 139 devman_driver_sess = 140 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN, 141 DEVMAN_DRIVER, 0); 142 143 fibril_mutex_unlock(&devman_driver_mutex); 144 145 if (devman_driver_sess == NULL) 146 return NULL; 147 148 return async_exchange_begin(devman_driver_sess); 149 case DEVMAN_CLIENT: 150 fibril_mutex_lock(&devman_client_mutex); 151 152 if (devman_client_sess == NULL) 153 devman_client_sess = 154 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN, 155 DEVMAN_CLIENT, 0); 156 157 fibril_mutex_unlock(&devman_client_mutex); 158 159 if (devman_client_sess == NULL) 160 return NULL; 161 162 return async_exchange_begin(devman_client_sess); 163 default: 164 return NULL; 165 } 166 } 167 168 /** Finish an async exchange on the devman session. 169 * 170 * @param exch Exchange to be finished. 171 * 172 */ 173 void devman_exchange_end(async_exch_t *exch) 174 { 175 async_exchange_end(exch); 93 176 } 94 177 … … 96 179 int devman_driver_register(const char *name, async_client_conn_t conn) 97 180 { 98 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 99 100 if (phone < 0) 101 return phone; 102 103 async_serialize_start(); 104 105 ipc_call_t answer; 106 aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 107 108 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 109 if (retval != EOK) { 110 async_wait_for(req, NULL); 111 async_serialize_end(); 112 return -1; 181 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 182 183 ipc_call_t answer; 184 aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 185 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 186 187 devman_exchange_end(exch); 188 189 if (retval != EOK) { 190 async_wait_for(req, NULL); 191 return retval; 113 192 } 114 193 115 194 async_set_client_connection(conn); 116 195 117 async_connect_to_me(phone, 0, 0, 0, NULL); 196 exch = devman_exchange_begin(DEVMAN_DRIVER); 197 async_connect_to_me(exch, 0, 0, 0, NULL, NULL); 198 devman_exchange_end(exch); 199 118 200 async_wait_for(req, &retval); 119 120 async_serialize_end();121 122 201 return retval; 123 }124 125 static int devman_send_match_id(int phone, match_id_t *match_id)126 {127 ipc_call_t answer;128 129 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,130 &answer);131 int retval = async_data_write_start(phone, match_id->id,132 str_size(match_id->id));133 134 async_wait_for(req, NULL);135 return retval;136 }137 138 139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids)140 {141 link_t *link = match_ids->ids.next;142 match_id_t *match_id = NULL;143 int ret = EOK;144 145 while (link != &match_ids->ids) {146 match_id = list_get_instance(link, match_id_t, link);147 ret = devman_send_match_id(phone, match_id);148 if (ret != EOK) {149 return ret;150 }151 152 link = link->next;153 }154 155 return ret;156 202 } 157 203 … … 161 207 * this driver task. 162 208 * 163 * @param name Name of the new function 164 * @param ftype Function type, fun_inner or fun_exposed 165 * @param match_ids Match IDs (should be empty for fun_exposed) 166 * @param devh Devman handle of the device 167 * @param funh Place to store handle of the new function 168 * 169 * @return EOK on success or negative error code. 209 * @param name Name of the new function 210 * @param ftype Function type, fun_inner or fun_exposed 211 * @param match_ids Match IDs (should be empty for fun_exposed) 212 * @param devh Devman handle of the device 213 * @param funh Place to store handle of the new function 214 * 215 * @return EOK on success or negative error code. 216 * 170 217 */ 171 218 int devman_add_function(const char *name, fun_type_t ftype, 172 219 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh) 173 220 { 174 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);175 int fun_handle;176 177 if (phone < 0)178 return phone;179 180 async_serialize_start();181 182 221 int match_count = list_count(&match_ids->ids); 183 ipc_call_t answer; 184 185 aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 222 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 223 224 ipc_call_t answer; 225 aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 186 226 devh, match_count, &answer); 187 188 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 189 if (retval != EOK) { 190 async_wait_for(req, NULL); 191 async_serialize_end(); 192 return retval; 193 } 194 195 int match_ids_rc = devman_send_match_ids(phone, match_ids); 227 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 228 if (retval != EOK) { 229 devman_exchange_end(exch); 230 async_wait_for(req, NULL); 231 return retval; 232 } 233 234 match_id_t *match_id = NULL; 235 236 list_foreach(match_ids->ids, link) { 237 match_id = list_get_instance(link, match_id_t, link); 238 239 ipc_call_t answer2; 240 aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID, 241 match_id->score, &answer2); 242 retval = async_data_write_start(exch, match_id->id, 243 str_size(match_id->id)); 244 if (retval != EOK) { 245 devman_exchange_end(exch); 246 async_wait_for(req2, NULL); 247 async_wait_for(req, NULL); 248 return retval; 249 } 250 251 async_wait_for(req2, &retval); 252 if (retval != EOK) { 253 devman_exchange_end(exch); 254 async_wait_for(req, NULL); 255 return retval; 256 } 257 } 258 259 devman_exchange_end(exch); 196 260 197 261 async_wait_for(req, &retval); 198 199 async_serialize_end(); 200 201 /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */ 202 if ((match_ids_rc != EOK) && (retval == EOK)) { 203 retval = match_ids_rc; 204 } 205 206 if (retval == EOK) 207 fun_handle = (int) IPC_GET_ARG1(answer); 208 else 209 fun_handle = -1; 210 211 *funh = fun_handle; 212 262 if (retval == EOK) { 263 if (funh != NULL) 264 *funh = (int) IPC_GET_ARG1(answer); 265 } else { 266 if (funh != NULL) 267 *funh = -1; 268 } 269 213 270 return retval; 214 271 } … … 217 274 const char *class_name) 218 275 { 219 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 220 221 if (phone < 0) 222 return phone; 223 224 async_serialize_start(); 225 ipc_call_t answer; 226 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, 276 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 277 278 ipc_call_t answer; 279 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS, 227 280 devman_handle, &answer); 228 229 sysarg_t retval = async_data_write_start(phone, class_name, 281 sysarg_t retval = async_data_write_start(exch, class_name, 230 282 str_size(class_name)); 231 if (retval != EOK) { 232 async_wait_for(req, NULL); 233 async_serialize_end(); 283 284 devman_exchange_end(exch); 285 286 if (retval != EOK) { 287 async_wait_for(req, NULL); 234 288 return retval; 235 289 } 236 290 237 291 async_wait_for(req, &retval); 238 async_serialize_end();239 240 292 return retval; 241 293 } 242 294 243 void devman_hangup_phone(devman_interface_t iface) 244 { 245 switch (iface) { 246 case DEVMAN_DRIVER: 247 if (devman_phone_driver >= 0) { 248 async_hangup(devman_phone_driver); 249 devman_phone_driver = -1; 250 } 251 break; 252 case DEVMAN_CLIENT: 253 if (devman_phone_client >= 0) { 254 async_hangup(devman_phone_client); 255 devman_phone_client = -1; 256 } 257 break; 258 default: 259 break; 260 } 261 } 262 263 int devman_device_connect(devman_handle_t handle, unsigned int flags) 264 { 265 int phone; 266 267 if (flags & IPC_FLAG_BLOCKING) { 268 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 269 DEVMAN_CONNECT_TO_DEVICE, handle); 270 } else { 271 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 272 DEVMAN_CONNECT_TO_DEVICE, handle); 273 } 274 275 return phone; 276 } 277 278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags) 279 { 280 int phone; 281 282 if (flags & IPC_FLAG_BLOCKING) { 283 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 284 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 285 } else { 286 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 287 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 288 } 289 290 return phone; 295 async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle, 296 unsigned int flags) 297 { 298 async_sess_t *sess; 299 300 if (flags & IPC_FLAG_BLOCKING) 301 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 302 DEVMAN_CONNECT_TO_DEVICE, handle); 303 else 304 sess = service_connect(mgmt, SERVICE_DEVMAN, 305 DEVMAN_CONNECT_TO_DEVICE, handle); 306 307 return sess; 308 } 309 310 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 311 devman_handle_t handle, unsigned int flags) 312 { 313 async_sess_t *sess; 314 315 if (flags & IPC_FLAG_BLOCKING) 316 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 317 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 318 else 319 sess = service_connect(mgmt, SERVICE_DEVMAN, 320 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 321 322 return sess; 291 323 } 292 324 … … 294 326 unsigned int flags) 295 327 { 296 int phone = devman_get_phone(DEVMAN_CLIENT, flags); 297 298 if (phone < 0) 299 return phone; 300 301 async_serialize_start(); 302 303 ipc_call_t answer; 304 aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 328 async_exch_t *exch; 329 330 if (flags & IPC_FLAG_BLOCKING) 331 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 332 else { 333 exch = devman_exchange_begin(DEVMAN_CLIENT); 334 if (exch == NULL) 335 return errno; 336 } 337 338 ipc_call_t answer; 339 aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 305 340 &answer); 306 307 sysarg_t retval = async_data_write_start(phone, pathname, 341 sysarg_t retval = async_data_write_start(exch, pathname, 308 342 str_size(pathname)); 309 if (retval != EOK) { 310 async_wait_for(req, NULL); 311 async_serialize_end(); 343 344 devman_exchange_end(exch); 345 346 if (retval != EOK) { 347 async_wait_for(req, NULL); 312 348 return retval; 313 349 } 314 350 315 351 async_wait_for(req, &retval); 316 317 async_serialize_end();318 352 319 353 if (retval != EOK) { 320 354 if (handle != NULL) 321 355 *handle = (devman_handle_t) -1; 356 322 357 return retval; 323 358 } … … 332 367 const char *devname, devman_handle_t *handle, unsigned int flags) 333 368 { 334 int phone = devman_get_phone(DEVMAN_CLIENT, flags); 335 336 if (phone < 0) 337 return phone; 338 339 async_serialize_start(); 340 341 ipc_call_t answer; 342 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 369 async_exch_t *exch; 370 371 if (flags & IPC_FLAG_BLOCKING) 372 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 373 else { 374 exch = devman_exchange_begin(DEVMAN_CLIENT); 375 if (exch == NULL) 376 return errno; 377 } 378 379 ipc_call_t answer; 380 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 343 381 flags, &answer); 344 345 sysarg_t retval = async_data_write_start(phone, classname, 382 sysarg_t retval = async_data_write_start(exch, classname, 346 383 str_size(classname)); 347 if (retval != EOK) { 348 async_wait_for(req, NULL); 349 async_serialize_end(); 350 return retval; 351 } 352 retval = async_data_write_start(phone, devname, 384 385 if (retval != EOK) { 386 devman_exchange_end(exch); 387 async_wait_for(req, NULL); 388 return retval; 389 } 390 391 retval = async_data_write_start(exch, devname, 353 392 str_size(devname)); 354 if (retval != EOK) { 355 async_wait_for(req, NULL); 356 async_serialize_end(); 357 return retval; 358 } 359 393 394 devman_exchange_end(exch); 395 396 if (retval != EOK) { 397 async_wait_for(req, NULL); 398 return retval; 399 } 400 360 401 async_wait_for(req, &retval); 361 362 async_serialize_end(); 363 402 364 403 if (retval != EOK) { 365 404 if (handle != NULL) 366 405 *handle = (devman_handle_t) -1; 367 return retval; 368 } 369 406 407 return retval; 408 } 409 370 410 if (handle != NULL) 371 411 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 372 412 373 413 return retval; 374 414 } 375 415 416 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size) 417 { 418 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 419 if (exch == NULL) 420 return errno; 421 422 ipc_call_t answer; 423 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH, 424 handle, &answer); 425 426 ipc_call_t data_request_call; 427 aid_t data_request = async_data_read(exch, path, path_size, 428 &data_request_call); 429 430 devman_exchange_end(exch); 431 432 if (data_request == 0) { 433 async_wait_for(req, NULL); 434 return ENOMEM; 435 } 436 437 sysarg_t data_request_rc; 438 async_wait_for(data_request, &data_request_rc); 439 440 sysarg_t opening_request_rc; 441 async_wait_for(req, &opening_request_rc); 442 443 if (data_request_rc != EOK) { 444 /* Prefer the return code of the opening request. */ 445 if (opening_request_rc != EOK) 446 return (int) opening_request_rc; 447 else 448 return (int) data_request_rc; 449 } 450 451 if (opening_request_rc != EOK) 452 return (int) opening_request_rc; 453 454 /* To be on the safe-side. */ 455 path[path_size - 1] = 0; 456 size_t transferred_size = IPC_GET_ARG2(data_request_call); 457 if (transferred_size >= path_size) 458 return ELIMIT; 459 460 /* Terminate the string (trailing 0 not send over IPC). */ 461 path[transferred_size] = 0; 462 return EOK; 463 } 376 464 377 465 /** @} -
uspace/lib/c/generic/devmap.c
r52a79081 ra33f0a6 30 30 #include <str.h> 31 31 #include <ipc/services.h> 32 #include < ipc/ns.h>32 #include <ns.h> 33 33 #include <ipc/devmap.h> 34 34 #include <devmap.h> 35 #include <fibril_synch.h> 35 36 #include <async.h> 36 37 #include <errno.h> … … 38 39 #include <bool.h> 39 40 40 static int devmap_phone_driver = -1; 41 static int devmap_phone_client = -1; 42 43 /** Get phone to device mapper task. */ 44 int devmap_get_phone(devmap_interface_t iface, unsigned int flags) 41 static FIBRIL_MUTEX_INITIALIZE(devmap_driver_block_mutex); 42 static FIBRIL_MUTEX_INITIALIZE(devmap_client_block_mutex); 43 44 static FIBRIL_MUTEX_INITIALIZE(devmap_driver_mutex); 45 static FIBRIL_MUTEX_INITIALIZE(devmap_client_mutex); 46 47 static async_sess_t *devmap_driver_block_sess = NULL; 48 static async_sess_t *devmap_client_block_sess = NULL; 49 50 static async_sess_t *devmap_driver_sess = NULL; 51 static async_sess_t *devmap_client_sess = NULL; 52 53 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 54 async_sess_t **dst) 55 { 56 fibril_mutex_lock(mtx); 57 58 if ((*dst == NULL) && (src != NULL)) 59 *dst = src; 60 61 fibril_mutex_unlock(mtx); 62 } 63 64 /** Start an async exchange on the devmap session (blocking). 65 * 66 * @param iface Device mapper interface to choose 67 * 68 * @return New exchange. 69 * 70 */ 71 async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t iface) 45 72 { 46 73 switch (iface) { 47 74 case DEVMAP_DRIVER: 48 if (devmap_phone_driver >= 0) 49 return devmap_phone_driver; 50 51 if (flags & IPC_FLAG_BLOCKING) 52 devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP, 53 DEVMAP_DRIVER, 0); 54 else 55 devmap_phone_driver = service_connect(SERVICE_DEVMAP, 56 DEVMAP_DRIVER, 0); 57 58 return devmap_phone_driver; 75 fibril_mutex_lock(&devmap_driver_block_mutex); 76 77 while (devmap_driver_block_sess == NULL) { 78 clone_session(&devmap_driver_mutex, devmap_driver_sess, 79 &devmap_driver_block_sess); 80 81 if (devmap_driver_block_sess == NULL) 82 devmap_driver_block_sess = 83 service_connect_blocking(EXCHANGE_SERIALIZE, 84 SERVICE_DEVMAP, DEVMAP_DRIVER, 0); 85 } 86 87 fibril_mutex_unlock(&devmap_driver_block_mutex); 88 89 clone_session(&devmap_driver_mutex, devmap_driver_block_sess, 90 &devmap_driver_sess); 91 92 return async_exchange_begin(devmap_driver_block_sess); 59 93 case DEVMAP_CLIENT: 60 if (devmap_phone_client >= 0) 61 return devmap_phone_client; 62 63 if (flags & IPC_FLAG_BLOCKING) 64 devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP, 65 DEVMAP_CLIENT, 0); 66 else 67 devmap_phone_client = service_connect(SERVICE_DEVMAP, 68 DEVMAP_CLIENT, 0); 69 70 return devmap_phone_client; 94 fibril_mutex_lock(&devmap_client_block_mutex); 95 96 while (devmap_client_block_sess == NULL) { 97 clone_session(&devmap_client_mutex, devmap_client_sess, 98 &devmap_client_block_sess); 99 100 if (devmap_client_block_sess == NULL) 101 devmap_client_block_sess = 102 service_connect_blocking(EXCHANGE_SERIALIZE, 103 SERVICE_DEVMAP, DEVMAP_CLIENT, 0); 104 } 105 106 fibril_mutex_unlock(&devmap_client_block_mutex); 107 108 clone_session(&devmap_client_mutex, devmap_client_block_sess, 109 &devmap_client_sess); 110 111 return async_exchange_begin(devmap_client_block_sess); 71 112 default: 72 return -1; 73 } 74 } 75 76 void devmap_hangup_phone(devmap_interface_t iface) 113 return NULL; 114 } 115 } 116 117 /** Start an async exchange on the devmap session. 118 * 119 * @param iface Device mapper interface to choose 120 * 121 * @return New exchange. 122 * 123 */ 124 async_exch_t *devmap_exchange_begin(devmap_interface_t iface) 77 125 { 78 126 switch (iface) { 79 127 case DEVMAP_DRIVER: 80 if (devmap_phone_driver >= 0) { 81 async_hangup(devmap_phone_driver); 82 devmap_phone_driver = -1; 83 } 84 break; 128 fibril_mutex_lock(&devmap_driver_mutex); 129 130 if (devmap_driver_sess == NULL) 131 devmap_driver_sess = 132 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP, 133 DEVMAP_DRIVER, 0); 134 135 fibril_mutex_unlock(&devmap_driver_mutex); 136 137 if (devmap_driver_sess == NULL) 138 return NULL; 139 140 return async_exchange_begin(devmap_driver_sess); 85 141 case DEVMAP_CLIENT: 86 if (devmap_phone_client >= 0) { 87 async_hangup(devmap_phone_client); 88 devmap_phone_client = -1; 89 } 90 break; 142 fibril_mutex_lock(&devmap_client_mutex); 143 144 if (devmap_client_sess == NULL) 145 devmap_client_sess = 146 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP, 147 DEVMAP_CLIENT, 0); 148 149 fibril_mutex_unlock(&devmap_client_mutex); 150 151 if (devmap_client_sess == NULL) 152 return NULL; 153 154 return async_exchange_begin(devmap_client_sess); 91 155 default: 92 break; 93 } 156 return NULL; 157 } 158 } 159 160 /** Finish an async exchange on the devmap session. 161 * 162 * @param exch Exchange to be finished. 163 * 164 */ 165 void devmap_exchange_end(async_exch_t *exch) 166 { 167 async_exchange_end(exch); 94 168 } 95 169 … … 97 171 int devmap_driver_register(const char *name, async_client_conn_t conn) 98 172 { 99 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 100 101 if (phone < 0) 102 return phone; 103 104 async_serialize_start(); 173 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 105 174 106 175 ipc_call_t answer; 107 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 108 109 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 176 aid_t req = async_send_2(exch, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 177 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 178 179 devmap_exchange_end(exch); 180 110 181 if (retval != EOK) { 111 182 async_wait_for(req, NULL); 112 async_serialize_end(); 113 return -1; 183 return retval; 114 184 } 115 185 116 186 async_set_client_connection(conn); 117 187 118 async_connect_to_me(phone, 0, 0, 0, NULL); 188 exch = devmap_exchange_begin(DEVMAP_DRIVER); 189 async_connect_to_me(exch, 0, 0, 0, NULL, NULL); 190 devmap_exchange_end(exch); 191 119 192 async_wait_for(req, &retval); 120 121 async_serialize_end();122 123 193 return retval; 124 194 } … … 129 199 * If not 0, the first argument is the interface and the second argument 130 200 * is the devmap handle of the device. 201 * 131 202 * When the interface is zero (default), the first argument is directly 132 203 * the handle (to ensure backward compatibility). 133 204 * 134 * @param fqdnFully qualified device name.135 * @param[out] handle Handle to the created instance of device.136 * @param interface Interface when forwarding.205 * @param fqdn Fully qualified device name. 206 * @param[out] handle Handle to the created instance of device. 207 * @param interface Interface when forwarding. 137 208 * 138 209 */ … … 140 211 devmap_handle_t *handle, sysarg_t interface) 141 212 { 142 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 143 144 if (phone < 0) 145 return phone; 146 147 async_serialize_start(); 213 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 148 214 149 215 ipc_call_t answer; 150 aid_t req = async_send_2( phone, DEVMAP_DEVICE_REGISTER, interface, 0,216 aid_t req = async_send_2(exch, DEVMAP_DEVICE_REGISTER, interface, 0, 151 217 &answer); 152 153 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 218 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 219 220 devmap_exchange_end(exch); 221 154 222 if (retval != EOK) { 155 223 async_wait_for(req, NULL); 156 async_serialize_end();157 224 return retval; 158 225 } 159 226 160 227 async_wait_for(req, &retval); 161 162 async_serialize_end();163 228 164 229 if (retval != EOK) { 165 230 if (handle != NULL) 166 231 *handle = -1; 232 167 233 return retval; 168 234 } … … 176 242 /** Register new device. 177 243 * 178 * @param fqdn 179 * @param handle 244 * @param fqdn Fully qualified device name. 245 * @param handle Output: Handle to the created instance of device. 180 246 * 181 247 */ … … 185 251 } 186 252 187 188 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags) 189 { 190 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 191 192 if (phone < 0) 193 return phone; 194 195 async_serialize_start(); 253 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, 254 unsigned int flags) 255 { 256 async_exch_t *exch; 257 258 if (flags & IPC_FLAG_BLOCKING) 259 exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 260 else { 261 exch = devmap_exchange_begin(DEVMAP_CLIENT); 262 if (exch == NULL) 263 return errno; 264 } 196 265 197 266 ipc_call_t answer; 198 aid_t req = async_send_2( phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,267 aid_t req = async_send_2(exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0, 199 268 &answer); 200 201 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 269 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 270 271 devmap_exchange_end(exch); 272 202 273 if (retval != EOK) { 203 274 async_wait_for(req, NULL); 204 async_serialize_end();205 275 return retval; 206 276 } 207 277 208 278 async_wait_for(req, &retval); 209 210 async_serialize_end();211 279 212 280 if (retval != EOK) { 213 281 if (handle != NULL) 214 282 *handle = (devmap_handle_t) -1; 283 215 284 return retval; 216 285 } … … 222 291 } 223 292 224 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags) 225 { 226 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 227 228 if (phone < 0) 229 return phone; 230 231 async_serialize_start(); 293 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, 294 unsigned int flags) 295 { 296 async_exch_t *exch; 297 298 if (flags & IPC_FLAG_BLOCKING) 299 exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 300 else { 301 exch = devmap_exchange_begin(DEVMAP_CLIENT); 302 if (exch == NULL) 303 return errno; 304 } 232 305 233 306 ipc_call_t answer; 234 aid_t req = async_send_2( phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,307 aid_t req = async_send_2(exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0, 235 308 &answer); 236 237 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 309 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 310 311 devmap_exchange_end(exch); 312 238 313 if (retval != EOK) { 239 314 async_wait_for(req, NULL); 240 async_serialize_end();241 315 return retval; 242 316 } 243 317 244 318 async_wait_for(req, &retval); 245 246 async_serialize_end();247 319 248 320 if (retval != EOK) { 249 321 if (handle != NULL) 250 322 *handle = (devmap_handle_t) -1; 323 251 324 return retval; 252 325 } … … 260 333 devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle) 261 334 { 262 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 263 264 if (phone < 0) 265 return phone; 335 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 266 336 267 337 sysarg_t type; 268 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type); 338 int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type); 339 340 devmap_exchange_end(exch); 341 269 342 if (retval != EOK) 270 343 return DEV_HANDLE_NONE; … … 273 346 } 274 347 275 int devmap_device_connect(devmap_handle_t handle, unsigned int flags) 276 { 277 int phone; 278 279 if (flags & IPC_FLAG_BLOCKING) { 280 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, 348 async_sess_t *devmap_device_connect(exch_mgmt_t mgmt, devmap_handle_t handle, 349 unsigned int flags) 350 { 351 async_sess_t *sess; 352 353 if (flags & IPC_FLAG_BLOCKING) 354 sess = service_connect_blocking(mgmt, SERVICE_DEVMAP, 281 355 DEVMAP_CONNECT_TO_DEVICE, handle); 282 } else {283 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,356 else 357 sess = service_connect(mgmt, SERVICE_DEVMAP, 284 358 DEVMAP_CONNECT_TO_DEVICE, handle); 285 } 286 287 return phone; 359 360 return sess; 288 361 } 289 362 290 363 int devmap_null_create(void) 291 364 { 292 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 293 294 if (phone < 0) 295 return -1; 365 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 296 366 297 367 sysarg_t null_id; 298 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id); 368 int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id); 369 370 devmap_exchange_end(exch); 371 299 372 if (retval != EOK) 300 373 return -1; … … 305 378 void devmap_null_destroy(int null_id) 306 379 { 307 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 308 309 if (phone < 0) 310 return; 311 312 async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id); 313 } 314 315 static size_t devmap_count_namespaces_internal(int phone) 380 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 381 async_req_1_0(exch, DEVMAP_NULL_DESTROY, (sysarg_t) null_id); 382 devmap_exchange_end(exch); 383 } 384 385 static size_t devmap_count_namespaces_internal(async_exch_t *exch) 316 386 { 317 387 sysarg_t count; 318 int retval = async_req_0_1( phone, DEVMAP_GET_NAMESPACE_COUNT, &count);388 int retval = async_req_0_1(exch, DEVMAP_GET_NAMESPACE_COUNT, &count); 319 389 if (retval != EOK) 320 390 return 0; … … 323 393 } 324 394 325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle) 395 static size_t devmap_count_devices_internal(async_exch_t *exch, 396 devmap_handle_t ns_handle) 326 397 { 327 398 sysarg_t count; 328 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count); 399 int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle, 400 &count); 329 401 if (retval != EOK) 330 402 return 0; … … 335 407 size_t devmap_count_namespaces(void) 336 408 { 337 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 338 339 if (phone < 0) 340 return 0; 341 342 return devmap_count_namespaces_internal(phone); 409 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 410 size_t size = devmap_count_namespaces_internal(exch); 411 devmap_exchange_end(exch); 412 413 return size; 343 414 } 344 415 345 416 size_t devmap_count_devices(devmap_handle_t ns_handle) 346 417 { 347 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 348 349 if (phone < 0) 350 return 0; 351 352 return devmap_count_devices_internal(phone, ns_handle); 418 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 419 size_t size = devmap_count_devices_internal(exch, ns_handle); 420 devmap_exchange_end(exch); 421 422 return size; 353 423 } 354 424 355 425 size_t devmap_get_namespaces(dev_desc_t **data) 356 426 { 357 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);358 359 if (phone < 0)360 return 0;361 362 427 /* Loop until namespaces read succesful */ 363 428 while (true) { 364 size_t count = devmap_count_namespaces_internal(phone); 429 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 430 size_t count = devmap_count_namespaces_internal(exch); 431 devmap_exchange_end(exch); 432 365 433 if (count == 0) 366 434 return 0; … … 370 438 return 0; 371 439 372 async_serialize_start();440 exch = devmap_exchange_begin(DEVMAP_CLIENT); 373 441 374 442 ipc_call_t answer; 375 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer); 376 377 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 443 aid_t req = async_send_0(exch, DEVMAP_GET_NAMESPACES, &answer); 444 int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t)); 445 446 devmap_exchange_end(exch); 447 378 448 if (rc == EOVERFLOW) { 379 449 /* … … 381 451 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT 382 452 */ 383 async_serialize_end();384 453 free(devs); 385 454 continue; … … 388 457 if (rc != EOK) { 389 458 async_wait_for(req, NULL); 390 async_serialize_end();391 459 free(devs); 392 460 return 0; … … 395 463 sysarg_t retval; 396 464 async_wait_for(req, &retval); 397 async_serialize_end();398 465 399 466 if (retval != EOK) … … 407 474 size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data) 408 475 { 409 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 410 411 if (phone < 0) 412 return 0; 413 414 /* Loop until namespaces read succesful */ 476 /* Loop until devices read succesful */ 415 477 while (true) { 416 size_t count = devmap_count_devices_internal(phone, ns_handle); 478 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 479 size_t count = devmap_count_devices_internal(exch, ns_handle); 480 devmap_exchange_end(exch); 481 417 482 if (count == 0) 418 483 return 0; … … 422 487 return 0; 423 488 424 async_serialize_start();489 exch = devmap_exchange_begin(DEVMAP_CLIENT); 425 490 426 491 ipc_call_t answer; 427 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer); 428 429 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 492 aid_t req = async_send_1(exch, DEVMAP_GET_DEVICES, ns_handle, &answer); 493 int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t)); 494 495 devmap_exchange_end(exch); 496 430 497 if (rc == EOVERFLOW) { 431 498 /* … … 433 500 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT 434 501 */ 435 async_serialize_end();436 502 free(devs); 437 503 continue; … … 440 506 if (rc != EOK) { 441 507 async_wait_for(req, NULL); 442 async_serialize_end();443 508 free(devs); 444 509 return 0; … … 447 512 sysarg_t retval; 448 513 async_wait_for(req, &retval); 449 async_serialize_end();450 514 451 515 if (retval != EOK) -
uspace/lib/c/generic/elf/elf_load.c
r52a79081 ra33f0a6 2 2 * Copyright (c) 2006 Sergey Bondari 3 3 * Copyright (c) 2006 Jakub Jermar 4 * Copyright (c) 20 08Jiri Svoboda4 * Copyright (c) 2011 Jiri Svoboda 5 5 * All rights reserved. 6 6 * … … 29 29 */ 30 30 31 /** @addtogroup generic 31 /** @addtogroup generic 32 32 * @{ 33 33 */ … … 49 49 #include <assert.h> 50 50 #include <as.h> 51 #include <elf/elf.h> 51 52 #include <unistd.h> 52 53 #include <fcntl.h> 53 54 #include <smc.h> 54 55 #include <loader/pcb.h> 55 56 #include "elf.h" 57 #include "elf_load.h" 58 #include "arch.h" 56 #include <entry_point.h> 57 58 #include <elf/elf_load.h> 59 59 60 60 #define DPRINTF(...) … … 74 74 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 75 75 76 /** Read until the buffer is read in its entirety. */77 static int my_read(int fd, void *buf, size_t len)78 {79 int cnt = 0;80 do {81 buf += cnt;82 len -= cnt;83 cnt = read(fd, buf, len);84 } while ((cnt > 0) && ((len - cnt) > 0));85 86 return cnt;87 }88 89 76 /** Load ELF binary from a file. 90 77 * … … 103 90 * 104 91 */ 105 int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info) 92 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags, 93 elf_info_t *info) 106 94 { 107 95 elf_ld_t elf; … … 118 106 elf.fd = fd; 119 107 elf.info = info; 108 elf.flags = flags; 120 109 121 110 rc = elf_load(&elf, so_bias); … … 124 113 125 114 return rc; 126 }127 128 /** Run an ELF executable.129 *130 * Transfers control to the entry point of an ELF executable loaded131 * earlier with elf_load_file(). This function does not return.132 *133 * @param info Info structure filled earlier by elf_load_file()134 *135 */136 void elf_run(elf_info_t *info, pcb_t *pcb)137 {138 program_run(info->entry, pcb);139 140 /* not reached */141 115 } 142 116 … … 153 127 pcb->entry = info->entry; 154 128 pcb->dynamic = info->dynamic; 129 pcb->rtld_runtime = NULL; 155 130 } 156 131 … … 172 147 int i, rc; 173 148 174 rc = my_read(elf->fd, header, sizeof(elf_header_t));175 if (rc < 0) {149 rc = read_all(elf->fd, header, sizeof(elf_header_t)); 150 if (rc != sizeof(elf_header_t)) { 176 151 DPRINTF("Read error.\n"); 177 152 return EE_INVALID; … … 234 209 + i * sizeof(elf_segment_header_t), SEEK_SET); 235 210 236 rc = my_read(elf->fd, &segment_hdr,211 rc = read_all(elf->fd, &segment_hdr, 237 212 sizeof(elf_segment_header_t)); 238 if (rc < 0) {213 if (rc != sizeof(elf_segment_header_t)) { 239 214 DPRINTF("Read error.\n"); 240 215 return EE_INVALID; … … 256 231 + i * sizeof(elf_section_header_t), SEEK_SET); 257 232 258 rc = my_read(elf->fd, §ion_hdr,233 rc = read_all(elf->fd, §ion_hdr, 259 234 sizeof(elf_section_header_t)); 260 if (rc < 0) {235 if (rc != sizeof(elf_section_header_t)) { 261 236 DPRINTF("Read error.\n"); 262 237 return EE_INVALID; … … 306 281 break; 307 282 case PT_INTERP: 308 /* Assume silently interp == "/ rtld.so" */309 elf->info->interp = "/ rtld.so";283 /* Assume silently interp == "/app/dload" */ 284 elf->info->interp = "/app/dload"; 310 285 break; 311 286 case PT_DYNAMIC: 287 /* Record pointer to dynamic section into info structure */ 288 elf->info->dynamic = 289 (void *)((uint8_t *)entry->p_vaddr + elf->bias); 290 DPRINTF("dynamic section found at 0x%x\n", 291 (uintptr_t)elf->info->dynamic); 292 break; 293 case 0x70000000: 294 /* FIXME: MIPS reginfo */ 295 break; 312 296 case PT_SHLIB: 313 case PT_LOPROC:314 case PT_HIPROC:297 // case PT_LOPROC: 298 // case PT_HIPROC: 315 299 default: 316 300 DPRINTF("Segment p_type %d unknown.\n", entry->p_type); … … 337 321 uintptr_t seg_addr; 338 322 size_t mem_sz; 339 int rc;323 ssize_t rc; 340 324 341 325 bias = elf->bias; … … 383 367 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); 384 368 if (a == (void *)(-1)) { 385 DPRINTF("Memory mapping failed.\n"); 369 DPRINTF("memory mapping failed (0x%x, %d)\n", 370 base+bias, mem_sz); 386 371 return EE_MEMORY; 387 372 } … … 414 399 if (now > left) now = left; 415 400 416 rc = my_read(elf->fd, dp, now);417 418 if (rc < 0) {401 rc = read_all(elf->fd, dp, now); 402 403 if (rc != (ssize_t) now) { 419 404 DPRINTF("Read error.\n"); 420 405 return EE_INVALID; … … 425 410 } 426 411 412 /* 413 * The caller wants to modify the segments first. He will then 414 * need to set the right access mode and ensure SMC coherence. 415 */ 416 if ((elf->flags & ELDF_RW) != 0) return EE_OK; 417 418 // printf("set area flags to %d\n", flags); 427 419 rc = as_area_change_flags(seg_ptr, flags); 428 420 if (rc != 0) { -
uspace/lib/c/generic/event.c
r52a79081 ra33f0a6 41 41 #include <kernel/ipc/event_types.h> 42 42 43 /** Subscribe forevent notifications.43 /** Subscribe event notifications. 44 44 * 45 * @param evno Event number.46 * @param method Use thismethod for notifying me.45 * @param evno Event type to subscribe. 46 * @param imethod Use this interface and method for notifying me. 47 47 * 48 48 * @return Value returned by the kernel. 49 * 49 50 */ 50 int event_subscribe(event_type_t e , sysarg_tmethod)51 int event_subscribe(event_type_t evno, sysarg_t imethod) 51 52 { 52 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method); 53 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, 54 (sysarg_t) imethod); 55 } 56 57 /** Unmask event notifications. 58 * 59 * @param evno Event type to unmask. 60 * 61 * @return Value returned by the kernel. 62 * 63 */ 64 int event_unmask(event_type_t evno) 65 { 66 return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno); 53 67 } 54 68 -
uspace/lib/c/generic/fibril.c
r52a79081 ra33f0a6 222 222 fibril_t *dstf; 223 223 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 224 dstf = list_get_instance(manager_list.next, fibril_t, link); 224 dstf = list_get_instance(list_first(&manager_list), fibril_t, 225 link); 225 226 if (serialization_count && stype == FIBRIL_TO_MANAGER) { 226 227 serialized_threads++; … … 233 234 } else { 234 235 if (!list_empty(&serialized_list)) { 235 dstf = list_get_instance( serialized_list.next, fibril_t,236 link);236 dstf = list_get_instance(list_first(&serialized_list), 237 fibril_t, link); 237 238 serialized_threads--; 238 239 } else { 239 dstf = list_get_instance( ready_list.next, fibril_t,240 link);240 dstf = list_get_instance(list_first(&ready_list), 241 fibril_t, link); 241 242 } 242 243 } … … 326 327 327 328 if (!list_empty(&manager_list)) 328 list_remove( manager_list.next);329 list_remove(list_first(&manager_list)); 329 330 330 331 futex_up(&fibril_futex); -
uspace/lib/c/generic/fibril_synch.c
r52a79081 ra33f0a6 148 148 fibril_t *f; 149 149 150 assert(!list_empty(&fm->waiters));151 tmp = fm->waiters.next;150 tmp = list_first(&fm->waiters); 151 assert(tmp != NULL); 152 152 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 153 153 wdp->active = true; … … 279 279 280 280 while (!list_empty(&frw->waiters)) { 281 link_t *tmp = frw->waiters.next;281 link_t *tmp = list_first(&frw->waiters); 282 282 awaiter_t *wdp; 283 283 fibril_t *f; … … 422 422 futex_down(&async_futex); 423 423 while (!list_empty(&fcv->waiters)) { 424 tmp = fcv->waiters.next;424 tmp = list_first(&fcv->waiters); 425 425 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 426 426 list_remove(&wdp->wu_event.link); -
uspace/lib/c/generic/io/console.c
r52a79081 ra33f0a6 37 37 #include <libc.h> 38 38 #include <async.h> 39 #include <errno.h> 40 #include <stdio.h> 41 #include <malloc.h> 42 #include <vfs/vfs_sess.h> 39 43 #include <io/console.h> 40 44 #include <ipc/console.h> 41 45 42 void console_clear(int phone) 43 { 44 async_msg_0(phone, CONSOLE_CLEAR); 45 } 46 47 int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows) 48 { 49 return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows); 50 } 51 52 void console_set_style(int phone, uint8_t style) 53 { 54 async_msg_1(phone, CONSOLE_SET_STYLE, style); 55 } 56 57 void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color, 46 console_ctrl_t *console_init(FILE *ifile, FILE *ofile) 47 { 48 console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t)); 49 if (!ctrl) 50 return NULL; 51 52 ctrl->input_sess = fsession(EXCHANGE_SERIALIZE, ifile); 53 if (!ctrl->input_sess) { 54 free(ctrl); 55 return NULL; 56 } 57 58 ctrl->output_sess = fsession(EXCHANGE_SERIALIZE, ofile); 59 if (!ctrl->output_sess) { 60 free(ctrl); 61 return NULL; 62 } 63 64 ctrl->input = ifile; 65 ctrl->output = ofile; 66 ctrl->input_aid = 0; 67 68 return ctrl; 69 } 70 71 void console_done(console_ctrl_t *ctrl) 72 { 73 free(ctrl); 74 } 75 76 bool console_kcon(void) 77 { 78 return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 79 } 80 81 void console_flush(console_ctrl_t *ctrl) 82 { 83 fflush(ctrl->output); 84 } 85 86 void console_clear(console_ctrl_t *ctrl) 87 { 88 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 89 async_msg_0(exch, CONSOLE_CLEAR); 90 async_exchange_end(exch); 91 } 92 93 int console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows) 94 { 95 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 96 int rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows); 97 async_exchange_end(exch); 98 99 return rc; 100 } 101 102 void console_set_style(console_ctrl_t *ctrl, uint8_t style) 103 { 104 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 105 async_msg_1(exch, CONSOLE_SET_STYLE, style); 106 async_exchange_end(exch); 107 } 108 109 void console_set_color(console_ctrl_t *ctrl, uint8_t fg_color, uint8_t bg_color, 58 110 uint8_t flags) 59 111 { 60 async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); 61 } 62 63 void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color) 64 { 65 async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); 66 } 67 68 void console_cursor_visibility(int phone, bool show) 69 { 70 async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false)); 71 } 72 73 int console_get_color_cap(int phone, sysarg_t *ccap) 74 { 75 return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap); 76 } 77 78 void console_kcon_enable(int phone) 79 { 80 async_msg_0(phone, CONSOLE_KCON_ENABLE); 81 } 82 83 int console_get_pos(int phone, sysarg_t *col, sysarg_t *row) 84 { 85 return async_req_0_2(phone, CONSOLE_GET_POS, col, row); 86 } 87 88 void console_set_pos(int phone, sysarg_t col, sysarg_t row) 89 { 90 async_msg_2(phone, CONSOLE_GOTO, col, row); 91 } 92 93 bool console_get_event(int phone, console_event_t *event) 94 { 95 sysarg_t type; 96 sysarg_t key; 97 sysarg_t mods; 98 sysarg_t c; 99 100 int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c); 101 if (rc < 0) 112 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 113 async_msg_3(exch, CONSOLE_SET_COLOR, fg_color, bg_color, flags); 114 async_exchange_end(exch); 115 } 116 117 void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t fg_color, 118 uint32_t bg_color) 119 { 120 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 121 async_msg_2(exch, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); 122 async_exchange_end(exch); 123 } 124 125 void console_cursor_visibility(console_ctrl_t *ctrl, bool show) 126 { 127 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 128 async_msg_1(exch, CONSOLE_CURSOR_VISIBILITY, (show != false)); 129 async_exchange_end(exch); 130 } 131 132 int console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap) 133 { 134 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 135 int rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap); 136 async_exchange_end(exch); 137 138 return rc; 139 } 140 141 int console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row) 142 { 143 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 144 int rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row); 145 async_exchange_end(exch); 146 147 return rc; 148 } 149 150 void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row) 151 { 152 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 153 async_msg_2(exch, CONSOLE_GOTO, col, row); 154 async_exchange_end(exch); 155 } 156 157 bool console_get_kbd_event(console_ctrl_t *ctrl, kbd_event_t *event) 158 { 159 if (ctrl->input_aid == 0) { 160 sysarg_t type; 161 sysarg_t key; 162 sysarg_t mods; 163 sysarg_t c; 164 165 async_exch_t *exch = async_exchange_begin(ctrl->input_sess); 166 int rc = async_req_0_4(exch, CONSOLE_GET_EVENT, &type, &key, &mods, &c); 167 async_exchange_end(exch); 168 169 if (rc != EOK) { 170 errno = rc; 171 return false; 172 } 173 174 event->type = type; 175 event->key = key; 176 event->mods = mods; 177 event->c = c; 178 } else { 179 sysarg_t retval; 180 async_wait_for(ctrl->input_aid, &retval); 181 182 ctrl->input_aid = 0; 183 184 if (retval != EOK) { 185 errno = (int) retval; 186 return false; 187 } 188 189 event->type = IPC_GET_ARG1(ctrl->input_call); 190 event->key = IPC_GET_ARG2(ctrl->input_call); 191 event->mods = IPC_GET_ARG3(ctrl->input_call); 192 event->c = IPC_GET_ARG4(ctrl->input_call); 193 } 194 195 return true; 196 } 197 198 bool console_get_kbd_event_timeout(console_ctrl_t *ctrl, kbd_event_t *event, 199 suseconds_t *timeout) 200 { 201 struct timeval t0; 202 gettimeofday(&t0, NULL); 203 204 if (ctrl->input_aid == 0) { 205 async_exch_t *exch = async_exchange_begin(ctrl->input_sess); 206 ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT, 207 &ctrl->input_call); 208 async_exchange_end(exch); 209 } 210 211 sysarg_t retval; 212 int rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout); 213 if (rc != EOK) { 214 *timeout = 0; 215 errno = rc; 102 216 return false; 103 104 event->type = type; 105 event->key = key; 106 event->mods = mods; 107 event->c = c; 217 } 218 219 ctrl->input_aid = 0; 220 221 if (retval != EOK) { 222 errno = (int) retval; 223 return false; 224 } 225 226 event->type = IPC_GET_ARG1(ctrl->input_call); 227 event->key = IPC_GET_ARG2(ctrl->input_call); 228 event->mods = IPC_GET_ARG3(ctrl->input_call); 229 event->c = IPC_GET_ARG4(ctrl->input_call); 230 231 /* Update timeout */ 232 struct timeval t1; 233 gettimeofday(&t1, NULL); 234 *timeout -= tv_sub(&t1, &t0); 108 235 109 236 return true; -
uspace/lib/c/generic/io/io.c
r52a79081 ra33f0a6 44 44 #include <io/klog.h> 45 45 #include <vfs/vfs.h> 46 #include <vfs/vfs_sess.h> 46 47 #include <ipc/devmap.h> 47 48 #include <adt/list.h> 48 49 #include "../private/io.h" 50 #include "../private/stdio.h" 49 51 50 52 static void _ffillbuf(FILE *stream); … … 56 58 .eof = true, 57 59 .klog = false, 58 . phone = -1,60 .sess = NULL, 59 61 .btype = _IONBF, 60 62 .buf = NULL, … … 70 72 .eof = false, 71 73 .klog = true, 72 . phone = -1,74 .sess = NULL, 73 75 .btype = _IOLBF, 74 76 .buf = NULL, … … 84 86 .eof = false, 85 87 .klog = true, 86 . phone = -1,88 .sess = NULL, 87 89 .btype = _IONBF, 88 90 .buf = NULL, … … 125 127 void __stdio_done(void) 126 128 { 127 link_t *link = files.next; 128 129 while (link != &files) { 130 FILE *file = list_get_instance(link, FILE, link); 129 while (!list_empty(&files)) { 130 FILE *file = list_get_instance(list_first(&files), FILE, link); 131 131 fclose(file); 132 link = files.next;133 132 } 134 133 } … … 255 254 stream->eof = false; 256 255 stream->klog = false; 257 stream-> phone = -1;256 stream->sess = NULL; 258 257 stream->need_sync = false; 259 258 _setvbuf(stream); … … 277 276 stream->eof = false; 278 277 stream->klog = false; 279 stream-> phone = -1;278 stream->sess = NULL; 280 279 stream->need_sync = false; 281 280 _setvbuf(stream); … … 309 308 stream->eof = false; 310 309 stream->klog = false; 311 stream-> phone = -1;310 stream->sess = NULL; 312 311 stream->need_sync = false; 313 312 _setvbuf(stream); … … 324 323 fflush(stream); 325 324 326 if (stream-> phone >= 0)327 async_hangup(stream-> phone);325 if (stream->sess != NULL) 326 async_hangup(stream->sess); 328 327 329 328 if (stream->fd >= 0) … … 595 594 } 596 595 597 buf+= now;596 data += now; 598 597 stream->buf_head += now; 599 598 buf_free -= now; 600 599 bytes_left -= now; 601 600 total_written += now; 601 stream->buf_state = _bs_write; 602 602 603 603 if (buf_free == 0) { … … 607 607 } 608 608 } 609 610 if (total_written > 0)611 stream->buf_state = _bs_write;612 609 613 610 if (need_flush) … … 715 712 off64_t ftell(FILE *stream) 716 713 { 714 _fflushbuf(stream); 717 715 return lseek(stream->fd, 0, SEEK_CUR); 718 716 } … … 732 730 } 733 731 734 if ( stream->fd >= 0 && stream->need_sync) {732 if ((stream->fd >= 0) && (stream->need_sync)) { 735 733 /** 736 734 * Better than syncing always, but probably still not the … … 770 768 } 771 769 772 int fphone(FILE *stream)770 async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream) 773 771 { 774 772 if (stream->fd >= 0) { 775 if (stream-> phone < 0)776 stream-> phone = fd_phone(stream->fd);777 778 return stream-> phone;779 } 780 781 return -1;773 if (stream->sess == NULL) 774 stream->sess = fd_session(mgmt, stream->fd); 775 776 return stream->sess; 777 } 778 779 return NULL; 782 780 } 783 781 -
uspace/lib/c/generic/io/klog.c
r52a79081 ra33f0a6 38 38 #include <sys/types.h> 39 39 #include <unistd.h> 40 #include <errno.h> 40 41 #include <io/klog.h> 42 #include <io/printf_core.h> 41 43 42 44 size_t klog_write(const void *buf, size_t size) … … 55 57 } 56 58 59 /** Print formatted text to klog. 60 * 61 * @param fmt Format string 62 * 63 * \see For more details about format string see printf_core. 64 * 65 */ 66 int klog_printf(const char *fmt, ...) 67 { 68 va_list args; 69 va_start(args, fmt); 70 71 int ret = klog_vprintf(fmt, args); 72 73 va_end(args); 74 75 return ret; 76 } 77 78 static int klog_vprintf_str_write(const char *str, size_t size, void *data) 79 { 80 size_t wr = klog_write(str, size); 81 return str_nlength(str, wr); 82 } 83 84 static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data) 85 { 86 size_t offset = 0; 87 size_t chars = 0; 88 89 while (offset < size) { 90 char buf[STR_BOUNDS(1)]; 91 size_t sz = 0; 92 93 if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK) 94 klog_write(buf, sz); 95 96 chars++; 97 offset += sizeof(wchar_t); 98 } 99 100 return chars; 101 } 102 103 /** Print formatted text to klog. 104 * 105 * @param fmt Format string 106 * @param ap Format parameters 107 * 108 * \see For more details about format string see printf_core. 109 * 110 */ 111 int klog_vprintf(const char *fmt, va_list ap) 112 { 113 printf_spec_t ps = { 114 klog_vprintf_str_write, 115 klog_vprintf_wstr_write, 116 NULL 117 }; 118 119 return printf_core(fmt, &ps, ap); 120 } 121 57 122 /** @} 58 123 */ -
uspace/lib/c/generic/io/vprintf.c
r52a79081 ra33f0a6 96 96 /** Print formatted text to stdout. 97 97 * 98 * @param file Output stream 99 * @param fmt Format string 100 * @param ap Format parameters 98 * @param fmt Format string 99 * @param ap Format parameters 101 100 * 102 101 * \see For more details about format string see printf_core. -
uspace/lib/c/generic/ipc.c
r52a79081 ra33f0a6 458 458 while (!list_empty(&queued_calls)) { 459 459 async_call_t *call = 460 list_get_instance( queued_calls.next, async_call_t, list);460 list_get_instance(list_first(&queued_calls), async_call_t, list); 461 461 ipc_callid_t callid = 462 462 ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data); … … 511 511 512 512 link_t *item; 513 for (item = dispatched_calls. next; item != &dispatched_calls;513 for (item = dispatched_calls.head.next; item != &dispatched_calls.head; 514 514 item = item->next) { 515 515 async_call_t *call = … … 632 632 } 633 633 634 /** Request cloned connection. 635 * 636 * @param phoneid Phone handle used for contacting the other side. 637 * 638 * @return Cloned phone handle on success or a negative error code. 639 * 640 */ 641 int ipc_connect_me(int phoneid) 642 { 643 sysarg_t newphid; 644 int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL, 645 NULL, NULL, &newphid); 646 if (res) 647 return res; 648 649 return newphid; 650 } 651 634 652 /** Request new connection. 635 653 * -
uspace/lib/c/generic/libc.c
r52a79081 ra33f0a6 49 49 #include "private/libc.h" 50 50 #include "private/async.h" 51 #include "private/async_sess.h"52 51 #include "private/malloc.h" 53 52 #include "private/io.h" 53 54 #ifdef CONFIG_RTLD 55 #include <rtld/rtld.h> 56 #endif 54 57 55 58 static bool env_setup = false; … … 60 63 __malloc_init(); 61 64 __async_init(); 62 __async_sess_init();63 65 64 66 fibril_t *fibril = fibril_setup(); … … 77 79 char **argv; 78 80 81 #ifdef __IN_SHARED_LIBC__ 82 if (__pcb != NULL && __pcb->rtld_runtime != NULL) { 83 runtime_env = (runtime_env_t *) __pcb->rtld_runtime; 84 } 85 #endif 79 86 /* 80 87 * Get command line arguments and initialize -
uspace/lib/c/generic/loader.c
r52a79081 ra33f0a6 35 35 #include <ipc/loader.h> 36 36 #include <ipc/services.h> 37 #include < ipc/ns.h>37 #include <ns.h> 38 38 #include <libc.h> 39 39 #include <task.h> … … 44 44 #include <vfs/vfs.h> 45 45 #include <loader/loader.h> 46 #include "private/loader.h" 46 47 47 48 /** Connect to a new program loader. … … 63 64 loader_t *loader_connect(void) 64 65 { 65 int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);66 if (phone_id < 0)67 return NULL;68 69 66 loader_t *ldr = malloc(sizeof(loader_t)); 70 67 if (ldr == NULL) 71 68 return NULL; 72 69 73 ldr->phone_id = phone_id; 70 async_sess_t *sess = 71 service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOAD, 0, 0); 72 if (sess == NULL) { 73 free(ldr); 74 return NULL; 75 } 76 77 ldr->sess = sess; 74 78 return ldr; 75 79 } … … 88 92 { 89 93 /* Get task ID. */ 90 ipc_call_t answer; 91 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); 92 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 sysarg_t retval; 99 async_wait_for(req, &retval); 100 return (int) retval; 94 async_exch_t *exch = async_exchange_begin(ldr->sess); 95 96 ipc_call_t answer; 97 aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer); 98 sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t)); 99 100 async_exchange_end(exch); 101 102 if (rc != EOK) { 103 async_wait_for(req, NULL); 104 return (int) rc; 105 } 106 107 async_wait_for(req, &rc); 108 return (int) rc; 101 109 } 102 110 … … 112 120 int loader_set_cwd(loader_t *ldr) 113 121 { 114 char *cwd; 115 size_t len; 116 117 cwd = (char *) malloc(MAX_PATH_LEN + 1); 122 char *cwd = (char *) malloc(MAX_PATH_LEN + 1); 118 123 if (!cwd) 119 124 return ENOMEM; 125 120 126 if (!getcwd(cwd, MAX_PATH_LEN + 1)) 121 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 122 len = str_length(cwd); 123 124 ipc_call_t answer; 125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer); 126 int rc = async_data_write_start(ldr->phone_id, cwd, len); 127 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 128 129 size_t len = str_length(cwd); 130 131 async_exch_t *exch = async_exchange_begin(ldr->sess); 132 133 ipc_call_t answer; 134 aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer); 135 sysarg_t rc = async_data_write_start(exch, cwd, len); 136 137 async_exchange_end(exch); 127 138 free(cwd); 128 if (rc != EOK) {129 async_wait_for(req, NULL);130 return rc;131 }132 133 sysarg_t retval;134 async_wait_for(req, &r etval);135 return (int) r etval;139 140 if (rc != EOK) { 141 async_wait_for(req, NULL); 142 return (int) rc; 143 } 144 145 async_wait_for(req, &rc); 146 return (int) rc; 136 147 } 137 148 … … 153 164 char *pa = absolutize(path, &pa_len); 154 165 if (!pa) 155 return 0;166 return ENOMEM; 156 167 157 168 /* Send program pathname */ 158 ipc_call_t answer; 159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); 160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 161 if (rc != EOK) { 162 free(pa); 163 async_wait_for(req, NULL); 164 return rc; 165 } 166 169 async_exch_t *exch = async_exchange_begin(ldr->sess); 170 171 ipc_call_t answer; 172 aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer); 173 sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len); 174 175 async_exchange_end(exch); 167 176 free(pa); 168 177 169 sysarg_t retval; 170 async_wait_for(req, &retval); 171 return (int) retval; 178 if (rc != EOK) { 179 async_wait_for(req, NULL); 180 return (int) rc; 181 } 182 183 async_wait_for(req, &rc); 184 return (int) rc; 172 185 } 173 186 … … 212 225 213 226 /* Send serialized arguments to the loader */ 214 ipc_call_t answer; 215 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); 216 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); 217 if (rc != EOK) { 218 async_wait_for(req, NULL); 219 return rc; 220 } 221 222 async_wait_for(req, &rc); 223 if (rc != EOK) 224 return rc; 225 226 /* Free temporary buffer */ 227 async_exch_t *exch = async_exchange_begin(ldr->sess); 228 229 ipc_call_t answer; 230 aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer); 231 sysarg_t rc = async_data_write_start(exch, (void *) arg_buf, 232 buffer_size); 233 234 async_exchange_end(exch); 227 235 free(arg_buf); 228 236 229 return EOK; 237 if (rc != EOK) { 238 async_wait_for(req, NULL); 239 return (int) rc; 240 } 241 242 async_wait_for(req, &rc); 243 return (int) rc; 230 244 } 231 245 … … 266 280 267 281 /* Send serialized files to the loader */ 268 ipc_call_t answer; 269 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); 270 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf, 282 async_exch_t *exch = async_exchange_begin(ldr->sess); 283 284 ipc_call_t answer; 285 aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer); 286 sysarg_t rc = async_data_write_start(exch, (void *) files_buf, 271 287 count * sizeof(fdi_node_t)); 272 if (rc != EOK) { 273 async_wait_for(req, NULL); 274 return rc; 275 } 276 277 async_wait_for(req, &rc); 278 if (rc != EOK) 279 return rc; 280 281 /* Free temporary buffer */ 288 289 async_exchange_end(exch); 282 290 free(files_buf); 283 291 284 return EOK; 292 if (rc != EOK) { 293 async_wait_for(req, NULL); 294 return (int) rc; 295 } 296 297 async_wait_for(req, &rc); 298 return (int) rc; 285 299 } 286 300 … … 297 311 int loader_load_program(loader_t *ldr) 298 312 { 299 return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD); 313 async_exch_t *exch = async_exchange_begin(ldr->sess); 314 int rc = async_req_0_0(exch, LOADER_LOAD); 315 async_exchange_end(exch); 316 317 return rc; 300 318 } 301 319 … … 306 324 * the task and its thread is stopped. 307 325 * 308 * After using this function, no further operations mustbe performed309 * on the loader structure . It should be de-allocated using free().326 * After using this function, no further operations can be performed 327 * on the loader structure and it is deallocated. 310 328 * 311 329 * @param ldr Loader connection structure. … … 316 334 int loader_run(loader_t *ldr) 317 335 { 318 int rc = async_req_0_0(ldr->phone_id, LOADER_RUN); 336 async_exch_t *exch = async_exchange_begin(ldr->sess); 337 int rc = async_req_0_0(exch, LOADER_RUN); 338 async_exchange_end(exch); 339 319 340 if (rc != EOK) 320 341 return rc; 321 342 322 async_hangup(ldr->phone_id); 323 ldr->phone_id = 0; 343 async_hangup(ldr->sess); 344 free(ldr); 345 324 346 return EOK; 325 347 } … … 327 349 /** Cancel the loader session. 328 350 * 329 * Tell sthe loader not to load any program and terminate.330 * After using this function, no further operations mustbe performed331 * on the loader structure . It should be de-allocated using free().351 * Tell the loader not to load any program and terminate. 352 * After using this function, no further operations can be performed 353 * on the loader structure and it is deallocated. 332 354 * 333 355 * @param ldr Loader connection structure. … … 338 360 void loader_abort(loader_t *ldr) 339 361 { 340 async_hangup(ldr-> phone_id);341 ldr->phone_id = 0;362 async_hangup(ldr->sess); 363 free(ldr); 342 364 } 343 365 -
uspace/lib/c/generic/malloc.c
r52a79081 ra33f0a6 65 65 #define BASE_ALIGN 16 66 66 67 /** Heap shrink granularity 68 * 69 * Try not to pump and stress the heap to much 70 * by shrinking and enlarging it too often. 71 * A heap area won't shrunk if it the released 72 * free block is smaller than this constant. 73 * 74 */ 75 #define SHRINK_GRANULARITY (64 * PAGE_SIZE) 76 67 77 /** Overhead of each heap block. */ 68 78 #define STRUCT_OVERHEAD \ 69 79 (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t)) 70 80 81 /** Overhead of each area. */ 82 #define AREA_OVERHEAD(size) \ 83 (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN)) 84 71 85 /** Calculate real size of a heap block. 72 86 * … … 86 100 * 87 101 */ 88 #define AREA_FIRST_BLOCK (area) \102 #define AREA_FIRST_BLOCK_HEAD(area) \ 89 103 (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN)) 104 105 /** Get last block in heap area. 106 * 107 */ 108 #define AREA_LAST_BLOCK_FOOT(area) \ 109 (((uintptr_t) (area)->end) - sizeof(heap_block_foot_t)) 110 111 /** Get header in heap block. 112 * 113 */ 114 #define BLOCK_HEAD(foot) \ 115 ((heap_block_head_t *) \ 116 (((uintptr_t) (foot)) + sizeof(heap_block_foot_t) - (foot)->size)) 90 117 91 118 /** Get footer in heap block. … … 94 121 #define BLOCK_FOOT(head) \ 95 122 ((heap_block_foot_t *) \ 96 (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))123 (((uintptr_t) (head)) + (head)->size - sizeof(heap_block_foot_t))) 97 124 98 125 /** Heap area. … … 115 142 void *end; 116 143 144 /** Previous heap area */ 145 struct heap_area *prev; 146 117 147 /** Next heap area */ 118 148 struct heap_area *next; … … 157 187 158 188 /** Next heap block to examine (next fit algorithm) */ 159 static heap_block_head_t *next = NULL;189 static heap_block_head_t *next_fit = NULL; 160 190 161 191 /** Futex for thread-safe heap manipulation */ 162 192 static futex_t malloc_futex = FUTEX_INITIALIZER; 193 194 #ifndef NDEBUG 195 196 #define malloc_assert(expr) \ 197 do { \ 198 if (!(expr)) {\ 199 futex_up(&malloc_futex); \ 200 assert_abort(#expr, __FILE__, __LINE__); \ 201 } \ 202 } while (0) 203 204 #else /* NDEBUG */ 205 206 #define malloc_assert(expr) 207 208 #endif /* NDEBUG */ 163 209 164 210 /** Initialize a heap block … … 202 248 heap_block_head_t *head = (heap_block_head_t *) addr; 203 249 204 assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);250 malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC); 205 251 206 252 heap_block_foot_t *foot = BLOCK_FOOT(head); 207 253 208 assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);209 assert(head->size == foot->size);254 malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC); 255 malloc_assert(head->size == foot->size); 210 256 } 211 257 212 258 /** Check a heap area structure 213 259 * 260 * Should be called only inside the critical section. 261 * 214 262 * @param addr Address of the heap area. 215 263 * … … 219 267 heap_area_t *area = (heap_area_t *) addr; 220 268 221 assert(area->magic == HEAP_AREA_MAGIC); 222 assert(area->start < area->end); 223 assert(((uintptr_t) area->start % PAGE_SIZE) == 0); 224 assert(((uintptr_t) area->end % PAGE_SIZE) == 0); 269 malloc_assert(area->magic == HEAP_AREA_MAGIC); 270 malloc_assert(addr == area->start); 271 malloc_assert(area->start < area->end); 272 malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0); 273 malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0); 225 274 } 226 275 227 276 /** Create new heap area 228 277 * 229 * @param start Preffered starting address of the new area. 230 * @param size Size of the area. 278 * Should be called only inside the critical section. 279 * 280 * @param size Size of the area. 231 281 * 232 282 */ … … 248 298 249 299 area->start = astart; 250 area->end = (void *) 251 ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);300 area->end = (void *) ((uintptr_t) astart + asize); 301 area->prev = NULL; 252 302 area->next = NULL; 253 303 area->magic = HEAP_AREA_MAGIC; 254 304 255 void *block = (void *) AREA_FIRST_BLOCK (area);305 void *block = (void *) AREA_FIRST_BLOCK_HEAD(area); 256 306 size_t bsize = (size_t) (area->end - block); 257 307 … … 262 312 last_heap_area = area; 263 313 } else { 314 area->prev = last_heap_area; 264 315 last_heap_area->next = area; 265 316 last_heap_area = area; … … 271 322 /** Try to enlarge a heap area 272 323 * 324 * Should be called only inside the critical section. 325 * 273 326 * @param area Heap area to grow. 274 * @param size Gross size of item to allocate (bytes). 327 * @param size Gross size to grow (bytes). 328 * 329 * @return True if successful. 275 330 * 276 331 */ … … 282 337 area_check(area); 283 338 284 size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,285 PAGE_SIZE);286 287 339 /* New heap area size */ 288 void *end = (void *) 289 ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN); 340 size_t gross_size = (size_t) (area->end - area->start) + size; 341 size_t asize = ALIGN_UP(gross_size, PAGE_SIZE); 342 void *end = (void *) ((uintptr_t) area->start + asize); 290 343 291 344 /* Check for overflow */ … … 299 352 300 353 /* Add new free block */ 301 block_init(area->end, (size_t) (end - area->end), true, area); 354 size_t net_size = (size_t) (end - area->end); 355 if (net_size > 0) 356 block_init(area->end, net_size, true, area); 302 357 303 358 /* Update heap area parameters */ … … 309 364 /** Try to enlarge any of the heap areas 310 365 * 366 * Should be called only inside the critical section. 367 * 311 368 * @param size Gross size of item to allocate (bytes). 312 369 * … … 318 375 319 376 /* First try to enlarge some existing area */ 320 heap_area_t *area;321 for (area = first_heap_area; area != NULL;area = area->next) {377 for (heap_area_t *area = first_heap_area; area != NULL; 378 area = area->next) { 322 379 if (area_grow(area, size)) 323 380 return true; … … 325 382 326 383 /* Eventually try to create a new area */ 327 return area_create(AREA_FIRST_BLOCK(size)); 328 } 329 330 /** Try to shrink heap space 331 * 384 return area_create(AREA_OVERHEAD(size)); 385 } 386 387 /** Try to shrink heap 388 * 389 * Should be called only inside the critical section. 332 390 * In all cases the next pointer is reset. 333 391 * 334 */ 335 static void heap_shrink(void) 336 { 337 next = NULL; 392 * @param area Last modified heap area. 393 * 394 */ 395 static void heap_shrink(heap_area_t *area) 396 { 397 area_check(area); 398 399 heap_block_foot_t *last_foot = 400 (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area); 401 heap_block_head_t *last_head = BLOCK_HEAD(last_foot); 402 403 block_check((void *) last_head); 404 malloc_assert(last_head->area == area); 405 406 if (last_head->free) { 407 /* 408 * The last block of the heap area is 409 * unused. The area might be potentially 410 * shrunk. 411 */ 412 413 heap_block_head_t *first_head = 414 (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area); 415 416 block_check((void *) first_head); 417 malloc_assert(first_head->area == area); 418 419 size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE); 420 421 if (first_head == last_head) { 422 /* 423 * The entire heap area consists of a single 424 * free heap block. This means we can get rid 425 * of it entirely. 426 */ 427 428 heap_area_t *prev = area->prev; 429 heap_area_t *next = area->next; 430 431 if (prev != NULL) { 432 area_check(prev); 433 prev->next = next; 434 } else 435 first_heap_area = next; 436 437 if (next != NULL) { 438 area_check(next); 439 next->prev = prev; 440 } else 441 last_heap_area = prev; 442 443 as_area_destroy(area->start); 444 } else if (shrink_size >= SHRINK_GRANULARITY) { 445 /* 446 * Make sure that we always shrink the area 447 * by a multiple of page size and update 448 * the block layout accordingly. 449 */ 450 451 size_t asize = (size_t) (area->end - area->start) - shrink_size; 452 void *end = (void *) ((uintptr_t) area->start + asize); 453 454 /* Resize the address space area */ 455 int ret = as_area_resize(area->start, asize, 0); 456 if (ret != EOK) 457 abort(); 458 459 /* Update heap area parameters */ 460 area->end = end; 461 size_t excess = ((size_t) area->end) - ((size_t) last_head); 462 463 if (excess > 0) { 464 if (excess >= STRUCT_OVERHEAD) { 465 /* 466 * The previous block cannot be free and there 467 * is enough free space left in the area to 468 * create a new free block. 469 */ 470 block_init((void *) last_head, excess, true, area); 471 } else { 472 /* 473 * The excess is small. Therefore just enlarge 474 * the previous block. 475 */ 476 heap_block_foot_t *prev_foot = (heap_block_foot_t *) 477 (((uintptr_t) last_head) - sizeof(heap_block_foot_t)); 478 heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot); 479 480 block_check((void *) prev_head); 481 482 block_init(prev_head, prev_head->size + excess, 483 prev_head->free, area); 484 } 485 } 486 } 487 } 488 489 next_fit = NULL; 338 490 } 339 491 … … 362 514 static void split_mark(heap_block_head_t *cur, const size_t size) 363 515 { 364 assert(cur->size >= size);516 malloc_assert(cur->size >= size); 365 517 366 518 /* See if we should split the block. */ … … 398 550 { 399 551 area_check((void *) area); 400 assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area)); 401 assert((void *) first_block < area->end); 402 403 heap_block_head_t *cur; 404 for (cur = first_block; (void *) cur < area->end; 552 malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area)); 553 malloc_assert((void *) first_block < area->end); 554 555 for (heap_block_head_t *cur = first_block; (void *) cur < area->end; 405 556 cur = (heap_block_head_t *) (((void *) cur) + cur->size)) { 406 557 block_check(cur); … … 425 576 split_mark(cur, real_size); 426 577 427 next = cur;578 next_fit = cur; 428 579 return addr; 429 580 } else { … … 436 587 * data in (including alignment). 437 588 */ 438 if ((void *) cur > (void *) AREA_FIRST_BLOCK (area)) {589 if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) { 439 590 /* 440 591 * There is a block before the current block. … … 477 628 split_mark(next_head, real_size); 478 629 479 next = next_head;630 next_fit = next_head; 480 631 return aligned; 481 632 } else { … … 496 647 size_t reduced_size = cur->size - excess; 497 648 cur = (heap_block_head_t *) 498 (AREA_FIRST_BLOCK (area) + excess);649 (AREA_FIRST_BLOCK_HEAD(area) + excess); 499 650 500 block_init((void *) AREA_FIRST_BLOCK (area), excess,501 true, area);651 block_init((void *) AREA_FIRST_BLOCK_HEAD(area), 652 excess, true, area); 502 653 block_init(cur, reduced_size, true, area); 503 654 split_mark(cur, real_size); 504 655 505 next = cur;656 next_fit = cur; 506 657 return aligned; 507 658 } … … 527 678 static void *malloc_internal(const size_t size, const size_t align) 528 679 { 529 assert(first_heap_area != NULL);680 malloc_assert(first_heap_area != NULL); 530 681 531 682 if (align == 0) … … 541 692 542 693 /* Try the next fit approach */ 543 split = next ;694 split = next_fit; 544 695 545 696 if (split != NULL) { … … 552 703 553 704 /* Search the entire heap */ 554 heap_area_t *area;555 for (area = first_heap_area; area != NULL;area = area->next) {705 for (heap_area_t *area = first_heap_area; area != NULL; 706 area = area->next) { 556 707 heap_block_head_t *first = (heap_block_head_t *) 557 AREA_FIRST_BLOCK (area);708 AREA_FIRST_BLOCK_HEAD(area); 558 709 559 710 void *addr = malloc_area(area, first, split, real_size, … … 652 803 653 804 block_check(head); 654 assert(!head->free);805 malloc_assert(!head->free); 655 806 656 807 heap_area_t *area = head->area; 657 808 658 809 area_check(area); 659 assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));660 assert((void *) head < area->end);810 malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area)); 811 malloc_assert((void *) head < area->end); 661 812 662 813 void *ptr = NULL; … … 675 826 block_init((void *) head + real_size, 676 827 orig_size - real_size, true, area); 677 heap_shrink( );828 heap_shrink(area); 678 829 } 679 830 … … 697 848 698 849 ptr = ((void *) head) + sizeof(heap_block_head_t); 699 next = NULL;850 next_fit = NULL; 700 851 } else 701 852 reloc = true; … … 729 880 730 881 block_check(head); 731 assert(!head->free);882 malloc_assert(!head->free); 732 883 733 884 heap_area_t *area = head->area; 734 885 735 886 area_check(area); 736 assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));737 assert((void *) head < area->end);887 malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area)); 888 malloc_assert((void *) head < area->end); 738 889 739 890 /* Mark the block itself as free. */ … … 751 902 752 903 /* Look at the previous block. If it is free, merge the two. */ 753 if ((void *) head > (void *) AREA_FIRST_BLOCK (area)) {904 if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) { 754 905 heap_block_foot_t *prev_foot = 755 906 (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t)); … … 765 916 } 766 917 767 heap_shrink( );918 heap_shrink(area); 768 919 769 920 futex_up(&malloc_futex); 770 921 } 771 922 923 void *heap_check(void) 924 { 925 futex_down(&malloc_futex); 926 927 if (first_heap_area == NULL) { 928 futex_up(&malloc_futex); 929 return (void *) -1; 930 } 931 932 /* Walk all heap areas */ 933 for (heap_area_t *area = first_heap_area; area != NULL; 934 area = area->next) { 935 936 /* Check heap area consistency */ 937 if ((area->magic != HEAP_AREA_MAGIC) || 938 ((void *) area != area->start) || 939 (area->start >= area->end) || 940 (((uintptr_t) area->start % PAGE_SIZE) != 0) || 941 (((uintptr_t) area->end % PAGE_SIZE) != 0)) { 942 futex_up(&malloc_futex); 943 return (void *) area; 944 } 945 946 /* Walk all heap blocks */ 947 for (heap_block_head_t *head = (heap_block_head_t *) 948 AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end; 949 head = (heap_block_head_t *) (((void *) head) + head->size)) { 950 951 /* Check heap block consistency */ 952 if (head->magic != HEAP_BLOCK_HEAD_MAGIC) { 953 futex_up(&malloc_futex); 954 return (void *) head; 955 } 956 957 heap_block_foot_t *foot = BLOCK_FOOT(head); 958 959 if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) || 960 (head->size != foot->size)) { 961 futex_up(&malloc_futex); 962 return (void *) foot; 963 } 964 } 965 } 966 967 futex_up(&malloc_futex); 968 969 return NULL; 970 } 971 772 972 /** @} 773 973 */ -
uspace/lib/c/generic/net/icmp_api.c
r52a79081 ra33f0a6 54 54 * timeout occurs. 55 55 * 56 * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.56 * @param[in] sess The ICMP session. 57 57 * @param[in] size The message data length in bytes. 58 58 * @param[in] timeout The timeout in milliseconds. … … 73 73 */ 74 74 int 75 icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,75 icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl, 76 76 ip_tos_t tos, int dont_fragment, const struct sockaddr *addr, 77 77 socklen_t addrlen) … … 82 82 if (addrlen <= 0) 83 83 return EINVAL; 84 85 message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, 84 85 async_exch_t *exch = async_exchange_begin(sess); 86 87 message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl, 86 88 tos, (sysarg_t) dont_fragment, NULL); 87 89 88 90 /* Send the address */ 89 async_data_write_start(icmp_phone, addr, (size_t) addrlen); 91 async_data_write_start(exch, addr, (size_t) addrlen); 92 93 async_exchange_end(exch); 90 94 91 95 async_wait_for(message_id, &result); -
uspace/lib/c/generic/net/icmp_common.c
r52a79081 ra33f0a6 45 45 /** Connect to the ICMP module. 46 46 * 47 * @param[in] timeout Connection timeout in microseconds, zero 48 * for no timeout. 49 * 50 * @return ICMP module phone on success. 51 * @return ETIMEOUT if the connection timeouted. 47 * @return ICMP module session. 52 48 * 53 49 */ 54 int icmp_connect_module(suseconds_t timeout)50 async_sess_t *icmp_connect_module(void) 55 51 { 56 return connect_to_service _timeout(SERVICE_ICMP, timeout);52 return connect_to_service(SERVICE_ICMP); 57 53 } 58 54 -
uspace/lib/c/generic/net/modules.c
r52a79081 ra33f0a6 45 45 #include <ipc/services.h> 46 46 #include <net/modules.h> 47 48 /** The time between connect requests in microseconds. */ 49 #define MODULE_WAIT_TIME (10 * 1000) 47 #include <ns.h> 50 48 51 49 /** Answer a call. … … 95 93 } 96 94 97 /** Create bidirectional connection with the needed module service and register s95 /** Create bidirectional connection with the needed module service and register 98 96 * the message receiver. 99 97 * 100 * @param[in] need The needed module service. 101 * @param[in] arg1 The first parameter. 102 * @param[in] arg2 The second parameter. 103 * @param[in] arg3 The third parameter. 104 * @param[in] client_receiver The message receiver. 105 * 106 * @return The phone of the needed service. 107 * @return Other error codes as defined for the ipc_connect_to_me() 108 * function. 109 */ 110 int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 111 async_client_conn_t client_receiver) 112 { 113 return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0); 114 } 115 116 /** Create bidirectional connection with the needed module service and registers 117 * the message receiver. 118 * 119 * @param[in] need The needed module service. 120 * @param[in] arg1 The first parameter. 121 * @param[in] arg2 The second parameter. 122 * @param[in] arg3 The third parameter. 123 * @param[in] client_receiver The message receiver. 124 * @param[in] timeout The connection timeout in microseconds. No timeout if 125 * set to zero (0). 126 * 127 * @return The phone of the needed service. 128 * @return ETIMEOUT if the connection timeouted. 129 * @return Other error codes as defined for the ipc_connect_to_me() 130 * function. 131 * 132 */ 133 int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2, 134 sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout) 98 * @param[in] need Needed module service. 99 * @param[in] arg1 First parameter. 100 * @param[in] arg2 Second parameter. 101 * @param[in] arg3 Third parameter. 102 * @param[in] client_receiver Message receiver. 103 * 104 * @return Session to the needed service. 105 * @return Other error codes as defined for the async_connect_to_me() 106 * function. 107 * 108 */ 109 async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, 110 sysarg_t arg3, async_client_conn_t client_receiver) 135 111 { 136 112 /* Connect to the needed service */ 137 int phone = connect_to_service_timeout(need, timeout);138 if ( phone >= 0) {113 async_sess_t *sess = connect_to_service(need); 114 if (sess != NULL) { 139 115 /* Request the bidirectional connection */ 140 int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver); 116 async_exch_t *exch = async_exchange_begin(sess); 117 int rc = async_connect_to_me(exch, arg1, arg2, arg3, 118 client_receiver, NULL); 119 async_exchange_end(exch); 120 141 121 if (rc != EOK) { 142 async_hangup(phone); 143 return rc; 122 async_hangup(sess); 123 errno = rc; 124 return NULL; 144 125 } 145 126 } 146 127 147 return phone; 148 } 149 150 /** Connects to the needed module. 151 * 152 * @param[in] need The needed module service. 153 * @return The phone of the needed service. 154 */ 155 int connect_to_service(services_t need) 156 { 157 return connect_to_service_timeout(need, 0); 158 } 159 160 /** Connects to the needed module. 161 * 162 * @param[in] need The needed module service. 163 * @param[in] timeout The connection timeout in microseconds. No timeout if 164 * set to zero (0). 165 * @return The phone of the needed service. 166 * @return ETIMEOUT if the connection timeouted. 167 */ 168 int connect_to_service_timeout(services_t need, suseconds_t timeout) 169 { 170 int phone; 171 172 /* If no timeout is set */ 173 if (timeout <= 0) 174 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0); 175 176 while (true) { 177 phone = async_connect_me_to(PHONE_NS, need, 0, 0); 178 if ((phone >= 0) || (phone != ENOENT)) 179 return phone; 180 181 /* Abort if no time is left */ 182 if (timeout <= 0) 183 return ETIMEOUT; 184 185 /* Wait the minimum of the module wait time and the timeout */ 186 usleep((timeout <= MODULE_WAIT_TIME) ? 187 timeout : MODULE_WAIT_TIME); 188 timeout -= MODULE_WAIT_TIME; 189 } 190 } 191 192 /** Replies the data to the other party. 193 * 194 * @param[in] data The data buffer to be sent. 128 return sess; 129 } 130 131 /** Connect to the needed module. 132 * 133 * @param[in] need Needed module service. 134 * 135 * @return Session to the needed service. 136 * @return NULL if the connection timeouted. 137 * 138 */ 139 async_sess_t *connect_to_service(services_t need) 140 { 141 return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0); 142 } 143 144 /** Reply the data to the other party. 145 * 146 * @param[in] data The data buffer to be sent. 195 147 * @param[in] data_length The buffer length. 196 * @return EOK on success. 197 * @return EINVAL if the client does not expect the data. 198 * @return EOVERFLOW if the client does not expect all the data. 199 * Only partial data are transfered. 200 * @return Other error codes as defined for the 201 * async_data_read_finalize() function. 148 * 149 * @return EOK on success. 150 * @return EINVAL if the client does not expect the data. 151 * @return EOVERFLOW if the client does not expect all the data. 152 * Only partial data are transfered. 153 * @return Other error codes as defined for the 154 * async_data_read_finalize() function. 155 * 202 156 */ 203 157 int data_reply(void *data, size_t data_length) … … 205 159 size_t length; 206 160 ipc_callid_t callid; 207 161 208 162 /* Fetch the request */ 209 163 if (!async_data_read_receive(&callid, &length)) 210 164 return EINVAL; 211 165 212 166 /* Check the requested data size */ 213 167 if (length < data_length) { … … 215 169 return EOVERFLOW; 216 170 } 217 171 218 172 /* Send the data */ 219 173 return async_data_read_finalize(callid, data, data_length); -
uspace/lib/c/generic/net/socket_client.c
r52a79081 ra33f0a6 64 64 #define SOCKET_MAX_ACCEPTED_SIZE 0 65 65 66 /** Default timeout for connections in microseconds. */67 #define SOCKET_CONNECT_TIMEOUT (1 * 1000 * 1000)68 69 66 /** 70 67 * Maximum number of random attempts to find a new socket identifier before … … 86 83 /** Socket identifier. */ 87 84 int socket_id; 88 /** Parent module phone. */89 int phone;85 /** Parent module session. */ 86 async_sess_t *sess; 90 87 /** Parent module service. */ 91 88 services_t service; … … 146 143 /** Socket client library global data. */ 147 144 static struct socket_client_globals { 148 /** TCP module phone. */ 149 int tcp_phone; 150 /** UDP module phone. */ 151 int udp_phone; 152 153 // /** The last socket identifier. 154 // */ 155 // int last_id; 145 /** TCP module session. */ 146 async_sess_t *tcp_sess; 147 /** UDP module session. */ 148 async_sess_t *udp_sess; 156 149 157 150 /** Active sockets. */ … … 166 159 fibril_rwlock_t lock; 167 160 } socket_globals = { 168 .tcp_phone = -1, 169 .udp_phone = -1, 170 // .last_id = 0, 161 .tcp_sess = NULL, 162 .udp_sess = NULL, 171 163 .sockets = NULL, 172 164 .lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock) … … 202 194 * @param[in] iid The initial message identifier. 203 195 * @param[in] icall The initial message call structure. 204 */ 205 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall) 196 * @param[in] arg Local argument. 197 */ 198 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg) 206 199 { 207 200 ipc_callid_t callid; … … 281 274 } 282 275 283 /** Returns the TCP module phone. 284 * 285 * Connects to the TCP module if necessary. 286 * 287 * @return The TCP module phone. 288 * @return Other error codes as defined for the 289 * bind_service_timeout() function. 290 */ 291 static int socket_get_tcp_phone(void) 292 { 293 if (socket_globals.tcp_phone < 0) { 294 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 295 0, 0, SERVICE_TCP, socket_connection, 296 SOCKET_CONNECT_TIMEOUT); 297 } 298 299 return socket_globals.tcp_phone; 300 } 301 302 /** Returns the UDP module phone. 303 * 304 * Connects to the UDP module if necessary. 305 * 306 * @return The UDP module phone. 307 * @return Other error codes as defined for the 308 * bind_service_timeout() function. 309 */ 310 static int socket_get_udp_phone(void) 311 { 312 if (socket_globals.udp_phone < 0) { 313 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 314 0, 0, SERVICE_UDP, socket_connection, 315 SOCKET_CONNECT_TIMEOUT); 316 } 317 318 return socket_globals.udp_phone; 276 /** Return the TCP module session. 277 * 278 * Connect to the TCP module if necessary. 279 * 280 * @return The TCP module session. 281 * 282 */ 283 static async_sess_t *socket_get_tcp_sess(void) 284 { 285 if (socket_globals.tcp_sess == NULL) { 286 socket_globals.tcp_sess = bind_service(SERVICE_TCP, 287 0, 0, SERVICE_TCP, socket_connection); 288 } 289 290 return socket_globals.tcp_sess; 291 } 292 293 /** Return the UDP module session. 294 * 295 * Connect to the UDP module if necessary. 296 * 297 * @return The UDP module session. 298 * 299 */ 300 static async_sess_t *socket_get_udp_sess(void) 301 { 302 if (socket_globals.udp_sess == NULL) { 303 socket_globals.udp_sess = bind_service(SERVICE_UDP, 304 0, 0, SERVICE_UDP, socket_connection); 305 } 306 307 return socket_globals.udp_sess; 319 308 } 320 309 … … 332 321 sockets = socket_get_sockets(); 333 322 count = 0; 334 // socket_id = socket_globals.last_id;335 323 336 324 do { … … 345 333 if (socket_id < INT_MAX) { 346 334 ++socket_id; 347 /* } else if(socket_globals.last_id) { 348 * socket_globals.last_id = 0; 349 * socket_id = 1; 350 */ } else { 335 } else { 351 336 return ELIMIT; 352 337 } 353 338 } 354 339 } while (sockets_find(sockets, socket_id)); 355 356 // last_id = socket_id 340 357 341 return socket_id; 358 342 } … … 361 345 * 362 346 * @param[in,out] socket The socket to be initialized. 363 * @param[in] socket_id The new socket identifier. 364 * @param[in] phone The parent module phone. 365 * @param[in] service The parent module service. 366 */ 367 static void 368 socket_initialize(socket_t *socket, int socket_id, int phone, 369 services_t service) 347 * @param[in] socket_id The new socket identifier. 348 * @param[in] sess The parent module session. 349 * @param[in] service The parent module service. 350 */ 351 static void socket_initialize(socket_t *socket, int socket_id, 352 async_sess_t *sess, services_t service) 370 353 { 371 354 socket->socket_id = socket_id; 372 socket-> phone = phone;355 socket->sess = sess; 373 356 socket->service = service; 374 357 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); … … 395 378 * @return Other error codes as defined for the NET_SOCKET message. 396 379 * @return Other error codes as defined for the 397 * bind_service _timeout() function.380 * bind_service() function. 398 381 */ 399 382 int socket(int domain, int type, int protocol) 400 383 { 401 384 socket_t *socket; 402 int phone;385 async_sess_t *sess; 403 386 int socket_id; 404 387 services_t service; … … 417 400 switch (protocol) { 418 401 case IPPROTO_TCP: 419 phone = socket_get_tcp_phone();402 sess = socket_get_tcp_sess(); 420 403 service = SERVICE_TCP; 421 404 break; … … 432 415 switch (protocol) { 433 416 case IPPROTO_UDP: 434 phone = socket_get_udp_phone();417 sess = socket_get_udp_sess(); 435 418 service = SERVICE_UDP; 436 419 break; … … 453 436 } 454 437 455 if ( phone < 0)456 return phone;438 if (sess == NULL) 439 return ENOENT; 457 440 458 441 /* Create a new socket structure */ … … 471 454 return socket_id; 472 455 } 473 474 rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, 456 457 async_exch_t *exch = async_exchange_begin(sess); 458 rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL, 475 459 &fragment_size, &header_size); 460 async_exchange_end(exch); 461 476 462 if (rc != EOK) { 477 463 fibril_rwlock_write_unlock(&socket_globals.lock); … … 484 470 485 471 /* Finish the new socket initialization */ 486 socket_initialize(socket, socket_id, phone, service);472 socket_initialize(socket, socket_id, sess, service); 487 473 /* Store the new socket */ 488 474 rc = sockets_add(socket_get_sockets(), socket_id, socket); … … 493 479 dyn_fifo_destroy(&socket->accepted); 494 480 free(socket); 495 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 481 482 exch = async_exchange_begin(sess); 483 async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 496 484 service); 485 async_exchange_end(exch); 486 497 487 return rc; 498 488 } … … 538 528 539 529 /* Request the message */ 540 message_id = async_send_3(socket->phone, message, 530 async_exch_t *exch = async_exchange_begin(socket->sess); 531 message_id = async_send_3(exch, message, 541 532 (sysarg_t) socket->socket_id, arg2, socket->service, NULL); 542 533 /* Send the address */ 543 async_data_write_start(socket->phone, data, datalength); 534 async_data_write_start(exch, data, datalength); 535 async_exchange_end(exch); 544 536 545 537 fibril_rwlock_read_unlock(&socket_globals.lock); … … 598 590 599 591 /* Request listen backlog change */ 600 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, 592 async_exch_t *exch = async_exchange_begin(socket->sess); 593 result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN, 601 594 (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service); 595 async_exchange_end(exch); 602 596 603 597 fibril_rwlock_read_unlock(&socket_globals.lock); … … 669 663 return socket_id; 670 664 } 671 socket_initialize(new_socket, socket_id, socket-> phone,665 socket_initialize(new_socket, socket_id, socket->sess, 672 666 socket->service); 673 667 result = sockets_add(socket_get_sockets(), new_socket->socket_id, … … 681 675 682 676 /* Request accept */ 683 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, 677 async_exch_t *exch = async_exchange_begin(socket->sess); 678 message_id = async_send_5(exch, NET_SOCKET_ACCEPT, 684 679 (sysarg_t) socket->socket_id, 0, socket->service, 0, 685 680 new_socket->socket_id, &answer); 686 681 687 682 /* Read address */ 688 async_data_read_start(socket->phone, cliaddr, *addrlen); 683 async_data_read_start(exch, cliaddr, *addrlen); 684 async_exchange_end(exch); 685 689 686 fibril_rwlock_write_unlock(&socket_globals.lock); 690 687 async_wait_for(message_id, &ipc_result); … … 780 777 781 778 /* Request close */ 782 rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, 779 async_exch_t *exch = async_exchange_begin(socket->sess); 780 rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE, 783 781 (sysarg_t) socket->socket_id, 0, socket->service); 782 async_exchange_end(exch); 783 784 784 if (rc != EOK) { 785 785 fibril_rwlock_write_unlock(&socket_globals.lock); … … 853 853 854 854 /* Request send */ 855 message_id = async_send_5(socket->phone, message, 855 async_exch_t *exch = async_exchange_begin(socket->sess); 856 857 message_id = async_send_5(exch, message, 856 858 (sysarg_t) socket->socket_id, 857 859 (fragments == 1 ? datalength : socket->data_fragment_size), … … 860 862 /* Send the address if given */ 861 863 if (!toaddr || 862 (async_data_write_start( socket->phone, toaddr, addrlen) == EOK)) {864 (async_data_write_start(exch, toaddr, addrlen) == EOK)) { 863 865 if (fragments == 1) { 864 866 /* Send all if only one fragment */ 865 async_data_write_start( socket->phone, data, datalength);867 async_data_write_start(exch, data, datalength); 866 868 } else { 867 869 /* Send the first fragment */ 868 async_data_write_start( socket->phone, data,870 async_data_write_start(exch, data, 869 871 socket->data_fragment_size - socket->header_size); 870 872 data = ((const uint8_t *) data) + … … 873 875 /* Send the middle fragments */ 874 876 while (--fragments > 1) { 875 async_data_write_start( socket->phone, data,877 async_data_write_start(exch, data, 876 878 socket->data_fragment_size); 877 879 data = ((const uint8_t *) data) + … … 880 882 881 883 /* Send the last fragment */ 882 async_data_write_start( socket->phone, data,884 async_data_write_start(exch, data, 883 885 (datalength + socket->header_size) % 884 886 socket->data_fragment_size); 885 887 } 886 888 } 889 890 async_exchange_end(exch); 887 891 888 892 async_wait_for(message_id, &result); … … 1026 1030 return 0; 1027 1031 } 1032 1033 async_exch_t *exch = async_exchange_begin(socket->sess); 1028 1034 1029 1035 /* Prepare lengths if more fragments */ … … 1038 1044 1039 1045 /* Request packet data */ 1040 message_id = async_send_4( socket->phone, message,1046 message_id = async_send_4(exch, message, 1041 1047 (sysarg_t) socket->socket_id, 0, socket->service, 1042 1048 (sysarg_t) flags, &answer); … … 1044 1050 /* Read the address if desired */ 1045 1051 if(!fromaddr || 1046 (async_data_read_start( socket->phone, fromaddr,1052 (async_data_read_start(exch, fromaddr, 1047 1053 *addrlen) == EOK)) { 1048 1054 /* Read the fragment lengths */ 1049 if (async_data_read_start( socket->phone, lengths,1055 if (async_data_read_start(exch, lengths, 1050 1056 sizeof(int) * (fragments + 1)) == EOK) { 1051 1057 if (lengths[fragments] <= datalength) { … … 1054 1060 for (index = 0; index < fragments; 1055 1061 ++index) { 1056 async_data_read_start( 1057 socket->phone, data, 1062 async_data_read_start(exch, data, 1058 1063 lengths[index]); 1059 1064 data = ((uint8_t *) data) + … … 1067 1072 } else { /* fragments == 1 */ 1068 1073 /* Request packet data */ 1069 message_id = async_send_4( socket->phone, message,1074 message_id = async_send_4(exch, message, 1070 1075 (sysarg_t) socket->socket_id, 0, socket->service, 1071 1076 (sysarg_t) flags, &answer); … … 1073 1078 /* Read the address if desired */ 1074 1079 if (!fromaddr || 1075 (async_data_read_start(socket->phone, fromaddr, 1076 *addrlen) == EOK)) { 1080 (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) { 1077 1081 /* Read all if only one fragment */ 1078 async_data_read_start( socket->phone, data, datalength);1082 async_data_read_start(exch, data, datalength); 1079 1083 } 1080 1084 } 1085 1086 async_exchange_end(exch); 1081 1087 1082 1088 async_wait_for(message_id, &ipc_result); … … 1190 1196 1191 1197 /* Request option value */ 1192 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, 1198 async_exch_t *exch = async_exchange_begin(socket->sess); 1199 1200 message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT, 1193 1201 (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service, 1194 1202 NULL); 1195 1203 1196 1204 /* Read the length */ 1197 if (async_data_read_start( socket->phone, optlen,1205 if (async_data_read_start(exch, optlen, 1198 1206 sizeof(*optlen)) == EOK) { 1199 1207 /* Read the value */ 1200 async_data_read_start(socket->phone, value, *optlen); 1201 } 1208 async_data_read_start(exch, value, *optlen); 1209 } 1210 1211 async_exchange_end(exch); 1202 1212 1203 1213 fibril_rwlock_read_unlock(&socket_globals.lock); -
uspace/lib/c/generic/ns_obsolete.c
r52a79081 ra33f0a6 34 34 35 35 #include <async.h> 36 #include <ipc/ns.h> 36 #include <async_obsolete.h> 37 #include <ns_obsolete.h> 38 #include <kernel/ipc/ipc_methods.h> 37 39 38 int service_ register(sysarg_t service)40 int service_obsolete_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3) 39 41 { 40 return async_ connect_to_me(PHONE_NS, service, 0, 0, NULL);42 return async_obsolete_connect_me_to(PHONE_NS, service, arg2, arg3); 41 43 } 42 44 43 int service_ connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)45 int service_obsolete_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3) 44 46 { 45 return async_connect_me_to(PHONE_NS, service, arg2, arg3); 46 } 47 48 int service_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3) 49 { 50 return async_connect_me_to_blocking(PHONE_NS, service, arg2, arg3); 47 return async_obsolete_connect_me_to_blocking(PHONE_NS, service, arg2, arg3); 51 48 } 52 49 -
uspace/lib/c/generic/private/async.h
r52a79081 ra33f0a6 79 79 } awaiter_t; 80 80 81 /** Message data */ 82 typedef struct { 83 awaiter_t wdata; 84 85 /** If reply was received. */ 86 bool done; 87 88 /** Pointer to where the answer data is stored. */ 89 ipc_call_t *dataptr; 90 91 sysarg_t retval; 92 } amsg_t; 93 81 94 extern void __async_init(void); 82 95 extern void async_insert_timeout(awaiter_t *); 96 extern void reply_received(void *, int, ipc_call_t *); 83 97 84 98 #endif -
uspace/lib/c/generic/private/ns.h
r52a79081 ra33f0a6 33 33 */ 34 34 35 #ifndef LIBC_PRIVATE_ ASYNC_SESS_H_36 #define LIBC_PRIVATE_ ASYNC_SESS_H_35 #ifndef LIBC_PRIVATE_NS_H_ 36 #define LIBC_PRIVATE_NS_H_ 37 37 38 extern void __async_sess_init(void); 38 #include <async.h> 39 40 extern async_sess_t *session_ns; 39 41 40 42 #endif -
uspace/lib/c/generic/str.c
r52a79081 ra33f0a6 553 553 554 554 dstr_size = str_size(dest); 555 if (dstr_size >= size) 556 return; 557 555 558 str_cpy(dest + dstr_size, size - dstr_size, src); 559 } 560 561 /** Convert space-padded ASCII to string. 562 * 563 * Common legacy text encoding in hardware is 7-bit ASCII fitted into 564 * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces 565 * (ASCII 0x20). Convert space-padded ascii to string representation. 566 * 567 * If the text does not fit into the destination buffer, the function converts 568 * as many characters as possible and returns EOVERFLOW. 569 * 570 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is 571 * converted anyway and invalid characters are replaced with question marks 572 * (U_SPECIAL) and the function returns EIO. 573 * 574 * Regardless of return value upon return @a dest will always be well-formed. 575 * 576 * @param dest Destination buffer 577 * @param size Size of destination buffer 578 * @param src Space-padded ASCII. 579 * @param n Size of the source buffer in bytes. 580 * 581 * @return EOK on success, EOVERFLOW if the text does not fit 582 * destination buffer, EIO if the text contains 583 * non-ASCII bytes. 584 */ 585 int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n) 586 { 587 size_t sidx; 588 size_t didx; 589 size_t dlast; 590 uint8_t byte; 591 int rc; 592 int result; 593 594 /* There must be space for a null terminator in the buffer. */ 595 assert(size > 0); 596 result = EOK; 597 598 didx = 0; 599 dlast = 0; 600 for (sidx = 0; sidx < n; ++sidx) { 601 byte = src[sidx]; 602 if (!ascii_check(byte)) { 603 byte = U_SPECIAL; 604 result = EIO; 605 } 606 607 rc = chr_encode(byte, dest, &didx, size - 1); 608 if (rc != EOK) { 609 assert(rc == EOVERFLOW); 610 dest[didx] = '\0'; 611 return rc; 612 } 613 614 /* Remember dest index after last non-empty character */ 615 if (byte != 0x20) 616 dlast = didx; 617 } 618 619 /* Terminate string after last non-empty character */ 620 dest[dlast] = '\0'; 621 return result; 556 622 } 557 623 -
uspace/lib/c/generic/str_error.c
r52a79081 ra33f0a6 33 33 */ 34 34 35 #include <errno.h> 35 36 #include <str_error.h> 36 37 #include <stdio.h> … … 63 64 static fibril_local char noerr[NOERR_LEN]; 64 65 65 const char *str_error(const int e rrno)66 const char *str_error(const int e) 66 67 { 67 if ((e rrno <= 0) && (errno>= MIN_ERRNO))68 return err_desc[-e rrno];68 if ((e <= 0) && (e >= MIN_ERRNO)) 69 return err_desc[-e]; 69 70 70 snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno); 71 /* Ad hoc descriptions of error codes interesting for USB. */ 72 // FIXME: integrate these as first-class error values 73 switch (e) { 74 case EBADCHECKSUM: 75 return "Bad checksum"; 76 case ESTALL: 77 return "Operation stalled"; 78 case EAGAIN: 79 return "Resource temporarily unavailable"; 80 case EEMPTY: 81 return "Resource is empty"; 82 default: 83 break; 84 } 85 86 snprintf(noerr, NOERR_LEN, "Unkown error code %d", e); 71 87 return noerr; 72 88 } -
uspace/lib/c/generic/task.c
r52a79081 ra33f0a6 35 35 36 36 #include <task.h> 37 #include <libc.h>38 #include <stdlib.h>39 #include <errno.h>40 37 #include <loader/loader.h> 41 38 #include <stdarg.h> … … 43 40 #include <ipc/ns.h> 44 41 #include <macros.h> 42 #include <assert.h> 45 43 #include <async.h> 44 #include <errno.h> 45 #include <malloc.h> 46 #include <libc.h> 47 #include "private/ns.h" 46 48 47 49 task_id_t task_get_id(void) … … 68 70 int task_set_name(const char *name) 69 71 { 72 assert(name); 73 70 74 return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name)); 71 75 } … … 88 92 * loader API. Arguments are passed as a null-terminated array of strings. 89 93 * 90 * @param id If not NULL, the ID of the task is stored here on success. 91 * @param path Pathname of the binary to execute. 92 * @param argv Command-line arguments. 93 * 94 * @return Zero on success or negative error code. 94 * @param id If not NULL, the ID of the task is stored here on success. 95 * @param path Pathname of the binary to execute. 96 * @param argv Command-line arguments. 97 * 98 * @return Zero on success or negative error code. 99 * 95 100 */ 96 101 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 97 102 { 98 loader_t *ldr;99 task_id_t task_id;100 int rc;101 102 /* Connect to a program loader. */103 ldr = loader_connect();104 if (ldr == NULL)105 return EREFUSED;106 107 /* Get task ID. */108 rc = loader_get_task_id(ldr, &task_id);109 if (rc != EOK)110 goto error;111 112 /* Send spawner's current working directory. */113 rc = loader_set_cwd(ldr);114 if (rc != EOK)115 goto error;116 117 /* Send program pathname. */118 rc = loader_set_pathname(ldr, path);119 if (rc != EOK)120 goto error;121 122 /* Send arguments. */123 rc = loader_set_args(ldr, args);124 if (rc != EOK)125 goto error;126 127 103 /* Send default files */ 128 104 fdi_node_t *files[4]; … … 148 124 files[3] = NULL; 149 125 126 return task_spawnvf(id, path, args, files); 127 } 128 129 /** Create a new task by running an executable from the filesystem. 130 * 131 * This is really just a convenience wrapper over the more complicated 132 * loader API. Arguments are passed as a null-terminated array of strings. 133 * Files are passed as null-terminated array of pointers to fdi_node_t. 134 * 135 * @param id If not NULL, the ID of the task is stored here on success. 136 * @param path Pathname of the binary to execute. 137 * @param argv Command-line arguments. 138 * @param files Standard files to use. 139 * 140 * @return Zero on success or negative error code. 141 * 142 */ 143 int task_spawnvf(task_id_t *id, const char *path, const char *const args[], 144 fdi_node_t *const files[]) 145 { 146 /* Connect to a program loader. */ 147 loader_t *ldr = loader_connect(); 148 if (ldr == NULL) 149 return EREFUSED; 150 151 /* Get task ID. */ 152 task_id_t task_id; 153 int rc = loader_get_task_id(ldr, &task_id); 154 if (rc != EOK) 155 goto error; 156 157 /* Send spawner's current working directory. */ 158 rc = loader_set_cwd(ldr); 159 if (rc != EOK) 160 goto error; 161 162 /* Send program pathname. */ 163 rc = loader_set_pathname(ldr, path); 164 if (rc != EOK) 165 goto error; 166 167 /* Send arguments. */ 168 rc = loader_set_args(ldr, args); 169 if (rc != EOK) 170 goto error; 171 172 /* Send files */ 150 173 rc = loader_set_files(ldr, files); 151 174 if (rc != EOK) … … 163 186 164 187 /* Success */ 165 free(ldr);166 167 188 if (id != NULL) 168 189 *id = task_id; … … 173 194 /* Error exit */ 174 195 loader_abort(ldr); 175 free(ldr);176 196 return rc; 177 197 } … … 182 202 * loader API. Arguments are passed as a null-terminated list of arguments. 183 203 * 184 * @param id If not NULL, the ID of the task is stored here on success. 185 * @param path Pathname of the binary to execute. 186 * @param ... Command-line arguments. 187 * 188 * @return Zero on success or negative error code. 204 * @param id If not NULL, the ID of the task is stored here on success. 205 * @param path Pathname of the binary to execute. 206 * @param ... Command-line arguments. 207 * 208 * @return Zero on success or negative error code. 209 * 189 210 */ 190 211 int task_spawnl(task_id_t *task_id, const char *path, ...) 191 212 { 213 /* Count the number of arguments. */ 214 192 215 va_list ap; 193 int rc, cnt;194 216 const char *arg; 195 217 const char **arglist; 196 197 /* Count the number of arguments. */ 198 cnt = 0; 218 int cnt = 0; 219 199 220 va_start(ap, path); 200 221 do { … … 203 224 } while (arg != NULL); 204 225 va_end(ap); 205 226 206 227 /* Allocate argument list. */ 207 228 arglist = malloc(cnt * sizeof(const char *)); 208 229 if (arglist == NULL) 209 230 return ENOMEM; 210 231 211 232 /* Fill in arguments. */ 212 233 cnt = 0; … … 217 238 } while (arg != NULL); 218 239 va_end(ap); 219 240 220 241 /* Spawn task. */ 221 rc = task_spawnv(task_id, path, arglist);222 242 int rc = task_spawnv(task_id, path, arglist); 243 223 244 /* Free argument list. */ 224 245 free(arglist); … … 228 249 int task_wait(task_id_t id, task_exit_t *texit, int *retval) 229 250 { 251 assert(texit); 252 assert(retval); 253 254 async_exch_t *exch = async_exchange_begin(session_ns); 230 255 sysarg_t te, rv; 231 int rc; 232 233 rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id), 256 int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id), 234 257 UPPER32(id), &te, &rv); 258 async_exchange_end(exch); 259 235 260 *texit = te; 236 261 *retval = rv; 237 262 238 263 return rc; 239 264 } … … 241 266 int task_retval(int val) 242 267 { 243 return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val); 268 async_exch_t *exch = async_exchange_begin(session_ns); 269 int rc = (int) async_req_1_0(exch, NS_RETVAL, val); 270 async_exchange_end(exch); 271 272 return rc; 244 273 } 245 274 -
uspace/lib/c/generic/thread.c
r52a79081 ra33f0a6 44 44 45 45 #ifndef THREAD_INITIAL_STACK_PAGES_NO 46 #define THREAD_INITIAL_STACK_PAGES_NO 146 #define THREAD_INITIAL_STACK_PAGES_NO 2 47 47 #endif 48 48 -
uspace/lib/c/generic/time.c
r52a79081 ra33f0a6 207 207 } 208 208 209 void udelay(useconds_t time) 210 { 211 (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time); 212 } 213 214 209 215 /** Wait unconditionally for specified number of seconds 210 216 * -
uspace/lib/c/generic/udebug.c
r52a79081 ra33f0a6 35 35 #include <udebug.h> 36 36 #include <sys/types.h> 37 #include <kernel/ipc/ipc_methods.h> 37 38 #include <async.h> 38 39 39 int udebug_begin( int phoneid)40 int udebug_begin(async_sess_t *sess) 40 41 { 41 return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN); 42 async_exch_t *exch = async_exchange_begin(sess); 43 return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN); 42 44 } 43 45 44 int udebug_end( int phoneid)46 int udebug_end(async_sess_t *sess) 45 47 { 46 return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_END); 48 async_exch_t *exch = async_exchange_begin(sess); 49 return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END); 47 50 } 48 51 49 int udebug_set_evmask( int phoneid, udebug_evmask_t mask)52 int udebug_set_evmask(async_sess_t *sess, udebug_evmask_t mask) 50 53 { 51 return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_SET_EVMASK,52 54 async_exch_t *exch = async_exchange_begin(sess); 55 return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask); 53 56 } 54 57 55 int udebug_thread_read( int phoneid, void *buffer, size_t n,56 58 int udebug_thread_read(async_sess_t *sess, void *buffer, size_t n, 59 size_t *copied, size_t *needed) 57 60 { 58 61 sysarg_t a_copied, a_needed; 59 int rc;60 61 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,62 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);63 64 *copied = (size_t) a_copied;65 *needed = (size_t) a_needed;66 62 63 async_exch_t *exch = async_exchange_begin(sess); 64 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ, 65 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 66 67 *copied = (size_t) a_copied; 68 *needed = (size_t) a_needed; 69 67 70 return rc; 68 71 } 69 72 70 int udebug_name_read( int phoneid, void *buffer, size_t n,71 73 int udebug_name_read(async_sess_t *sess, void *buffer, size_t n, 74 size_t *copied, size_t *needed) 72 75 { 73 76 sysarg_t a_copied, a_needed; 74 int rc;75 76 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,77 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);78 79 *copied = (size_t) a_copied;80 *needed = (size_t) a_needed;81 77 78 async_exch_t *exch = async_exchange_begin(sess); 79 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ, 80 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 81 82 *copied = (size_t) a_copied; 83 *needed = (size_t) a_needed; 84 82 85 return rc; 83 86 } 84 87 85 int udebug_areas_read( int phoneid, void *buffer, size_t n,86 88 int udebug_areas_read(async_sess_t *sess, void *buffer, size_t n, 89 size_t *copied, size_t *needed) 87 90 { 88 91 sysarg_t a_copied, a_needed; 89 int rc;90 91 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,92 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);93 94 *copied = (size_t) a_copied;95 *needed = (size_t) a_needed;96 92 93 async_exch_t *exch = async_exchange_begin(sess); 94 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ, 95 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 96 97 *copied = (size_t) a_copied; 98 *needed = (size_t) a_needed; 99 97 100 return rc; 98 101 } 99 102 100 int udebug_mem_read( int phoneid, void *buffer, uintptr_t addr, size_t n)103 int udebug_mem_read(async_sess_t *sess, void *buffer, uintptr_t addr, size_t n) 101 104 { 102 return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ, 103 (sysarg_t)buffer, addr, n); 105 async_exch_t *exch = async_exchange_begin(sess); 106 return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ, 107 (sysarg_t) buffer, addr, n); 104 108 } 105 109 106 int udebug_args_read( int phoneid, thash_t tid, sysarg_t *buffer)110 int udebug_args_read(async_sess_t *sess, thash_t tid, sysarg_t *buffer) 107 111 { 108 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ, 109 tid, (sysarg_t)buffer); 112 async_exch_t *exch = async_exchange_begin(sess); 113 return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ, 114 tid, (sysarg_t) buffer); 110 115 } 111 116 112 int udebug_regs_read( int phoneid, thash_t tid, void *buffer)117 int udebug_regs_read(async_sess_t *sess, thash_t tid, void *buffer) 113 118 { 114 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ, 115 tid, (sysarg_t)buffer); 119 async_exch_t *exch = async_exchange_begin(sess); 120 return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ, 121 tid, (sysarg_t) buffer); 116 122 } 117 123 118 int udebug_go( int phoneid, thash_t tid, udebug_event_t *ev_type,124 int udebug_go(async_sess_t *sess, thash_t tid, udebug_event_t *ev_type, 119 125 sysarg_t *val0, sysarg_t *val1) 120 126 { 121 127 sysarg_t a_ev_type; 122 int rc;123 124 rc = async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,128 129 async_exch_t *exch = async_exchange_begin(sess); 130 int rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO, 125 131 tid, &a_ev_type, val0, val1); 126 132 127 133 *ev_type = a_ev_type; 128 134 return rc; 129 135 } 130 136 131 int udebug_stop( int phoneid, thash_t tid)137 int udebug_stop(async_sess_t *sess, thash_t tid) 132 138 { 133 return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_STOP,134 139 async_exch_t *exch = async_exchange_begin(sess); 140 return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid); 135 141 } 136 142 -
uspace/lib/c/generic/vfs/vfs.c
r52a79081 ra33f0a6 33 33 */ 34 34 35 #include <vfs/canonify.h> 35 36 #include <vfs/vfs.h> 36 #include <vfs/ canonify.h>37 #include <vfs/vfs_sess.h> 37 38 #include <macros.h> 38 39 #include <stdlib.h> … … 44 45 #include <sys/types.h> 45 46 #include <ipc/services.h> 46 #include < ipc/ns.h>47 #include <ns.h> 47 48 #include <async.h> 48 49 #include <fibril_synch.h> … … 54 55 #include <ipc/devmap.h> 55 56 56 static async_sess_t vfs_session; 57 58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex); 59 static int vfs_phone = -1; 57 static FIBRIL_MUTEX_INITIALIZE(vfs_mutex); 58 static async_sess_t *vfs_sess = NULL; 60 59 61 60 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex); … … 65 64 static size_t cwd_size = 0; 66 65 66 /** Start an async exchange on the VFS session. 67 * 68 * @return New exchange. 69 * 70 */ 71 static async_exch_t *vfs_exchange_begin(void) 72 { 73 fibril_mutex_lock(&vfs_mutex); 74 75 while (vfs_sess == NULL) 76 vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS, 77 0, 0); 78 79 fibril_mutex_unlock(&vfs_mutex); 80 81 return async_exchange_begin(vfs_sess); 82 } 83 84 /** Finish an async exchange on the VFS session. 85 * 86 * @param exch Exchange to be finished. 87 * 88 */ 89 static void vfs_exchange_end(async_exch_t *exch) 90 { 91 async_exchange_end(exch); 92 } 93 67 94 char *absolutize(const char *path, size_t *retlen) 68 95 { 69 96 char *ncwd_path; 70 97 char *ncwd_path_nc; 71 size_t total_size;72 98 73 99 fibril_mutex_lock(&cwd_mutex); … … 78 104 return NULL; 79 105 } 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 106 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 82 107 if (!ncwd_path_nc) { 83 108 fibril_mutex_unlock(&cwd_mutex); 84 109 return NULL; 85 110 } 86 str_cpy(ncwd_path_nc, total_size, cwd_path);111 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path); 87 112 ncwd_path_nc[cwd_size] = '/'; 88 113 ncwd_path_nc[cwd_size + 1] = '\0'; 89 114 } else { 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 115 ncwd_path_nc = malloc(size + 1); 92 116 if (!ncwd_path_nc) { 93 117 fibril_mutex_unlock(&cwd_mutex); … … 96 120 ncwd_path_nc[0] = '\0'; 97 121 } 98 str_append(ncwd_path_nc, total_size, path);122 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); 99 123 ncwd_path = canonify(ncwd_path_nc, retlen); 100 124 if (!ncwd_path) { … … 118 142 } 119 143 120 /** Connect to VFS service and create session. */121 static void vfs_connect(void)122 {123 while (vfs_phone < 0)124 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);125 126 async_session_create(&vfs_session, vfs_phone, 0);127 }128 129 /** Start an async exchange on the VFS session.130 *131 * @return New phone to be used during the exchange.132 */133 static int vfs_exchange_begin(void)134 {135 fibril_mutex_lock(&vfs_phone_mutex);136 if (vfs_phone < 0)137 vfs_connect();138 fibril_mutex_unlock(&vfs_phone_mutex);139 140 return async_exchange_begin(&vfs_session);141 }142 143 /** End an async exchange on the VFS session.144 *145 * @param phone Phone used during the exchange.146 */147 static void vfs_exchange_end(int phone)148 {149 async_exchange_end(&vfs_session, phone);150 }151 152 144 int mount(const char *fs_name, const char *mp, const char *fqdn, 153 145 const char *opts, unsigned int flags) … … 186 178 } 187 179 188 int vfs_phone= vfs_exchange_begin();180 async_exch_t *exch = vfs_exchange_begin(); 189 181 190 182 sysarg_t rc_orig; 191 aid_t req = async_send_2( vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);192 sysarg_t rc = async_data_write_start( vfs_phone, (void *) mpa, mpa_size);193 if (rc != EOK) { 194 vfs_exchange_end( vfs_phone);183 aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL); 184 sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size); 185 if (rc != EOK) { 186 vfs_exchange_end(exch); 195 187 free(mpa); 196 188 async_wait_for(req, &rc_orig); … … 205 197 } 206 198 207 rc = async_data_write_start( vfs_phone, (void *) opts, str_size(opts));208 if (rc != EOK) { 209 vfs_exchange_end( vfs_phone);199 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 200 if (rc != EOK) { 201 vfs_exchange_end(exch); 210 202 free(mpa); 211 203 async_wait_for(req, &rc_orig); … … 220 212 } 221 213 222 rc = async_data_write_start( vfs_phone, (void *) fs_name, str_size(fs_name));223 if (rc != EOK) { 224 vfs_exchange_end( vfs_phone);214 rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name)); 215 if (rc != EOK) { 216 vfs_exchange_end(exch); 225 217 free(mpa); 226 218 async_wait_for(req, &rc_orig); … … 236 228 237 229 /* Ask VFS whether it likes fs_name. */ 238 rc = async_req_0_0( vfs_phone, IPC_M_PING);239 if (rc != EOK) { 240 vfs_exchange_end( vfs_phone);230 rc = async_req_0_0(exch, VFS_IN_PING); 231 if (rc != EOK) { 232 vfs_exchange_end(exch); 241 233 free(mpa); 242 234 async_wait_for(req, &rc_orig); … … 251 243 } 252 244 253 vfs_exchange_end( vfs_phone);245 vfs_exchange_end(exch); 254 246 free(mpa); 255 247 async_wait_for(req, &rc); … … 273 265 return ENOMEM; 274 266 275 int vfs_phone= vfs_exchange_begin();276 277 req = async_send_0( vfs_phone, VFS_IN_UNMOUNT, NULL);278 rc = async_data_write_start( vfs_phone, (void *) mpa, mpa_size);279 if (rc != EOK) { 280 vfs_exchange_end( vfs_phone);267 async_exch_t *exch = vfs_exchange_begin(); 268 269 req = async_send_0(exch, VFS_IN_UNMOUNT, NULL); 270 rc = async_data_write_start(exch, (void *) mpa, mpa_size); 271 if (rc != EOK) { 272 vfs_exchange_end(exch); 281 273 free(mpa); 282 274 async_wait_for(req, &rc_orig); … … 288 280 289 281 290 vfs_exchange_end( vfs_phone);282 vfs_exchange_end(exch); 291 283 free(mpa); 292 284 async_wait_for(req, &rc); … … 297 289 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 298 290 { 299 int vfs_phone= vfs_exchange_begin();291 async_exch_t *exch = vfs_exchange_begin(); 300 292 301 293 ipc_call_t answer; 302 aid_t req = async_send_3( vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);303 sysarg_t rc = async_data_write_start( vfs_phone, abs, abs_size);304 305 if (rc != EOK) { 306 vfs_exchange_end( vfs_phone);294 aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer); 295 sysarg_t rc = async_data_write_start(exch, abs, abs_size); 296 297 if (rc != EOK) { 298 vfs_exchange_end(exch); 307 299 308 300 sysarg_t rc_orig; … … 315 307 } 316 308 317 vfs_exchange_end( vfs_phone);309 vfs_exchange_end(exch); 318 310 async_wait_for(req, &rc); 319 311 … … 339 331 int open_node(fdi_node_t *node, int oflag) 340 332 { 341 int vfs_phone= vfs_exchange_begin();333 async_exch_t *exch = vfs_exchange_begin(); 342 334 343 335 ipc_call_t answer; 344 aid_t req = async_send_4( vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,336 aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle, 345 337 node->devmap_handle, node->index, oflag, &answer); 346 338 347 vfs_exchange_end( vfs_phone);339 vfs_exchange_end(exch); 348 340 349 341 sysarg_t rc; … … 360 352 sysarg_t rc; 361 353 362 int vfs_phone = vfs_exchange_begin(); 363 364 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes); 365 366 vfs_exchange_end(vfs_phone); 367 368 return (int)rc; 354 async_exch_t *exch = vfs_exchange_begin(); 355 rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes); 356 vfs_exchange_end(exch); 357 358 return (int) rc; 369 359 } 370 360 … … 374 364 ipc_call_t answer; 375 365 aid_t req; 376 377 int vfs_phone = vfs_exchange_begin(); 378 379 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 380 rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte, 381 IPC_XF_RESTRICT); 382 if (rc != EOK) { 383 vfs_exchange_end(vfs_phone); 366 367 async_exch_t *exch = vfs_exchange_begin(); 368 369 req = async_send_1(exch, VFS_IN_READ, fildes, &answer); 370 rc = async_data_read_start(exch, (void *)buf, nbyte); 371 if (rc != EOK) { 372 vfs_exchange_end(exch); 384 373 385 374 sysarg_t rc_orig; … … 391 380 return (ssize_t) rc_orig; 392 381 } 393 vfs_exchange_end( vfs_phone);382 vfs_exchange_end(exch); 394 383 async_wait_for(req, &rc); 395 384 if (rc == EOK) … … 404 393 ipc_call_t answer; 405 394 aid_t req; 406 407 int vfs_phone = vfs_exchange_begin(); 408 409 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 410 rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte, 411 IPC_XF_RESTRICT); 412 if (rc != EOK) { 413 vfs_exchange_end(vfs_phone); 395 396 async_exch_t *exch = vfs_exchange_begin(); 397 398 req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer); 399 rc = async_data_write_start(exch, (void *)buf, nbyte); 400 if (rc != EOK) { 401 vfs_exchange_end(exch); 414 402 415 403 sysarg_t rc_orig; … … 421 409 return (ssize_t) rc_orig; 422 410 } 423 vfs_exchange_end( vfs_phone);411 vfs_exchange_end(exch); 424 412 async_wait_for(req, &rc); 425 413 if (rc == EOK) … … 429 417 } 430 418 419 /** Read entire buffer. 420 * 421 * In face of short reads this function continues reading until either 422 * the entire buffer is read or no more data is available (at end of file). 423 * 424 * @param fildes File descriptor 425 * @param buf Buffer, @a nbytes bytes long 426 * @param nbytes Number of bytes to read 427 * 428 * @return On success, positive number of bytes read. 429 * On failure, negative error code from read(). 430 */ 431 ssize_t read_all(int fildes, void *buf, size_t nbyte) 432 { 433 ssize_t cnt = 0; 434 size_t nread = 0; 435 uint8_t *bp = (uint8_t *) buf; 436 437 do { 438 bp += cnt; 439 nread += cnt; 440 cnt = read(fildes, bp, nbyte - nread); 441 } while (cnt > 0 && (nbyte - nread - cnt) > 0); 442 443 if (cnt < 0) 444 return cnt; 445 446 return nread + cnt; 447 } 448 449 /** Write entire buffer. 450 * 451 * This function fails if it cannot write exactly @a len bytes to the file. 452 * 453 * @param fildes File descriptor 454 * @param buf Data, @a nbytes bytes long 455 * @param nbytes Number of bytes to write 456 * 457 * @return EOK on error, return value from write() if writing 458 * failed. 459 */ 460 ssize_t write_all(int fildes, const void *buf, size_t nbyte) 461 { 462 ssize_t cnt = 0; 463 ssize_t nwritten = 0; 464 const uint8_t *bp = (uint8_t *) buf; 465 466 do { 467 bp += cnt; 468 nwritten += cnt; 469 cnt = write(fildes, bp, nbyte - nwritten); 470 } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0); 471 472 if (cnt < 0) 473 return cnt; 474 475 if ((ssize_t)nbyte - nwritten - cnt > 0) 476 return EIO; 477 478 return nbyte; 479 } 480 431 481 int fsync(int fildes) 432 482 { 433 int vfs_phone = vfs_exchange_begin(); 434 435 sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes); 436 437 vfs_exchange_end(vfs_phone); 483 async_exch_t *exch = vfs_exchange_begin(); 484 sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes); 485 vfs_exchange_end(exch); 438 486 439 487 return (int) rc; … … 442 490 off64_t lseek(int fildes, off64_t offset, int whence) 443 491 { 444 int vfs_phone= vfs_exchange_begin();492 async_exch_t *exch = vfs_exchange_begin(); 445 493 446 494 sysarg_t newoff_lo; 447 495 sysarg_t newoff_hi; 448 sysarg_t rc = async_req_4_2( vfs_phone, VFS_IN_SEEK, fildes,496 sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes, 449 497 LOWER32(offset), UPPER32(offset), whence, 450 498 &newoff_lo, &newoff_hi); 451 499 452 vfs_exchange_end( vfs_phone);500 vfs_exchange_end(exch); 453 501 454 502 if (rc != EOK) … … 462 510 sysarg_t rc; 463 511 464 int vfs_phone = vfs_exchange_begin(); 465 466 rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes, 512 async_exch_t *exch = vfs_exchange_begin(); 513 rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes, 467 514 LOWER32(length), UPPER32(length)); 468 vfs_exchange_end( vfs_phone);515 vfs_exchange_end(exch); 469 516 470 517 return (int) rc; … … 475 522 sysarg_t rc; 476 523 aid_t req; 477 478 int vfs_phone= vfs_exchange_begin();479 480 req = async_send_1( vfs_phone, VFS_IN_FSTAT, fildes, NULL);481 rc = async_data_read_start( vfs_phone, (void *) stat, sizeof(struct stat));482 if (rc != EOK) { 483 vfs_exchange_end( vfs_phone);524 525 async_exch_t *exch = vfs_exchange_begin(); 526 527 req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL); 528 rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat)); 529 if (rc != EOK) { 530 vfs_exchange_end(exch); 484 531 485 532 sysarg_t rc_orig; … … 491 538 return (ssize_t) rc_orig; 492 539 } 493 vfs_exchange_end( vfs_phone);540 vfs_exchange_end(exch); 494 541 async_wait_for(req, &rc); 495 542 … … 508 555 return ENOMEM; 509 556 510 int vfs_phone= vfs_exchange_begin();511 512 req = async_send_0( vfs_phone, VFS_IN_STAT, NULL);513 rc = async_data_write_start( vfs_phone, pa, pa_size);514 if (rc != EOK) { 515 vfs_exchange_end( vfs_phone);557 async_exch_t *exch = vfs_exchange_begin(); 558 559 req = async_send_0(exch, VFS_IN_STAT, NULL); 560 rc = async_data_write_start(exch, pa, pa_size); 561 if (rc != EOK) { 562 vfs_exchange_end(exch); 516 563 free(pa); 517 564 async_wait_for(req, &rc_orig); … … 521 568 return (int) rc_orig; 522 569 } 523 rc = async_data_read_start( vfs_phone, stat, sizeof(struct stat));524 if (rc != EOK) { 525 vfs_exchange_end( vfs_phone);570 rc = async_data_read_start(exch, stat, sizeof(struct stat)); 571 if (rc != EOK) { 572 vfs_exchange_end(exch); 526 573 free(pa); 527 574 async_wait_for(req, &rc_orig); … … 531 578 return (int) rc_orig; 532 579 } 533 vfs_exchange_end( vfs_phone);580 vfs_exchange_end(exch); 534 581 free(pa); 535 582 async_wait_for(req, &rc); … … 592 639 return ENOMEM; 593 640 594 int vfs_phone= vfs_exchange_begin();595 596 req = async_send_1( vfs_phone, VFS_IN_MKDIR, mode, NULL);597 rc = async_data_write_start( vfs_phone, pa, pa_size);598 if (rc != EOK) { 599 vfs_exchange_end( vfs_phone);641 async_exch_t *exch = vfs_exchange_begin(); 642 643 req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL); 644 rc = async_data_write_start(exch, pa, pa_size); 645 if (rc != EOK) { 646 vfs_exchange_end(exch); 600 647 free(pa); 601 648 … … 608 655 return (int) rc_orig; 609 656 } 610 vfs_exchange_end( vfs_phone);657 vfs_exchange_end(exch); 611 658 free(pa); 612 659 async_wait_for(req, &rc); … … 623 670 if (!pa) 624 671 return ENOMEM; 625 626 int vfs_phone= vfs_exchange_begin();627 628 req = async_send_0( vfs_phone, VFS_IN_UNLINK, NULL);629 rc = async_data_write_start( vfs_phone, pa, pa_size);630 if (rc != EOK) { 631 vfs_exchange_end( vfs_phone);672 673 async_exch_t *exch = vfs_exchange_begin(); 674 675 req = async_send_0(exch, VFS_IN_UNLINK, NULL); 676 rc = async_data_write_start(exch, pa, pa_size); 677 if (rc != EOK) { 678 vfs_exchange_end(exch); 632 679 free(pa); 633 680 … … 640 687 return (int) rc_orig; 641 688 } 642 vfs_exchange_end( vfs_phone);689 vfs_exchange_end(exch); 643 690 free(pa); 644 691 async_wait_for(req, &rc); … … 673 720 return ENOMEM; 674 721 } 675 676 int vfs_phone= vfs_exchange_begin();677 678 req = async_send_0( vfs_phone, VFS_IN_RENAME, NULL);679 rc = async_data_write_start( vfs_phone, olda, olda_size);680 if (rc != EOK) { 681 vfs_exchange_end( vfs_phone);722 723 async_exch_t *exch = vfs_exchange_begin(); 724 725 req = async_send_0(exch, VFS_IN_RENAME, NULL); 726 rc = async_data_write_start(exch, olda, olda_size); 727 if (rc != EOK) { 728 vfs_exchange_end(exch); 682 729 free(olda); 683 730 free(newa); … … 688 735 return (int) rc_orig; 689 736 } 690 rc = async_data_write_start( vfs_phone, newa, newa_size);691 if (rc != EOK) { 692 vfs_exchange_end( vfs_phone);737 rc = async_data_write_start(exch, newa, newa_size); 738 if (rc != EOK) { 739 vfs_exchange_end(exch); 693 740 free(olda); 694 741 free(newa); … … 699 746 return (int) rc_orig; 700 747 } 701 vfs_exchange_end( vfs_phone);748 vfs_exchange_end(exch); 702 749 free(olda); 703 750 free(newa); … … 755 802 } 756 803 757 int fd_phone(int fildes)804 async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes) 758 805 { 759 806 struct stat stat; 760 761 807 int rc = fstat(fildes, &stat); 762 if (rc != 0) 763 return rc; 764 765 if (!stat.device) 766 return -1; 767 768 return devmap_device_connect(stat.device, 0); 808 if (rc != 0) { 809 errno = rc; 810 return NULL; 811 } 812 813 if (!stat.device) { 814 errno = ENOENT; 815 return NULL; 816 } 817 818 return devmap_device_connect(mgmt, stat.device, 0); 769 819 } 770 820 … … 772 822 { 773 823 struct stat stat; 774 int rc; 775 776 rc = fstat(fildes, &stat); 824 int rc = fstat(fildes, &stat); 777 825 778 826 if (rc == EOK) { … … 787 835 int dup2(int oldfd, int newfd) 788 836 { 789 int vfs_phone= vfs_exchange_begin();837 async_exch_t *exch = vfs_exchange_begin(); 790 838 791 839 sysarg_t ret; 792 sysarg_t rc = async_req_2_1( vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);793 794 vfs_exchange_end( vfs_phone);840 sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret); 841 842 vfs_exchange_end(exch); 795 843 796 844 if (rc == EOK)
Note:
See TracChangeset
for help on using the changeset viewer.