Changes in / [197ef43:6aef742] in mainline
- Files:
-
- 1 added
- 4 deleted
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/event_types.h
r197ef43 r6aef742 41 41 /** Returning from kernel console to userspace */ 42 42 EVENT_KCONSOLE, 43 /** A t ask/thread has faulted and will be terminated */43 /** A thread has faulted and will be terminated */ 44 44 EVENT_FAULT, 45 45 EVENT_END -
kernel/generic/include/proc/task.h
r197ef43 r6aef742 131 131 extern task_t *task_find_by_id(task_id_t); 132 132 extern int task_kill(task_id_t); 133 extern void task_kill_self(bool) __attribute__((noreturn));134 133 extern void task_get_accounting(task_t *, uint64_t *, uint64_t *); 135 134 extern void task_print_list(bool); … … 156 155 extern sysarg_t sys_task_set_name(const char *, size_t); 157 156 extern sysarg_t sys_task_kill(task_id_t *); 158 extern sysarg_t sys_task_exit(sysarg_t);159 157 160 158 #endif -
kernel/generic/include/syscall/syscall.h
r197ef43 r6aef742 48 48 SYS_TASK_SET_NAME, 49 49 SYS_TASK_KILL, 50 SYS_TASK_EXIT,51 50 SYS_PROGRAM_SPAWN_LOADER, 52 51 -
kernel/generic/src/interrupt/interrupt.c
r197ef43 r6aef742 45 45 #include <console/console.h> 46 46 #include <console/cmd.h> 47 #include <ipc/event.h> 47 48 #include <synch/mutex.h> 48 49 #include <time/delay.h> … … 187 188 printf("\n"); 188 189 189 task_kill_self(true); 190 /* 191 * Userspace can subscribe for FAULT events to take action 192 * whenever a thread faults. (E.g. take a dump, run a debugger). 193 * The notification is always available, but unless Udebug is enabled, 194 * that's all you get. 195 */ 196 if (event_is_subscribed(EVENT_FAULT)) { 197 /* Notify the subscriber that a fault occurred. */ 198 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid), 199 UPPER32(TASK->taskid), (sysarg_t) THREAD); 200 201 #ifdef CONFIG_UDEBUG 202 /* Wait for a debugging session. */ 203 udebug_thread_fault(); 204 #endif 205 } 206 207 task_kill(TASK->taskid); 208 thread_exit(); 190 209 } 191 210 -
kernel/generic/src/proc/task.c
r197ef43 r6aef742 384 384 { 385 385 task_id_t taskid; 386 int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(taskid)); 386 int rc; 387 388 rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(taskid)); 387 389 if (rc != 0) 388 390 return (sysarg_t) rc; 389 391 390 392 return (sysarg_t) task_kill(taskid); 391 393 } … … 518 520 } 519 521 520 /** Kill the currently running task.521 *522 * @param notify Send out fault notifications.523 *524 * @return Zero on success or an error code from errno.h.525 *526 */527 void task_kill_self(bool notify)528 {529 /*530 * User space can subscribe for FAULT events to take action531 * whenever a task faults (to take a dump, run a debugger, etc.).532 * The notification is always available, but unless udebug is enabled,533 * that's all you get.534 */535 if (notify) {536 if (event_is_subscribed(EVENT_FAULT)) {537 /* Notify the subscriber that a fault occurred. */538 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),539 UPPER32(TASK->taskid), (sysarg_t) THREAD);540 541 #ifdef CONFIG_UDEBUG542 /* Wait for a debugging session. */543 udebug_thread_fault();544 #endif545 }546 }547 548 irq_spinlock_lock(&tasks_lock, true);549 task_kill_internal(TASK);550 irq_spinlock_unlock(&tasks_lock, true);551 552 thread_exit();553 }554 555 /** Process syscall to terminate the current task.556 *557 * @param notify Send out fault notifications.558 *559 */560 sysarg_t sys_task_exit(sysarg_t notify)561 {562 task_kill_self(notify);563 564 /* Unreachable */565 return EOK;566 }567 568 522 static bool task_print_walker(avltree_node_t *node, void *arg) 569 523 { -
kernel/generic/src/syscall/syscall.c
r197ef43 r6aef742 86 86 } else { 87 87 printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id); 88 task_kill_self(true); 88 task_kill(TASK->taskid); 89 thread_exit(); 89 90 } 90 91 … … 130 131 (syshandler_t) sys_task_set_name, 131 132 (syshandler_t) sys_task_kill, 132 (syshandler_t) sys_task_exit,133 133 (syshandler_t) sys_program_spawn_loader, 134 134 -
uspace/lib/c/Makefile
r197ef43 r6aef742 97 97 generic/adt/char_map.c \ 98 98 generic/time.c \ 99 generic/err.c \ 99 100 generic/stdlib.c \ 100 101 generic/mman.c \ -
uspace/lib/c/arch/abs32le/src/entry.c
r197ef43 r6aef742 37 37 { 38 38 __main(NULL); 39 __exit(); 39 40 } 40 41 -
uspace/lib/c/arch/abs32le/src/thread_entry.c
r197ef43 r6aef742 31 31 32 32 #include <unistd.h> 33 #include "../../../generic/private/thread.h"33 #include <thread.h> 34 34 35 35 void __thread_entry(void) -
uspace/lib/c/arch/amd64/src/entry.s
r197ef43 r6aef742 47 47 # Pass PCB pointer to __main (no operation) 48 48 call __main 49 50 call __exit -
uspace/lib/c/arch/arm32/src/entry.s
r197ef43 r6aef742 42 42 ldr r0, =ras_page 43 43 str r2, [r0] 44 44 45 45 # 46 46 # Create the first stack frame. … … 50 50 push {fp, ip, lr, pc} 51 51 sub fp, ip, #4 52 52 53 53 # Pass pcb_ptr to __main as the first argument (in r0) 54 54 mov r0, r1 55 55 bl __main 56 57 bl __exit 56 58 57 59 .data … … 60 62 ras_page: 61 63 .long 0 64 -
uspace/lib/c/arch/ia32/src/entry.s
r197ef43 r6aef742 46 46 mov %ax, %fs 47 47 # Do not set %gs, it contains descriptor that can see TLS 48 48 49 49 # Detect the mechanism used for making syscalls 50 50 movl $(INTEL_CPUID_STANDARD), %eax … … 58 58 # Create the first stack frame. 59 59 # 60 pushl $0 60 pushl $0 61 61 movl %esp, %ebp 62 62 63 63 # Pass the PCB pointer to __main as the first argument 64 64 pushl %edi 65 65 call __main 66 67 call __exit -
uspace/lib/c/arch/ia64/src/entry.s
r197ef43 r6aef742 40 40 alloc loc0 = ar.pfs, 0, 1, 2, 0 41 41 movl gp = _gp 42 42 43 43 # Pass PCB pointer as the first argument to __main 44 44 mov out0 = r2 45 45 br.call.sptk.many b0 = __main 46 0: 47 br.call.sptk.many b0 = __exit -
uspace/lib/c/arch/mips32/src/entry.s
r197ef43 r6aef742 56 56 jal __main 57 57 nop 58 59 jal __exit 60 nop 58 61 .end 59 62 -
uspace/lib/c/arch/ppc32/src/entry.s
r197ef43 r6aef742 44 44 stw %r3, 0(%r1) 45 45 stwu %r1, -16(%r1) 46 46 47 47 # Pass the PCB pointer to __main() as the first argument. 48 48 # The first argument is passed in r3. 49 49 mr %r3, %r6 50 50 bl __main 51 52 bl __exit -
uspace/lib/c/arch/sparc64/src/entry.s
r197ef43 r6aef742 45 45 flushw 46 46 add %g0, -0x7ff, %fp 47 47 48 48 # Pass pcb_ptr as the first argument to __main() 49 49 mov %i1, %o0 … … 51 51 call __main 52 52 or %l7, %lo(_gp), %l7 53 54 call __exit 55 nop -
uspace/lib/c/generic/async.c
r197ef43 r6aef742 42 42 * You should be able to write very simple multithreaded programs, the async 43 43 * framework will automatically take care of most synchronization problems. 44 * 45 * Default semantics: 46 * - async_send_*(): Send asynchronously. If the kernel refuses to send 47 * more messages, [ try to get responses from kernel, if 48 * nothing found, might try synchronous ] 44 49 * 45 50 * Example of use (pseudo C): … … 122 127 123 128 /** 124 * Structures of this type are used to group information about 125 * a call and about amessage queue link.129 * Structures of this type are used to group information about a call and a 130 * message queue link. 126 131 */ 127 132 typedef struct { … … 151 156 /** Link to the client tracking structure. */ 152 157 client_t *client; 153 158 154 159 /** Messages that should be delivered to this fibril. */ 155 160 link_t msg_queue; … … 168 173 169 174 /** Identifier of the incoming connection handled by the current fibril. */ 170 staticfibril_local connection_t *FIBRIL_connection;175 fibril_local connection_t *FIBRIL_connection; 171 176 172 177 static void *default_client_data_constructor(void) … … 197 202 { 198 203 assert(FIBRIL_connection); 204 199 205 return FIBRIL_connection->client->data; 200 206 } 201 207 202 /** Default fibril function that gets called to handle new connection. 203 * 204 * This function is defined as a weak symbol - to be redefined in user code. 205 * 206 * @param callid Hash of the incoming call. 207 * @param call Data of the incoming call. 208 * 209 */ 210 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 211 { 212 ipc_answer_0(callid, ENOENT); 213 } 208 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); 209 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); 214 210 215 211 /** … … 217 213 */ 218 214 static async_client_conn_t client_connection = default_client_connection; 219 220 /** Default fibril function that gets called to handle interrupt notifications.221 *222 * This function is defined as a weak symbol - to be redefined in user code.223 *224 * @param callid Hash of the incoming call.225 * @param call Data of the incoming call.226 *227 */228 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)229 {230 }231 215 232 216 /** … … 240 224 static LIST_INITIALIZE(timeout_list); 241 225 242 #define CLIENT_HASH_TABLE_BUCKETS 243 #define CONN_HASH_TABLE_BUCKETS 244 245 static hash_index_t client_hash(unsigned long key[])226 #define CLIENT_HASH_TABLE_BUCKETS 32 227 #define CONN_HASH_TABLE_BUCKETS 32 228 229 static hash_index_t client_hash(unsigned long *key) 246 230 { 247 231 assert(key); 248 return ((( key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);232 return (((*key) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 249 233 } 250 234 251 235 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 252 236 { 253 client_t *cl ient= hash_table_get_instance(item, client_t, link);254 return (key[0] == cl ient->in_task_hash);237 client_t *cl = hash_table_get_instance(item, client_t, link); 238 return (key[0] == cl->in_task_hash); 255 239 } 256 240 … … 273 257 * 274 258 */ 275 static hash_index_t conn_hash(unsigned long key[])259 static hash_index_t conn_hash(unsigned long *key) 276 260 { 277 261 assert(key); 278 return ((( key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);262 return (((*key) >> 4) % CONN_HASH_TABLE_BUCKETS); 279 263 } 280 264 … … 290 274 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 291 275 { 292 connection_t * conn= hash_table_get_instance(item, connection_t, link);293 return (key[0] == conn->in_phone_hash);276 connection_t *hs = hash_table_get_instance(item, connection_t, link); 277 return (key[0] == hs->in_phone_hash); 294 278 } 295 279 … … 306 290 free(hash_table_get_instance(item, connection_t, link)); 307 291 } 292 308 293 309 294 /** Operations for the connection hash table. */ … … 326 311 link_t *tmp = timeout_list.next; 327 312 while (tmp != &timeout_list) { 328 awaiter_t *cur 329 = list_get_instance(tmp, awaiter_t, to_event.link); 313 awaiter_t *cur; 330 314 315 cur = list_get_instance(tmp, awaiter_t, to_event.link); 331 316 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 332 317 break; 333 334 318 tmp = tmp->next; 335 319 } … … 348 332 * 349 333 * @return False if the call doesn't match any connection. 350 * @returnTrue if the call was passed to the respective connection fibril.334 * True if the call was passed to the respective connection fibril. 351 335 * 352 336 */ … … 485 469 * the first IPC_M_PHONE_HUNGUP call and continues to 486 470 * call async_get_call_timeout(). Repeat 487 * IPC_M_PHONE_HUNGUP until the caller notices. 471 * IPC_M_PHONE_HUNGUP until the caller notices. 488 472 */ 489 473 memset(call, 0, sizeof(ipc_call_t)); … … 492 476 return conn->close_callid; 493 477 } 494 478 495 479 if (usecs) 496 480 async_insert_timeout(&conn->wdata); … … 530 514 } 531 515 516 /** Default fibril function that gets called to handle new connection. 517 * 518 * This function is defined as a weak symbol - to be redefined in user code. 519 * 520 * @param callid Hash of the incoming call. 521 * @param call Data of the incoming call. 522 * 523 */ 524 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 525 { 526 ipc_answer_0(callid, ENOENT); 527 } 528 529 /** Default fibril function that gets called to handle interrupt notifications. 530 * 531 * This function is defined as a weak symbol - to be redefined in user code. 532 * 533 * @param callid Hash of the incoming call. 534 * @param call Data of the incoming call. 535 * 536 */ 537 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call) 538 { 539 } 540 532 541 /** Wrapper for client connection fibril. 533 542 * … … 542 551 static int connection_fibril(void *arg) 543 552 { 553 unsigned long key; 554 client_t *cl; 555 link_t *lnk; 556 bool destroy = false; 557 544 558 /* 545 559 * Setup fibril-local connection pointer. 546 560 */ 547 561 FIBRIL_connection = (connection_t *) arg; 548 549 futex_down(&async_futex); 550 562 551 563 /* 552 564 * Add our reference for the current connection in the client task … … 554 566 * hash in a new tracking structure. 555 567 */ 556 557 unsigned long key = FIBRIL_connection->in_task_hash; 558 link_t *lnk = hash_table_find(&client_hash_table, &key); 559 560 client_t *client; 561 568 futex_down(&async_futex); 569 key = FIBRIL_connection->in_task_hash; 570 lnk = hash_table_find(&client_hash_table, &key); 562 571 if (lnk) { 563 cl ient= hash_table_get_instance(lnk, client_t, link);564 cl ient->refcnt++;572 cl = hash_table_get_instance(lnk, client_t, link); 573 cl->refcnt++; 565 574 } else { 566 cl ient= malloc(sizeof(client_t));567 if (!cl ient) {575 cl = malloc(sizeof(client_t)); 576 if (!cl) { 568 577 ipc_answer_0(FIBRIL_connection->callid, ENOMEM); 569 578 futex_up(&async_futex); 570 579 return 0; 571 580 } 572 573 client->in_task_hash = FIBRIL_connection->in_task_hash; 574 581 cl->in_task_hash = FIBRIL_connection->in_task_hash; 575 582 async_serialize_start(); 576 cl ient->data = async_client_data_create();583 cl->data = async_client_data_create(); 577 584 async_serialize_end(); 578 579 client->refcnt = 1; 580 hash_table_insert(&client_hash_table, &key, &client->link); 581 } 582 585 cl->refcnt = 1; 586 hash_table_insert(&client_hash_table, &key, &cl->link); 587 } 583 588 futex_up(&async_futex); 584 585 FIBRIL_connection->client = cl ient;586 589 590 FIBRIL_connection->client = cl; 591 587 592 /* 588 593 * Call the connection handler function. … … 594 599 * Remove the reference for this client task connection. 595 600 */ 596 bool destroy;597 598 601 futex_down(&async_futex); 599 600 if (--client->refcnt == 0) { 602 if (--cl->refcnt == 0) { 601 603 hash_table_remove(&client_hash_table, &key, 1); 602 604 destroy = true; 603 } else 604 destroy = false; 605 605 } 606 606 futex_up(&async_futex); 607 607 608 608 if (destroy) { 609 if (client->data) 610 async_client_data_destroy(client->data); 611 612 free(client); 613 } 614 609 if (cl->data) 610 async_client_data_destroy(cl->data); 611 free(cl); 612 } 613 615 614 /* 616 615 * Remove myself from the connection hash table. … … 625 624 */ 626 625 while (!list_empty(&FIBRIL_connection->msg_queue)) { 627 msg_t *msg = 628 list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, 629 link); 626 msg_t *msg; 630 627 628 msg = list_get_instance(FIBRIL_connection->msg_queue.next, 629 msg_t, link); 631 630 list_remove(&msg->link); 632 631 ipc_answer_0(msg->callid, EHANGUP); … … 671 670 if (callid) 672 671 ipc_answer_0(callid, ENOMEM); 673 674 672 return (uintptr_t) NULL; 675 673 } … … 719 717 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 720 718 { 721 /* Unrouted call - take some default action*/719 /* Unrouted call - do some default behaviour */ 722 720 if ((callid & IPC_CALLID_NOTIFICATION)) { 723 721 process_notification(callid, call); 724 return;722 goto out; 725 723 } 726 724 … … 728 726 case IPC_M_CONNECT_ME: 729 727 case IPC_M_CONNECT_ME_TO: 730 /* Open new connection with fibril ,etc. */728 /* Open new connection with fibril etc. */ 731 729 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call), 732 730 callid, call, client_connection); 733 return;731 goto out; 734 732 } 735 733 736 734 /* Try to route the call through the connection hash table */ 737 735 if (route_call(callid, call)) 738 return;736 goto out; 739 737 740 738 /* Unknown call from unknown phone - hang it up */ 741 739 ipc_answer_0(callid, EHANGUP); 740 return; 741 742 out: 743 ; 742 744 } 743 745 … … 752 754 link_t *cur = timeout_list.next; 753 755 while (cur != &timeout_list) { 754 awaiter_t *waiter = 755 list_get_instance(cur, awaiter_t, to_event.link); 756 awaiter_t *waiter; 756 757 758 waiter = list_get_instance(cur, awaiter_t, to_event.link); 757 759 if (tv_gt(&waiter->to_event.expires, &tv)) 758 760 break; 759 761 760 762 cur = cur->next; 761 763 762 764 list_remove(&waiter->to_event.link); 763 765 waiter->to_event.inlist = false; … … 786 788 while (true) { 787 789 if (fibril_switch(FIBRIL_FROM_MANAGER)) { 788 futex_up(&async_futex); 790 futex_up(&async_futex); 789 791 /* 790 792 * async_futex is always held when entering a manager … … 809 811 continue; 810 812 } else 811 timeout = tv_sub(&waiter->to_event.expires, &tv); 813 timeout = tv_sub(&waiter->to_event.expires, 814 &tv); 812 815 } else 813 816 timeout = SYNCH_NO_TIMEOUT; 814 817 815 818 futex_up(&async_futex); 816 819 817 820 atomic_inc(&threads_in_ipc_wait); 818 821 … … 822 825 823 826 atomic_dec(&threads_in_ipc_wait); 824 827 825 828 if (!callid) { 826 829 handle_expired_timeouts(); … … 872 875 /** Initialize the async framework. 873 876 * 874 */ 875 void __async_init(void) 877 * @return Zero on success or an error code. 878 */ 879 int __async_init(void) 876 880 { 877 881 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1, 878 &client_hash_table_ops)) 879 abort(); 880 881 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1, 882 &conn_hash_table_ops)) 883 abort(); 882 &client_hash_table_ops) || !hash_table_create(&conn_hash_table, 883 CONN_HASH_TABLE_BUCKETS, 1, &conn_hash_table_ops)) { 884 return ENOMEM; 885 } 886 887 _async_sess_init(); 888 889 return 0; 884 890 } 885 891 … … 894 900 * @param retval Value returned in the answer. 895 901 * @param data Call data of the answer. 896 *897 902 */ 898 903 static void reply_received(void *arg, int retval, ipc_call_t *data) … … 942 947 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 943 948 { 944 amsg_t *msg = malloc(sizeof( amsg_t));949 amsg_t *msg = malloc(sizeof(*msg)); 945 950 946 951 if (!msg) … … 951 956 952 957 msg->wdata.to_event.inlist = false; 953 954 /* 955 * We may sleep in the next method, 956 * but it will use its own means 957 */ 958 /* We may sleep in the next method, but it will use its own mechanism */ 958 959 msg->wdata.active = true; 959 960 … … 986 987 ipc_call_t *dataptr) 987 988 { 988 amsg_t *msg = malloc(sizeof( amsg_t));989 amsg_t *msg = malloc(sizeof(*msg)); 989 990 990 991 if (!msg) … … 995 996 996 997 msg->wdata.to_event.inlist = false; 997 998 /* 999 * We may sleep in the next method, 1000 * but it will use its own means 1001 */ 998 /* We may sleep in next method, but it will use its own mechanism */ 1002 999 msg->wdata.active = true; 1003 1000 … … 1098 1095 void async_usleep(suseconds_t timeout) 1099 1096 { 1100 amsg_t *msg = malloc(sizeof( amsg_t));1097 amsg_t *msg = malloc(sizeof(*msg)); 1101 1098 1102 1099 if (!msg) … … 1310 1307 } 1311 1308 1312 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,1313 sysarg_t arg1, sysarg_t arg2, unsignedint mode)1309 int async_forward_fast(ipc_callid_t callid, int phoneid, int imethod, 1310 sysarg_t arg1, sysarg_t arg2, int mode) 1314 1311 { 1315 1312 return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode); 1316 1313 } 1317 1314 1318 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,1315 int async_forward_slow(ipc_callid_t callid, int phoneid, int imethod, 1319 1316 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 1320 unsignedint mode)1317 int mode) 1321 1318 { 1322 1319 return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4, … … 1431 1428 } 1432 1429 1433 /** Wrapper for IPC_M_SHARE_IN calls using the async framework.1434 * 1435 * @param phoneid 1436 * @param dst 1437 * @param size 1438 * @param arg 1439 * @param flags Storage for the received flags. Can be NULL.1440 * 1441 * @return Zero on success or a negative error code from errno.h.1442 * 1430 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework. 1431 * 1432 * @param phoneid Phone that will be used to contact the receiving side. 1433 * @param dst Destination address space area base. 1434 * @param size Size of the destination address space area. 1435 * @param arg User defined argument. 1436 * @param flags Storage where the received flags will be stored. Can be 1437 * NULL. 1438 * 1439 * @return Zero on success or a negative error code from errno.h. 1443 1440 */ 1444 1441 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 1445 unsigned int *flags) 1446 { 1442 int *flags) 1443 { 1444 int res; 1447 1445 sysarg_t tmp_flags; 1448 intres = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,1446 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst, 1449 1447 (sysarg_t) size, arg, NULL, &tmp_flags); 1450 1451 1448 if (flags) 1452 *flags = (unsigned int) tmp_flags; 1453 1449 *flags = tmp_flags; 1454 1450 return res; 1455 1451 } … … 1457 1453 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework. 1458 1454 * 1459 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN 1460 * calls so that the user doesn't have to remember the meaning of each IPC 1461 * argument. 1455 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls 1456 * so that the user doesn't have to remember the meaning of each IPC argument. 1462 1457 * 1463 1458 * So far, this wrapper is to be used from within a connection fibril. 1464 1459 * 1465 * @param callid Storage for the hash of the IPC_M_SHARE_IN call. 1466 * @param size Destination address space area size. 1467 * 1468 * @return True on success, false on failure. 1469 * 1470 */ 1471 bool async_share_in_receive(ipc_callid_t *callid, size_t *size) 1472 { 1460 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will 1461 * be stored. 1462 * @param size Destination address space area size. 1463 * 1464 * @return Non-zero on success, zero on failure. 1465 */ 1466 int async_share_in_receive(ipc_callid_t *callid, size_t *size) 1467 { 1468 ipc_call_t data; 1469 1473 1470 assert(callid); 1474 1471 assert(size); 1475 1476 ipc_call_t data; 1472 1477 1473 *callid = async_get_call(&data); 1478 1479 1474 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN) 1480 return false; 1481 1475 return 0; 1482 1476 *size = (size_t) IPC_GET_ARG2(data); 1483 return true;1477 return 1; 1484 1478 } 1485 1479 1486 1480 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework. 1487 1481 * 1488 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 1489 * calls so that the user doesn't have to remember the meaning of each IPC 1490 * argument. 1491 * 1492 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1493 * @param src Source address space base. 1494 * @param flags Flags to be used for sharing. Bits can be only cleared. 1495 * 1496 * @return Zero on success or a value from @ref errno.h on failure. 1497 * 1498 */ 1499 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 1482 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1483 * so that the user doesn't have to remember the meaning of each IPC argument. 1484 * 1485 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1486 * @param src Source address space base. 1487 * @param flags Flags to be used for sharing. Bits can be only cleared. 1488 * 1489 * @return Zero on success or a value from @ref errno.h on failure. 1490 */ 1491 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags) 1500 1492 { 1501 1493 return ipc_share_in_finalize(callid, src, flags); 1502 1494 } 1503 1495 1504 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework. 1505 * 1506 * @param phoneid Phone that will be used to contact the receiving side. 1507 * @param src Source address space area base address. 1508 * @param flags Flags to be used for sharing. Bits can be only cleared. 1509 * 1510 * @return Zero on success or a negative error code from errno.h. 1511 * 1512 */ 1513 int async_share_out_start(int phoneid, void *src, unsigned int flags) 1496 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework. 1497 * 1498 * @param phoneid Phone that will be used to contact the receiving side. 1499 * @param src Source address space area base address. 1500 * @param flags Flags to be used for sharing. Bits can be only cleared. 1501 * 1502 * @return Zero on success or a negative error code from errno.h. 1503 */ 1504 int async_share_out_start(int phoneid, void *src, int flags) 1514 1505 { 1515 1506 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, … … 1519 1510 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework. 1520 1511 * 1521 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT 1522 * calls so that the user doesn't have to remember the meaning of each IPC 1523 * argument. 1512 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls 1513 * so that the user doesn't have to remember the meaning of each IPC argument. 1524 1514 * 1525 1515 * So far, this wrapper is to be used from within a connection fibril. 1526 1516 * 1527 * @param callid Storage for the hash of the IPC_M_SHARE_OUT call. 1528 * @param size Storage for the source address space area size. 1529 * @param flags Storage for the sharing flags. 1530 * 1531 * @return True on success, false on failure. 1532 * 1533 */ 1534 bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags) 1535 { 1517 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will 1518 * be stored. 1519 * @param size Storage where the source address space area size will be 1520 * stored. 1521 * @param flags Storage where the sharing flags will be stored. 1522 * 1523 * @return Non-zero on success, zero on failure. 1524 */ 1525 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags) 1526 { 1527 ipc_call_t data; 1528 1536 1529 assert(callid); 1537 1530 assert(size); 1538 1531 assert(flags); 1539 1540 ipc_call_t data; 1532 1541 1533 *callid = async_get_call(&data); 1542 1543 1534 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT) 1544 return false; 1545 1535 return 0; 1546 1536 *size = (size_t) IPC_GET_ARG2(data); 1547 *flags = ( unsignedint) IPC_GET_ARG3(data);1548 return true;1537 *flags = (int) IPC_GET_ARG3(data); 1538 return 1; 1549 1539 } 1550 1540 1551 1541 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework. 1552 1542 * 1553 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT 1554 * calls so that the user doesn't have to remember the meaning of each IPC 1555 * argument. 1556 * 1557 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1558 * @param dst Destination address space area base address. 1559 * 1560 * @return Zero on success or a value from @ref errno.h on failure. 1561 * 1543 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 1544 * so that the user doesn't have to remember the meaning of each IPC argument. 1545 * 1546 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1547 * @param dst Destination address space area base address. 1548 * 1549 * @return Zero on success or a value from @ref errno.h on failure. 1562 1550 */ 1563 1551 int async_share_out_finalize(ipc_callid_t callid, void *dst) … … 1566 1554 } 1567 1555 1568 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1569 * 1570 * @param phoneid Phone that will be used to contact the receiving side.1571 * @param dst Address of the beginning of the destination buffer.1572 * @param size Sizeof the destination buffer.1573 * 1574 * @return Zero on success or a negative error code from errno.h.1575 * 1556 1557 /** Wrapper for making IPC_M_DATA_READ calls using the async framework. 1558 * 1559 * @param phoneid Phone that will be used to contact the receiving side. 1560 * @param dst Address of the beginning of the destination buffer. 1561 * @param size Size of the destination buffer. 1562 * 1563 * @return Zero on success or a negative error code from errno.h. 1576 1564 */ 1577 1565 int async_data_read_start(int phoneid, void *dst, size_t size) … … 1583 1571 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework. 1584 1572 * 1585 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ 1586 * calls so that the user doesn't have to remember the meaning of each IPC 1587 * argument. 1573 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 1574 * so that the user doesn't have to remember the meaning of each IPC argument. 1588 1575 * 1589 1576 * So far, this wrapper is to be used from within a connection fibril. 1590 1577 * 1591 * @param callid Storage for the hash of the IPC_M_DATA_READ. 1592 * @param size Storage for the maximum size. Can be NULL. 1593 * 1594 * @return True on success, false on failure. 1595 * 1596 */ 1597 bool async_data_read_receive(ipc_callid_t *callid, size_t *size) 1598 { 1578 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 1579 * be stored. 1580 * @param size Storage where the maximum size will be stored. Can be 1581 * NULL. 1582 * 1583 * @return Non-zero on success, zero on failure. 1584 */ 1585 int async_data_read_receive(ipc_callid_t *callid, size_t *size) 1586 { 1587 ipc_call_t data; 1588 1599 1589 assert(callid); 1600 1601 ipc_call_t data; 1590 1602 1591 *callid = async_get_call(&data); 1603 1604 1592 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ) 1605 return false; 1606 1593 return 0; 1607 1594 if (size) 1608 1595 *size = (size_t) IPC_GET_ARG2(data); 1609 1610 return true; 1596 return 1; 1611 1597 } 1612 1598 1613 1599 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework. 1614 1600 * 1615 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 1616 * calls so that the user doesn't have to remember the meaning of each IPC 1617 * argument. 1618 * 1619 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1620 * @param src Source address for the IPC_M_DATA_READ call. 1621 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1622 * the maximum size announced by the sender. 1623 * 1624 * @return Zero on success or a value from @ref errno.h on failure. 1625 * 1601 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1602 * so that the user doesn't have to remember the meaning of each IPC argument. 1603 * 1604 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1605 * @param src Source address for the IPC_M_DATA_READ call. 1606 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1607 * the maximum size announced by the sender. 1608 * 1609 * @return Zero on success or a value from @ref errno.h on failure. 1626 1610 */ 1627 1611 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) … … 1663 1647 } 1664 1648 1665 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.1649 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1666 1650 * 1667 1651 * @param phoneid Phone that will be used to contact the receiving side. … … 1680 1664 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework. 1681 1665 * 1682 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE 1683 * calls so that the user doesn't have to remember the meaning of each IPC 1684 * argument. 1666 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls 1667 * so that the user doesn't have to remember the meaning of each IPC argument. 1685 1668 * 1686 1669 * So far, this wrapper is to be used from within a connection fibril. 1687 1670 * 1688 * @param callid Storage for the hash of the IPC_M_DATA_WRITE. 1689 * @param size Storage for the suggested size. May be NULL. 1690 * 1691 * @return True on success, false on failure. 1692 * 1693 */ 1694 bool async_data_write_receive(ipc_callid_t *callid, size_t *size) 1695 { 1671 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1672 * be stored. 1673 * @param size Storage where the suggested size will be stored. May be 1674 * NULL 1675 * 1676 * @return Non-zero on success, zero on failure. 1677 * 1678 */ 1679 int async_data_write_receive(ipc_callid_t *callid, size_t *size) 1680 { 1681 ipc_call_t data; 1682 1696 1683 assert(callid); 1697 1684 1698 ipc_call_t data;1699 1685 *callid = async_get_call(&data); 1700 1701 1686 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE) 1702 return false;1687 return 0; 1703 1688 1704 1689 if (size) 1705 1690 *size = (size_t) IPC_GET_ARG2(data); 1706 1691 1707 return true;1692 return 1; 1708 1693 } 1709 1694 1710 1695 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework. 1711 1696 * 1712 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE 1713 * calls so that the user doesn't have to remember the meaning of each IPC 1714 * argument. 1697 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 1698 * so that the user doesn't have to remember the meaning of each IPC argument. 1715 1699 * 1716 1700 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. … … 1808 1792 * 1809 1793 */ 1810 void async_data_write_void( sysarg_t retval)1794 void async_data_write_void(const int retval) 1811 1795 { 1812 1796 ipc_callid_t callid; -
uspace/lib/c/generic/async_sess.c
r197ef43 r6aef742 105 105 #include <errno.h> 106 106 #include <assert.h> 107 #include "private/async_sess.h"108 107 109 108 /** An inactive open connection. */ … … 138 137 * 139 138 * Needs to be called prior to any other interface in this file. 140 * 141 */ 142 void __async_sess_init(void) 139 */ 140 void _async_sess_init(void) 143 141 { 144 142 fibril_mutex_initialize(&async_sess_mutex); -
uspace/lib/c/generic/fibril_synch.c
r197ef43 r6aef742 105 105 106 106 if (fibril_get_sercount() != 0) 107 abort();107 core(); 108 108 109 109 futex_down(&async_futex); … … 198 198 199 199 if (fibril_get_sercount() != 0) 200 abort();200 core(); 201 201 202 202 futex_down(&async_futex); … … 226 226 227 227 if (fibril_get_sercount() != 0) 228 abort();228 core(); 229 229 230 230 futex_down(&async_futex); -
uspace/lib/c/generic/io/io.c
r197ef43 r6aef742 46 46 #include <ipc/devmap.h> 47 47 #include <adt/list.h> 48 #include "../private/io.h"49 48 50 49 static void _ffillbuf(FILE *stream); -
uspace/lib/c/generic/ipc.c
r197ef43 r6aef742 49 49 50 50 /** 51 * Structures of this type are used for keeping track 52 * of sent asynchronous callsand queing unsent calls.51 * Structures of this type are used for keeping track of sent asynchronous calls 52 * and queing unsent calls. 53 53 */ 54 54 typedef struct { 55 55 link_t list; 56 56 57 57 ipc_async_callback_t callback; 58 58 void *private; 59 60 59 union { 61 60 ipc_callid_t callid; … … 65 64 } msg; 66 65 } u; 67 68 /** Fibril waiting for sending this call. */ 69 fid_t fid; 66 fid_t fid; /**< Fibril waiting for sending this call. */ 70 67 } async_call_t; 71 68 … … 74 71 /** List of asynchronous calls that were not accepted by kernel. 75 72 * 76 * Protected by async_futex, because if the call is not accepted 77 * by the kernel, the async framework is used automatically. 78 * 73 * It is protected by async_futex, because if the call cannot be sent into the 74 * kernel, the async framework is used automatically. 79 75 */ 80 76 LIST_INITIALIZE(queued_calls); … … 82 78 static atomic_t ipc_futex = FUTEX_INITIALIZER; 83 79 84 /** Fast synchronous call.85 * 86 * Only three payload arguments can be passed using this function. However, 87 * this function is faster than the generic ipc_call_sync_slow() because88 * the payloadis passed directly in registers.89 * 90 * @param phoneid 91 * @param method 92 * @param arg1 93 * @param arg2 94 * @param arg3 95 * @param result1 96 * @param result2 97 * @param result3 98 * @param result4 99 * @param result5 100 * 101 * @return Negative values representing IPC errors.102 * @return Otherwise the RETVAL of the answer.103 * 104 */ 105 i nt ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,106 sysarg_t arg 2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,107 sysarg_t *result 3, sysarg_t *result4, sysarg_t *result5)80 /** Make a fast synchronous call. 81 * 82 * Only three payload arguments can be passed using this function. However, this 83 * function is faster than the generic ipc_call_sync_slow() because the payload 84 * is passed directly in registers. 85 * 86 * @param phoneid Phone handle for the call. 87 * @param method Requested method. 88 * @param arg1 Service-defined payload argument. 89 * @param arg2 Service-defined payload argument. 90 * @param arg3 Service-defined payload argument. 91 * @param result1 If non-NULL, the return ARG1 will be stored there. 92 * @param result2 If non-NULL, the return ARG2 will be stored there. 93 * @param result3 If non-NULL, the return ARG3 will be stored there. 94 * @param result4 If non-NULL, the return ARG4 will be stored there. 95 * @param result5 If non-NULL, the return ARG5 will be stored there. 96 * 97 * @return Negative values represent errors returned by IPC. 98 * Otherwise the RETVAL of the answer is returned. 99 */ 100 int 101 ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1, sysarg_t arg2, 102 sysarg_t arg3, sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, 103 sysarg_t *result4, sysarg_t *result5) 108 104 { 109 105 ipc_call_t resdata; 110 int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1, 106 int callres; 107 108 callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1, 111 109 arg2, arg3, (sysarg_t) &resdata); 112 110 if (callres) 113 111 return callres; 114 115 112 if (result1) 116 113 *result1 = IPC_GET_ARG1(resdata); … … 123 120 if (result5) 124 121 *result5 = IPC_GET_ARG5(resdata); 125 122 126 123 return IPC_GET_RETVAL(resdata); 127 124 } 128 125 129 /** Synchronous call transmitting 5 arguments of payload.126 /** Make a synchronous call transmitting 5 arguments of payload. 130 127 * 131 128 * @param phoneid Phone handle for the call. … … 142 139 * @param result5 If non-NULL, storage for the fifth return argument. 143 140 * 144 * @return Negative value s representing IPC errors.145 * @returnOtherwise the RETVAL of the answer.146 * 147 */ 148 int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,149 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,150 sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,151 sysarg_t *result 5)141 * @return Negative value means IPC error. 142 * Otherwise the RETVAL of the answer. 143 * 144 */ 145 int 146 ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 147 sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *result1, 148 sysarg_t *result2, sysarg_t *result3, sysarg_t *result4, sysarg_t *result5) 152 149 { 153 150 ipc_call_t data; … … 179 176 } 180 177 181 /** S end asynchronous message via syscall.178 /** Syscall to send asynchronous message. 182 179 * 183 180 * @param phoneid Phone handle for the call. … … 187 184 * 188 185 */ 189 static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)186 static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data) 190 187 { 191 188 return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data); 192 189 } 193 190 194 /** Prolog for ipc_call_async_*() functions. 195 * 196 * @param private Argument for the answer/error callback. 197 * @param callback Answer/error callback. 198 * 199 * @return New, partially initialized async_call structure or NULL. 200 * 191 /** Prolog to ipc_call_async_*() functions. 192 * 193 * @param private Argument for the answer/error callback. 194 * @param callback Answer/error callback. 195 * 196 * @return New, partially initialized async_call structure or NULL. 201 197 */ 202 198 static inline async_call_t *ipc_prepare_async(void *private, 203 199 ipc_async_callback_t callback) 204 200 { 205 async_call_t *call = 206 (async_call_t *) malloc(sizeof(async_call_t)); 201 async_call_t *call; 202 203 call = malloc(sizeof(*call)); 207 204 if (!call) { 208 205 if (callback) 209 206 callback(private, ENOMEM, NULL); 210 211 207 return NULL; 212 208 } 213 214 209 call->callback = callback; 215 210 call->private = private; 216 211 217 212 return call; 218 213 } 219 214 220 /** Epilog for ipc_call_async_*() functions. 221 * 222 * @param callid Value returned by the SYS_IPC_CALL_ASYNC_* syscall. 223 * @param phoneid Phone handle through which the call was made. 224 * @param call Structure returned by ipc_prepare_async(). 225 * @param can_preempt If true, the current fibril can be preempted 226 * in this call. 227 * 215 /** Epilogue of ipc_call_async_*() functions. 216 * 217 * @param callid Value returned by the SYS_IPC_CALL_ASYNC_* syscall. 218 * @param phoneid Phone handle through which the call was made. 219 * @param call async_call structure returned by ipc_prepare_async(). 220 * @param can_preempt If non-zero, the current fibril can be preempted in this 221 * call. 228 222 */ 229 223 static inline void ipc_finish_async(ipc_callid_t callid, int phoneid, 230 async_call_t *call, bool can_preempt) 231 { 232 if (!call) { 233 /* Nothing to do regardless if failed or not */ 224 async_call_t *call, int can_preempt) 225 { 226 if (!call) { /* Nothing to do regardless if failed or not */ 234 227 futex_up(&ipc_futex); 235 228 return; 236 229 } 237 230 238 231 if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { 239 232 futex_up(&ipc_futex); 240 241 233 /* Call asynchronous handler with error code */ 242 234 if (call->callback) 243 235 call->callback(call->private, ENOENT, NULL); 244 245 236 free(call); 246 237 return; 247 238 } 248 239 249 240 if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) { 250 241 futex_up(&ipc_futex); 251 242 252 243 call->u.msg.phoneid = phoneid; 253 244 254 245 futex_down(&async_futex); 255 246 list_append(&call->list, &queued_calls); 256 247 257 248 if (can_preempt) { 258 249 call->fid = fibril_get_id(); … … 263 254 futex_up(&async_futex); 264 255 } 265 266 256 return; 267 257 } 268 269 258 call->u.callid = callid; 270 271 259 /* Add call to the list of dispatched calls */ 272 260 list_append(&call->list, &dispatched_calls); 273 261 futex_up(&ipc_futex); 274 } 275 276 /** Fast asynchronous call. 262 263 } 264 265 /** Make a fast asynchronous call. 277 266 * 278 267 * This function can only handle four arguments of payload. It is, however, … … 280 269 * 281 270 * Note that this function is a void function. 282 * 283 * During normal operation, answering this call will trigger the callback. 284 * In case of fatal error, the callback handler is called with the proper 285 * error code. If the call cannot be temporarily made, it is queued. 271 * During normal opertation, answering this call will trigger the callback. 272 * In case of fatal error, call the callback handler with the proper error code. 273 * If the call cannot be temporarily made, queue it. 286 274 * 287 275 * @param phoneid Phone handle for the call. … … 293 281 * @param private Argument to be passed to the answer/error callback. 294 282 * @param callback Answer or error callback. 295 * @param can_preempt If true, the current fibril will be preempted in283 * @param can_preempt If non-zero, the current fibril will be preempted in 296 284 * case the kernel temporarily refuses to accept more 297 285 * asynchronous calls. … … 300 288 void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1, 301 289 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private, 302 ipc_async_callback_t callback, boolcan_preempt)290 ipc_async_callback_t callback, int can_preempt) 303 291 { 304 292 async_call_t *call = NULL; … … 311 299 312 300 /* 313 * We need to make sure that we get callid 314 * before another threadaccesses the queue again.301 * We need to make sure that we get callid before another thread 302 * accesses the queue again. 315 303 */ 316 317 304 futex_down(&ipc_futex); 318 305 ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, … … 325 312 return; 326 313 } 327 328 314 IPC_SET_IMETHOD(call->u.msg.data, imethod); 329 315 IPC_SET_ARG1(call->u.msg.data, arg1); … … 331 317 IPC_SET_ARG3(call->u.msg.data, arg3); 332 318 IPC_SET_ARG4(call->u.msg.data, arg4); 333 334 319 /* 335 320 * To achieve deterministic behavior, we always zero out the 336 321 * arguments that are beyond the limits of the fast version. 337 322 */ 338 339 323 IPC_SET_ARG5(call->u.msg.data, 0); 340 324 } 341 342 325 ipc_finish_async(callid, phoneid, call, can_preempt); 343 326 } 344 327 345 /** Asynchronous call transmitting the entire payload.328 /** Make an asynchronous call transmitting the entire payload. 346 329 * 347 330 * Note that this function is a void function. 348 * 349 * During normal operation, answering this call will trigger the callback. 350 * In case of fatal error, the callback handler is called with the proper 351 * error code. If the call cannot be temporarily made, it is queued. 331 * During normal opertation, answering this call will trigger the callback. 332 * In case of fatal error, call the callback handler with the proper error code. 333 * If the call cannot be temporarily made, queue it. 352 334 * 353 335 * @param phoneid Phone handle for the call. … … 360 342 * @param private Argument to be passed to the answer/error callback. 361 343 * @param callback Answer or error callback. 362 * @param can_preempt If true, the current fibril will be preempted in344 * @param can_preempt If non-zero, the current fibril will be preempted in 363 345 * case the kernel temporarily refuses to accept more 364 346 * asynchronous calls. … … 367 349 void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, 368 350 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private, 369 ipc_async_callback_t callback, bool can_preempt) 370 { 371 async_call_t *call = ipc_prepare_async(private, callback); 351 ipc_async_callback_t callback, int can_preempt) 352 { 353 async_call_t *call; 354 ipc_callid_t callid; 355 356 call = ipc_prepare_async(private, callback); 372 357 if (!call) 373 358 return; 374 359 375 360 IPC_SET_IMETHOD(call->u.msg.data, imethod); 376 361 IPC_SET_ARG1(call->u.msg.data, arg1); … … 379 364 IPC_SET_ARG4(call->u.msg.data, arg4); 380 365 IPC_SET_ARG5(call->u.msg.data, arg5); 381 382 366 /* 383 * We need to make sure that we get callid 384 * before another threadaccesses the queue again.367 * We need to make sure that we get callid before another thread 368 * accesses the queue again. 385 369 */ 386 387 370 futex_down(&ipc_futex); 388 ipc_callid_t callid = 389 ipc_call_async_internal(phoneid, &call->u.msg.data); 390 371 callid = _ipc_call_async(phoneid, &call->u.msg.data); 372 391 373 ipc_finish_async(callid, phoneid, call, can_preempt); 392 374 } 393 375 394 /** Answer received call (fast version). 376 377 /** Answer a received call - fast version. 395 378 * 396 379 * The fast answer makes use of passing retval and first four arguments in 397 380 * registers. If you need to return more, use the ipc_answer_slow() instead. 398 381 * 399 * @param callid Hash of the call being answered. 400 * @param retval Return value. 401 * @param arg1 First return argument. 402 * @param arg2 Second return argument. 403 * @param arg3 Third return argument. 404 * @param arg4 Fourth return argument. 405 * 406 * @return Zero on success. 407 * @return Value from @ref errno.h on failure. 408 * 382 * @param callid Hash of the call being answered. 383 * @param retval Return value. 384 * @param arg1 First return argument. 385 * @param arg2 Second return argument. 386 * @param arg3 Third return argument. 387 * @param arg4 Fourth return argument. 388 * 389 * @return Zero on success or a value from @ref errno.h on failure. 409 390 */ 410 391 sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, … … 415 396 } 416 397 417 /** Answer received call (entire payload). 418 * 419 * @param callid Hash of the call being answered. 420 * @param retval Return value. 421 * @param arg1 First return argument. 422 * @param arg2 Second return argument. 423 * @param arg3 Third return argument. 424 * @param arg4 Fourth return argument. 425 * @param arg5 Fifth return argument. 426 * 427 * @return Zero on success. 428 * @return Value from @ref errno.h on failure. 429 * 398 /** Answer a received call - slow full version. 399 * 400 * @param callid Hash of the call being answered. 401 * @param retval Return value. 402 * @param arg1 First return argument. 403 * @param arg2 Second return argument. 404 * @param arg3 Third return argument. 405 * @param arg4 Fourth return argument. 406 * @param arg5 Fifth return argument. 407 * 408 * @return Zero on success or a value from @ref errno.h on failure. 430 409 */ 431 410 sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, … … 433 412 { 434 413 ipc_call_t data; 435 414 436 415 IPC_SET_RETVAL(data, retval); 437 416 IPC_SET_ARG1(data, arg1); … … 440 419 IPC_SET_ARG4(data, arg4); 441 420 IPC_SET_ARG5(data, arg5); 442 421 443 422 return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data); 444 423 } 445 424 446 /** Try to dispatch queued calls from the async queue. 447 * 448 */ 449 static void dispatch_queued_calls(void) 450 { 425 426 /** Try to dispatch queued calls from the async queue. */ 427 static void try_dispatch_queued_calls(void) 428 { 429 async_call_t *call; 430 ipc_callid_t callid; 431 451 432 /** @todo 452 * Integrate intelligently ipc_futex so that it is locked during453 * ipc_call_async_*() until it is added to dispatched_calls.433 * Integrate intelligently ipc_futex, so that it is locked during 434 * ipc_call_async_*(), until it is added to dispatched_calls. 454 435 */ 455 456 436 futex_down(&async_futex); 457 458 437 while (!list_empty(&queued_calls)) { 459 async_call_t *call = 460 list_get_instance(queued_calls.next, async_call_t, list); 461 ipc_callid_t callid = 462 ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data); 463 464 if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) 438 call = list_get_instance(queued_calls.next, async_call_t, list); 439 callid = _ipc_call_async(call->u.msg.phoneid, 440 &call->u.msg.data); 441 if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) { 465 442 break; 466 443 } 467 444 list_remove(&call->list); 468 445 469 446 futex_up(&async_futex); 470 471 447 if (call->fid) 472 448 fibril_add_ready(call->fid); … … 475 451 if (call->callback) 476 452 call->callback(call->private, ENOENT, NULL); 477 478 453 free(call); 479 454 } else { 480 455 call->u.callid = callid; 481 482 456 futex_down(&ipc_futex); 483 457 list_append(&call->list, &dispatched_calls); 484 458 futex_up(&ipc_futex); 485 459 } 486 487 460 futex_down(&async_futex); 488 461 } 489 490 462 futex_up(&async_futex); 491 463 } 492 464 493 /** Handle received answer.465 /** Handle a received answer. 494 466 * 495 467 * Find the hash of the answer and call the answer callback. 496 468 * 497 * The answer has the same hash as the request OR'ed with 498 * the IPC_CALLID_ANSWERED bit. 499 * 500 * @todo Use hash table. 501 * 502 * @param callid Hash of the received answer. 503 * @param data Call data of the answer. 504 * 469 * @todo Make it use hash table. 470 * 471 * @param callid Hash of the received answer. 472 * The answer has the same hash as the request OR'ed with 473 * the IPC_CALLID_ANSWERED bit. 474 * @param data Call data of the answer. 505 475 */ 506 476 static void handle_answer(ipc_callid_t callid, ipc_call_t *data) 507 477 { 478 link_t *item; 479 async_call_t *call; 480 508 481 callid &= ~IPC_CALLID_ANSWERED; 509 482 510 483 futex_down(&ipc_futex); 511 512 link_t *item;513 484 for (item = dispatched_calls.next; item != &dispatched_calls; 514 485 item = item->next) { 515 async_call_t *call = 516 list_get_instance(item, async_call_t, list); 517 486 call = list_get_instance(item, async_call_t, list); 518 487 if (call->u.callid == callid) { 519 488 list_remove(&call->list); 520 521 489 futex_up(&ipc_futex); 522 523 490 if (call->callback) 524 call->callback(call->private, 491 call->callback(call->private, 525 492 IPC_GET_RETVAL(*data), data); 526 527 493 free(call); 528 494 return; 529 495 } 530 496 } 531 532 497 futex_up(&ipc_futex); 533 498 } 534 499 535 /** Wait for first IPC call to come. 536 * 537 * @param call Incoming call storage.538 * @param usec Timeout in microseconds539 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).540 * 541 * @return Hash of the call. Note that certain bits have special542 * meaning: IPC_CALLID_ANSWERED is set in an answer543 * and IPC_CALLID_NOTIFICATION is used for notifications.544 * 545 * /546 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec, 547 unsignedint flags)548 { 549 ipc_callid_t callid =550 __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags); 551 500 501 /** Wait for a first call to come. 502 * 503 * @param call Storage where the incoming call data will be stored. 504 * @param usec Timeout in microseconds 505 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking). 506 * 507 * @return Hash of the call. Note that certain bits have special 508 * meaning. IPC_CALLID_ANSWERED will be set in an answer 509 * and IPC_CALLID_NOTIFICATION is used for notifications. 510 * 511 */ 512 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags) 513 { 514 ipc_callid_t callid; 515 516 callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags); 552 517 /* Handle received answers */ 553 518 if (callid & IPC_CALLID_ANSWERED) { 554 519 handle_answer(callid, call); 555 dispatch_queued_calls();520 try_dispatch_queued_calls(); 556 521 } 557 522 558 523 return callid; 559 524 } 560 525 561 /** Interrupt one thread of this task from waiting for IPC. 562 * 563 */ 564 void ipc_poke(void) 565 { 566 __SYSCALL0(SYS_IPC_POKE); 567 } 568 569 /** Wait for first IPC call to come. 570 * 571 * Only requests are returned, answers are processed internally. 572 * 573 * @param call Incoming call storage. 574 * @param usec Timeout in microseconds 575 * 576 * @return Hash of the call. 577 * 578 */ 579 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec) 526 /** Wait some time for an IPC call. 527 * 528 * The call will return after an answer is received. 529 * 530 * @param call Storage where the incoming call data will be stored. 531 * @param usec Timeout in microseconds. 532 * 533 * @return Hash of the answer. 534 */ 535 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec) 580 536 { 581 537 ipc_callid_t callid; 582 538 583 539 do { 584 540 callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE); 585 541 } while (callid & IPC_CALLID_ANSWERED); 586 542 587 543 return callid; 588 544 } … … 590 546 /** Check if there is an IPC call waiting to be picked up. 591 547 * 592 * Only requests are returned, answers are processed internally. 593 * 594 * @param call Incoming call storage. 595 * 596 * @return Hash of the call. 597 * 548 * @param call Storage where the incoming call will be stored. 549 * @return Hash of the answer. 598 550 */ 599 551 ipc_callid_t ipc_trywait_for_call(ipc_call_t *call) 600 552 { 601 553 ipc_callid_t callid; 602 554 603 555 do { 604 556 callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT, 605 557 SYNCH_FLAGS_NON_BLOCKING); 606 558 } while (callid & IPC_CALLID_ANSWERED); 607 559 608 560 return callid; 609 561 } 610 562 611 /** Request callback connection. 612 * 613 * The @a taskhash and @a phonehash identifiers returned 614 * by the kernel can be used for connection tracking. 615 * 616 * @param phoneid Phone handle used for contacting the other side. 617 * @param arg1 User defined argument. 618 * @param arg2 User defined argument. 619 * @param arg3 User defined argument. 620 * @param taskhash Opaque identifier of the client task. 621 * @param phonehash Opaque identifier of the phone that will 622 * be used for incoming calls. 623 * 624 * @return Zero on success or a negative error code. 625 * 626 */ 627 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 563 /** Interrupt one thread of this task from waiting for IPC. */ 564 void ipc_poke(void) 565 { 566 __SYSCALL0(SYS_IPC_POKE); 567 } 568 569 /** Ask destination to do a callback connection. 570 * 571 * @param phoneid Phone handle used for contacting the other side. 572 * @param arg1 Service-defined argument. 573 * @param arg2 Service-defined argument. 574 * @param arg3 Service-defined argument. 575 * @param taskhash Storage where the kernel will store an opaque 576 * identifier of the client task. 577 * @param phonehash Storage where the kernel will store an opaque 578 * identifier of the phone that will be used for incoming 579 * calls. This identifier can be used for connection 580 * tracking. 581 * 582 * @return Zero on success or a negative error code. 583 */ 584 int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3, 628 585 sysarg_t *taskhash, sysarg_t *phonehash) 629 586 { … … 632 589 } 633 590 634 /** Request new connection. 635 * 636 * @param phoneid Phone handle used for contacting the other side. 637 * @param arg1 User defined argument. 638 * @param arg2 User defined argument. 639 * @param arg3 User defined argument. 640 * 641 * @return New phone handle on success or a negative error code. 642 * 643 */ 644 int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 591 /** Ask through phone for a new connection to some service. 592 * 593 * @param phoneid Phone handle used for contacting the other side. 594 * @param arg1 User defined argument. 595 * @param arg2 User defined argument. 596 * @param arg3 User defined argument. 597 * 598 * @return New phone handle on success or a negative error code. 599 */ 600 int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3) 645 601 { 646 602 sysarg_t newphid; 647 int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 603 int res; 604 605 res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 648 606 NULL, NULL, NULL, NULL, &newphid); 649 607 if (res) 650 608 return res; 651 652 609 return newphid; 653 610 } 654 611 655 /** Request new connection (blocking)612 /** Ask through phone for a new connection to some service. 656 613 * 657 614 * If the connection is not available at the moment, the 658 * call should block. This has to be, however, implemented 659 * on the server side. 660 * 661 * @param phoneid Phone handle used for contacting the other side. 662 * @param arg1 User defined argument. 663 * @param arg2 User defined argument. 664 * @param arg3 User defined argument. 665 * 666 * @return New phone handle on success or a negative error code. 667 * 668 */ 669 int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2, 670 sysarg_t arg3) 615 * call will block. 616 * 617 * @param phoneid Phone handle used for contacting the other side. 618 * @param arg1 User defined argument. 619 * @param arg2 User defined argument. 620 * @param arg3 User defined argument. 621 * 622 * @return New phone handle on success or a negative error code. 623 */ 624 int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3) 671 625 { 672 626 sysarg_t newphid; 673 int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 627 int res; 628 629 res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 674 630 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); 675 631 if (res) 676 632 return res; 677 678 633 return newphid; 679 634 } … … 681 636 /** Hang up a phone. 682 637 * 683 * @param phoneid Handle of the phone to be hung up. 684 * 685 * @return Zero on success or a negative error code. 686 * 638 * @param phoneid Handle of the phone to be hung up. 639 * 640 * @return Zero on success or a negative error code. 687 641 */ 688 642 int ipc_hangup(int phoneid) … … 692 646 693 647 /** Forward a received call to another destination. 694 *695 * For non-system methods, the old method, arg1 and arg2 are rewritten696 * by the new values. For system methods, the new method, arg1 and arg2697 * are written to the old arg1, arg2 and arg3, respectivelly. Calls with698 * immutable methods are forwarded verbatim.699 648 * 700 649 * @param callid Hash of the call to forward. … … 707 656 * @return Zero on success or an error code. 708 657 * 709 */ 710 int ipc_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod, 711 sysarg_t arg1, sysarg_t arg2, unsigned int mode) 658 * For non-system methods, the old method, arg1 and arg2 are rewritten by the 659 * new values. For system methods, the new method, arg1 and arg2 are written 660 * to the old arg1, arg2 and arg3, respectivelly. Calls with immutable 661 * methods are forwarded verbatim. 662 */ 663 int ipc_forward_fast(ipc_callid_t callid, int phoneid, int imethod, 664 sysarg_t arg1, sysarg_t arg2, int mode) 712 665 { 713 666 return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1, … … 715 668 } 716 669 717 int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod, 670 671 int ipc_forward_slow(ipc_callid_t callid, int phoneid, int imethod, 718 672 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 719 unsignedint mode)673 int mode) 720 674 { 721 675 ipc_call_t data; … … 728 682 IPC_SET_ARG5(data, arg5); 729 683 730 return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, 731 mode); 732 } 733 734 /** Wrapper for IPC_M_SHARE_IN calls. 735 * 736 * @param phoneid Phone that will be used to contact the receiving side. 737 * @param dst Destination address space area base. 738 * @param size Size of the destination address space area. 739 * @param arg User defined argument. 740 * @param flags Storage for received flags. Can be NULL. 741 * 742 * @return Zero on success or a negative error code from errno.h. 743 * 684 return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode); 685 } 686 687 /** Wrapper for making IPC_M_SHARE_IN calls. 688 * 689 * @param phoneid Phone that will be used to contact the receiving side. 690 * @param dst Destination address space area base. 691 * @param size Size of the destination address space area. 692 * @param arg User defined argument. 693 * @param flags Storage where the received flags will be stored. Can be 694 * NULL. 695 * 696 * @return Zero on success or a negative error code from errno.h. 744 697 */ 745 698 int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 746 unsignedint *flags)699 int *flags) 747 700 { 748 701 sysarg_t tmp_flags = 0; … … 751 704 752 705 if (flags) 753 *flags = (unsigned int)tmp_flags;706 *flags = tmp_flags; 754 707 755 708 return res; … … 758 711 /** Wrapper for answering the IPC_M_SHARE_IN calls. 759 712 * 760 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 761 * calls so that the user doesn't have to remember the meaning of each 762 * IPC argument. 763 * 764 * @param callid Hash of the IPC_M_DATA_READ call to answer. 765 * @param src Source address space base. 766 * @param flags Flags to be used for sharing. Bits can be only cleared. 767 * 768 * @return Zero on success or a value from @ref errno.h on failure. 769 * 770 */ 771 int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 713 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 714 * so that the user doesn't have to remember the meaning of each IPC argument. 715 * 716 * @param callid Hash of the IPC_M_DATA_READ call to answer. 717 * @param src Source address space base. 718 * @param flags Flags to be used for sharing. Bits can be only cleared. 719 * 720 * @return Zero on success or a value from @ref errno.h on failure. 721 */ 722 int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags) 772 723 { 773 724 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags); 774 725 } 775 726 776 /** Wrapper for IPC_M_SHARE_OUT calls. 777 * 778 * @param phoneid Phone that will be used to contact the receiving side. 779 * @param src Source address space area base address. 780 * @param flags Flags to be used for sharing. Bits can be only cleared. 781 * 782 * @return Zero on success or a negative error code from errno.h. 783 * 784 */ 785 int ipc_share_out_start(int phoneid, void *src, unsigned int flags) 727 /** Wrapper for making IPC_M_SHARE_OUT calls. 728 * 729 * @param phoneid Phone that will be used to contact the receiving side. 730 * @param src Source address space area base address. 731 * @param flags Flags to be used for sharing. Bits can be only cleared. 732 * 733 * @return Zero on success or a negative error code from errno.h. 734 */ 735 int ipc_share_out_start(int phoneid, void *src, int flags) 786 736 { 787 737 return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, … … 791 741 /** Wrapper for answering the IPC_M_SHARE_OUT calls. 792 742 * 793 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT 794 * calls so that the user doesn't have to remember the meaning of each 795 * IPC argument. 796 * 797 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 798 * @param dst Destination address space area base address. 799 * 800 * @return Zero on success or a value from @ref errno.h on failure. 801 * 743 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 744 * so that the user doesn't have to remember the meaning of each IPC argument. 745 * 746 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 747 * @param dst Destination address space area base address. 748 * 749 * @return Zero on success or a value from @ref errno.h on failure. 802 750 */ 803 751 int ipc_share_out_finalize(ipc_callid_t callid, void *dst) … … 806 754 } 807 755 808 /** Wrapper for IPC_M_DATA_READ calls. 809 * 810 * @param phoneid Phone that will be used to contact the receiving side.811 * @param dst Address of the beginning of the destination buffer.812 * @param size Sizeof the destination buffer.813 * 814 * @return Zero on success or a negative error code from errno.h.815 * 756 757 /** Wrapper for making IPC_M_DATA_READ calls. 758 * 759 * @param phoneid Phone that will be used to contact the receiving side. 760 * @param dst Address of the beginning of the destination buffer. 761 * @param size Size of the destination buffer. 762 * 763 * @return Zero on success or a negative error code from errno.h. 816 764 */ 817 765 int ipc_data_read_start(int phoneid, void *dst, size_t size) … … 823 771 /** Wrapper for answering the IPC_M_DATA_READ calls. 824 772 * 825 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 826 * calls so that the user doesn't have to remember the meaning of each 827 * IPC argument. 828 * 829 * @param callid Hash of the IPC_M_DATA_READ call to answer. 830 * @param src Source address for the IPC_M_DATA_READ call. 831 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 832 * the maximum size announced by the sender. 833 * 834 * @return Zero on success or a value from @ref errno.h on failure. 835 * 773 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 774 * so that the user doesn't have to remember the meaning of each IPC argument. 775 * 776 * @param callid Hash of the IPC_M_DATA_READ call to answer. 777 * @param src Source address for the IPC_M_DATA_READ call. 778 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 779 * the maximum size announced by the sender. 780 * 781 * @return Zero on success or a value from @ref errno.h on failure. 836 782 */ 837 783 int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) … … 840 786 } 841 787 842 /** Wrapper for IPC_M_DATA_WRITE calls. 843 * 844 * @param phoneid Phone that will be used to contact the receiving side. 845 * @param src Address of the beginning of the source buffer. 846 * @param size Size of the source buffer. 847 * 848 * @return Zero on success or a negative error code from errno.h. 849 * 788 /** Wrapper for making IPC_M_DATA_WRITE calls. 789 * 790 * @param phoneid Phone that will be used to contact the receiving side. 791 * @param src Address of the beginning of the source buffer. 792 * @param size Size of the source buffer. 793 * 794 * @return Zero on success or a negative error code from errno.h. 850 795 */ 851 796 int ipc_data_write_start(int phoneid, const void *src, size_t size) … … 857 802 /** Wrapper for answering the IPC_M_DATA_WRITE calls. 858 803 * 859 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE 860 * calls so that the user doesn't have to remember the meaning of each 861 * IPC argument. 862 * 863 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 864 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 865 * @param size Final size for the IPC_M_DATA_WRITE call. 866 * 867 * @return Zero on success or a value from @ref errno.h on failure. 868 * 804 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 805 * so that the user doesn't have to remember the meaning of each IPC argument. 806 * 807 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 808 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 809 * @param size Final size for the IPC_M_DATA_WRITE call. 810 * 811 * @return Zero on success or a value from @ref errno.h on failure. 869 812 */ 870 813 int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) -
uspace/lib/c/generic/libc.c
r197ef43 r6aef742 41 41 */ 42 42 43 #include <libc.h> 44 #include <stdlib.h> 43 #include <stdio.h> 44 #include <unistd.h> 45 #include <malloc.h> 45 46 #include <tls.h> 47 #include <thread.h> 46 48 #include <fibril.h> 47 #include <task.h> 49 #include <async.h> 50 #include <as.h> 48 51 #include <loader/pcb.h> 49 52 #include "private/libc.h" 50 #include "private/async.h"51 #include "private/async_sess.h"52 #include "private/malloc.h"53 #include "private/io.h"54 53 55 static bool env_setup = false; 54 void _exit(int status) 55 { 56 thread_exit(status); 57 } 56 58 57 59 void __main(void *pcb_ptr) 58 60 { 59 61 /* Initialize user task run-time environment */ 60 __ malloc_init();62 __heap_init(); 61 63 __async_init(); 62 __async_sess_init();63 64 64 fibril_t *fibril = fibril_setup(); 65 if (fibril == NULL)66 abort();67 68 65 __tcb_set(fibril->tcb); 69 66 … … 71 68 __pcb = (pcb_t *) pcb_ptr; 72 69 73 /* The basic run-time environment is setup */74 env_setup = true;75 76 70 int argc; 77 71 char **argv; 78 72 79 /* 80 * Get command line arguments and initialize 81 * standard input and output 82 */ 73 /* Get command line arguments and initialize 74 standard input and output */ 83 75 if (__pcb == NULL) { 84 76 argc = 0; … … 92 84 } 93 85 94 /* 95 * Run main() and set task return value 96 * according the result 97 */ 98 int retval = main(argc, argv); 99 exit(retval); 86 /* Run main() and set task return value 87 according the result */ 88 (void) task_retval(main(argc, argv)); 100 89 } 101 90 102 void exit(int status)91 void __exit(void) 103 92 { 104 if (env_setup) { 105 __stdio_done(); 106 task_retval(status); 107 fibril_teardown(__tcb_get()->fibril_data); 108 } 109 110 __SYSCALL1(SYS_TASK_EXIT, false); 111 112 /* Unreachable */ 113 while (1); 114 } 115 116 void abort(void) 117 { 118 __SYSCALL1(SYS_TASK_EXIT, true); 119 120 /* Unreachable */ 121 while (1); 93 __stdio_done(); 94 fibril_teardown(__tcb_get()->fibril_data); 95 _exit(0); 122 96 } 123 97 -
uspace/lib/c/generic/malloc.c
r197ef43 r6aef742 45 45 #include <futex.h> 46 46 #include <adt/gcdlcm.h> 47 #include "private/malloc.h"48 47 49 48 /* Magic used in heap headers. */ … … 216 215 /** Initialize the heap allocator 217 216 * 218 * Create initial heap memory area. This routine is 219 * only called from libc initialization, thus we do not 220 * take any locks. 221 * 222 */ 223 void __malloc_init(void) 224 { 225 if (!as_area_create((void *) &_heap, PAGE_SIZE, 226 AS_AREA_WRITE | AS_AREA_READ)) 227 abort(); 228 229 heap_pages = 1; 230 heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN); 231 heap_end = 232 (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN); 233 234 /* Make the entire area one large block. */ 235 block_init(heap_start, heap_end - heap_start, true); 217 * Find how much physical memory we have and create 218 * the heap management structures that mark the whole 219 * physical memory as a single free block. 220 * 221 */ 222 void __heap_init(void) 223 { 224 futex_down(&malloc_futex); 225 226 if (as_area_create((void *) &_heap, PAGE_SIZE, 227 AS_AREA_WRITE | AS_AREA_READ)) { 228 heap_pages = 1; 229 heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN); 230 heap_end = 231 (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN); 232 233 /* Make the entire area one large block. */ 234 block_init(heap_start, heap_end - heap_start, true); 235 } 236 237 futex_up(&malloc_futex); 236 238 } 237 239 -
uspace/lib/c/generic/private/async.h
r197ef43 r6aef742 79 79 } awaiter_t; 80 80 81 extern void __async_init(void);82 81 extern void async_insert_timeout(awaiter_t *); 83 82 -
uspace/lib/c/generic/private/libc.h
r197ef43 r6aef742 37 37 38 38 extern int main(int, char *[]); 39 extern void __main(void *) __attribute__((noreturn)); 39 extern void __main(void *); 40 extern void __exit(void); 40 41 41 42 #endif -
uspace/lib/c/generic/thread.c
r197ef43 r6aef742 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <thread.h> … … 41 41 #include <str.h> 42 42 #include <async.h> 43 #include "private/thread.h"44 43 45 44 #ifndef THREAD_INITIAL_STACK_PAGES_NO … … 51 50 * This function is called from __thread_entry() and is used 52 51 * to call the thread's implementing function and perform cleanup 53 * and exit when thread returns back. 52 * and exit when thread returns back. Do not call this function 53 * directly. 54 54 * 55 55 * @param uarg Pointer to userspace argument structure. 56 *57 56 */ 58 57 void __thread_main(uspace_arg_t *uarg) 59 58 { 60 fibril_t *fibril = fibril_setup(); 61 if (fibril == NULL) 62 thread_exit(0); 63 64 __tcb_set(fibril->tcb); 65 59 fibril_t *f; 60 61 f = fibril_setup(); 62 __tcb_set(f->tcb); 63 66 64 uarg->uspace_thread_function(uarg->uspace_thread_arg); 67 /* XXX: we cannot free the userspace stack while running on it 68 free(uarg->uspace_stack); 69 free(uarg); 70 */ 71 65 /* XXX: we cannot free the userspace stack while running on it */ 66 // free(uarg->uspace_stack); 67 // free(uarg); 68 72 69 /* If there is a manager, destroy it */ 73 70 async_destroy_manager(); 74 fibril_teardown(f ibril);75 71 fibril_teardown(f); 72 76 73 thread_exit(0); 77 74 } … … 130 127 * 131 128 * @param status Exit status. Currently not used. 132 *133 129 */ 134 130 void thread_exit(int status) 135 131 { 136 132 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status); 137 138 /* Unreachable */ 139 while (1); 133 for (;;) 134 ; 140 135 } 141 136 -
uspace/lib/c/include/async.h
r197ef43 r6aef742 57 57 extern atomic_t threads_in_ipc_wait; 58 58 59 #define async_manager() \ 60 fibril_switch(FIBRIL_TO_MANAGER) 61 62 #define async_get_call(data) \ 63 async_get_call_timeout(data, 0) 64 59 extern int __async_init(void); 65 60 extern ipc_callid_t async_get_call_timeout(ipc_call_t *, suseconds_t); 61 62 static inline ipc_callid_t async_get_call(ipc_call_t *data) 63 { 64 return async_get_call_timeout(data, 0); 65 } 66 67 static inline void async_manager(void) 68 { 69 fibril_switch(FIBRIL_TO_MANAGER); 70 } 66 71 67 72 /* … … 138 143 */ 139 144 140 extern int async_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t, 141 unsigned int); 142 extern int async_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t, 143 sysarg_t, sysarg_t, sysarg_t, unsigned int); 145 extern int async_forward_fast(ipc_callid_t, int, int, sysarg_t, sysarg_t, int); 146 extern int async_forward_slow(ipc_callid_t, int, int, sysarg_t, sysarg_t, 147 sysarg_t, sysarg_t, sysarg_t, int); 144 148 145 149 /* … … 302 306 async_share_in_start((phoneid), (dst), (size), (arg), (flags)) 303 307 304 extern int async_share_in_start(int, void *, size_t, sysarg_t, unsigned int *); 305 extern bool async_share_in_receive(ipc_callid_t *, size_t *); 306 extern int async_share_in_finalize(ipc_callid_t, void *, unsigned int); 307 308 extern int async_share_out_start(int, void *, unsigned int); 309 extern bool async_share_out_receive(ipc_callid_t *, size_t *, unsigned int *); 308 extern int async_share_in_start(int, void *, size_t, sysarg_t, int *); 309 extern int async_share_in_receive(ipc_callid_t *, size_t *); 310 extern int async_share_in_finalize(ipc_callid_t, void *, int ); 311 extern int async_share_out_start(int, void *, int); 312 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *); 310 313 extern int async_share_out_finalize(ipc_callid_t, void *); 311 314 … … 341 344 342 345 extern int async_data_read_start(int, void *, size_t); 343 extern boolasync_data_read_receive(ipc_callid_t *, size_t *);346 extern int async_data_read_receive(ipc_callid_t *, size_t *); 344 347 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); 345 348 … … 380 383 381 384 extern int async_data_write_start(int, const void *, size_t); 382 extern boolasync_data_write_receive(ipc_callid_t *, size_t *);385 extern int async_data_write_receive(ipc_callid_t *, size_t *); 383 386 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); 384 387 385 388 extern int async_data_write_accept(void **, const bool, const size_t, 386 389 const size_t, const size_t, size_t *); 387 extern void async_data_write_void( sysarg_t);390 extern void async_data_write_void(const int); 388 391 389 392 extern int async_data_write_forward_fast(int, sysarg_t, sysarg_t, sysarg_t, -
uspace/lib/c/include/async_sess.h
r197ef43 r6aef742 45 45 } async_sess_t; 46 46 47 extern void _async_sess_init(void); 47 48 extern void async_session_create(async_sess_t *, int, sysarg_t); 48 49 extern void async_session_destroy(async_sess_t *); -
uspace/lib/c/include/byteorder.h
r197ef43 r6aef742 80 80 #endif 81 81 82 #define htons(n) 83 #define htonl(n) 84 #define ntohs(n) 85 #define ntohl(n) 82 #define htons(n) host2uint16_t_be((n)) 83 #define htonl(n) host2uint32_t_be((n)) 84 #define ntohs(n) uint16_t_be2host((n)) 85 #define ntohl(n) uint32_t_be2host((n)) 86 86 87 87 static inline uint64_t uint64_t_byteorder_swap(uint64_t n) -
uspace/lib/c/include/err.h
r197ef43 r6aef742 39 39 40 40 #define errx(status, fmt, ...) \ 41 do{ \41 { \ 42 42 printf((fmt), ##__VA_ARGS__); \ 43 exit(status); \44 } while (0)43 _exit(status); \ 44 } 45 45 46 46 #endif -
uspace/lib/c/include/errno.h
r197ef43 r6aef742 39 39 #include <fibril.h> 40 40 41 extern int _errno; 42 41 43 #define errno _errno 42 43 extern int _errno;44 44 45 45 #define EMFILE (-18) … … 57 57 58 58 /** An API function is called while another blocking function is in progress. */ 59 #define EINPROGRESS 59 #define EINPROGRESS (-10036) 60 60 61 61 /** The socket identifier is not valid. */ 62 #define ENOTSOCK 62 #define ENOTSOCK (-10038) 63 63 64 64 /** The destination address required. */ 65 #define EDESTADDRREQ 65 #define EDESTADDRREQ (-10039) 66 66 67 67 /** Protocol is not supported. */ 68 #define EPROTONOSUPPORT 68 #define EPROTONOSUPPORT (-10043) 69 69 70 70 /** Socket type is not supported. */ 71 #define ESOCKTNOSUPPORT 71 #define ESOCKTNOSUPPORT (-10044) 72 72 73 73 /** Protocol family is not supported. */ 74 #define EPFNOSUPPORT 74 #define EPFNOSUPPORT (-10046) 75 75 76 76 /** Address family is not supported. */ 77 #define EAFNOSUPPORT 77 #define EAFNOSUPPORT (-10047) 78 78 79 79 /** Address is already in use. */ 80 #define EADDRINUSE 80 #define EADDRINUSE (-10048) 81 81 82 82 /** The socket is not connected or bound. */ 83 #define ENOTCONN 83 #define ENOTCONN (-10057) 84 84 85 85 /** The requested operation was not performed. Try again later. */ 86 #define EAGAIN 86 #define EAGAIN (-11002) 87 87 88 /** No data. */ 89 #define NO_DATA (-11004) 88 /** No data. 89 */ 90 #define NO_DATA (-11004) 90 91 91 92 #endif -
uspace/lib/c/include/ipc/ipc.h
r197ef43 r6aef742 53 53 * possible, the fast version is used. 54 54 */ 55 56 55 #define ipc_call_sync_0_0(phoneid, method) \ 57 56 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0) … … 183 182 sysarg_t *); 184 183 185 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); 184 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int); 185 extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t); 186 186 extern void ipc_poke(void); 187 187 188 #define ipc_wait_for_call(data) \ 189 ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT); 190 191 extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, sysarg_t); 188 static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data) 189 { 190 return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT); 191 } 192 192 193 extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *); 193 194 … … 198 199 * to m. 199 200 */ 200 201 201 #define ipc_answer_0(callid, retval) \ 202 202 ipc_answer_fast((callid), (retval), 0, 0, 0, 0) … … 223 223 * to m. 224 224 */ 225 226 225 #define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \ 227 226 ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ … … 249 248 250 249 extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 251 sysarg_t, void *, ipc_async_callback_t, bool);250 sysarg_t, void *, ipc_async_callback_t, int); 252 251 extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 253 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 254 255 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *, 256 sysarg_t *); 257 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t); 258 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t); 259 252 sysarg_t, sysarg_t, void *, ipc_async_callback_t, int); 253 254 extern int ipc_connect_to_me(int, int, int, int, sysarg_t *, sysarg_t *); 255 extern int ipc_connect_me_to(int, int, int, int); 256 extern int ipc_connect_me_to_blocking(int, int, int, int); 260 257 extern int ipc_hangup(int); 261 262 extern int ipc_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t, 263 unsigned int); 264 extern int ipc_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t, 265 sysarg_t, sysarg_t, sysarg_t, unsigned int); 258 extern int ipc_forward_fast(ipc_callid_t, int, int, sysarg_t, sysarg_t, int); 259 extern int ipc_forward_slow(ipc_callid_t, int, int, sysarg_t, sysarg_t, 260 sysarg_t, sysarg_t, sysarg_t, int); 266 261 267 262 /* 268 263 * User-friendly wrappers for ipc_share_in_start(). 269 264 */ 270 271 265 #define ipc_share_in_start_0_0(phoneid, dst, size) \ 272 266 ipc_share_in_start((phoneid), (dst), (size), 0, NULL) … … 278 272 ipc_share_in_start((phoneid), (dst), (size), (arg), (flags)) 279 273 280 extern int ipc_share_in_start(int, void *, size_t, sysarg_t, unsignedint *);281 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);282 extern int ipc_share_out_start(int, void *, unsignedint);274 extern int ipc_share_in_start(int, void *, size_t, sysarg_t, int *); 275 extern int ipc_share_in_finalize(ipc_callid_t, void *, int ); 276 extern int ipc_share_out_start(int, void *, int); 283 277 extern int ipc_share_out_finalize(ipc_callid_t, void *); 284 278 extern int ipc_data_read_start(int, void *, size_t); -
uspace/lib/c/include/loader/pcb.h
r197ef43 r6aef742 52 52 /** Program entry point. */ 53 53 entry_point_t entry; 54 54 55 55 /** Current working directory. */ 56 56 char *cwd; -
uspace/lib/c/include/malloc.h
r197ef43 r6aef742 38 38 #include <sys/types.h> 39 39 40 extern void __heap_init(void); 40 41 extern uintptr_t get_max_heap_addr(void); 41 42 -
uspace/lib/c/include/setjmp.h
r197ef43 r6aef742 41 41 42 42 extern int setjmp(jmp_buf env); 43 extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));43 extern void longjmp(jmp_buf env,int val) __attribute__((__noreturn__)); 44 44 45 45 #endif -
uspace/lib/c/include/stdlib.h
r197ef43 r6aef742 40 40 #include <stacktrace.h> 41 41 42 #define abort() \ 43 do { \ 44 stacktrace_print(); \ 45 _exit(1); \ 46 } while (0) 47 48 #define core() \ 49 *((int *) 0) = 0xbadbad; 50 51 #define exit(status) _exit((status)) 52 42 53 #define RAND_MAX 714025 43 44 #define rand() random()45 #define srand(seed) srandom(seed)46 54 47 55 extern long int random(void); 48 56 extern void srandom(unsigned int seed); 49 57 50 extern void abort(void) __attribute__((noreturn)); 58 static inline int rand(void) 59 { 60 return random(); 61 } 62 63 static inline void srand(unsigned int seed) 64 { 65 srandom(seed); 66 } 51 67 52 68 #endif -
uspace/lib/c/include/syscall.h
r197ef43 r6aef742 32 32 /** 33 33 * @file 34 * @brief 35 * 36 * 34 * @brief Syscall function declaration for architectures that don't 35 * inline syscalls or architectures that handle syscalls 36 * according to the number of arguments. 37 37 */ 38 38 … … 40 40 #define LIBC_SYSCALL_H_ 41 41 42 #ifndef 43 #error You cannot include this file directly 42 #ifndef LIBARCH_SYSCALL_GENERIC 43 #error "You can't include this file directly." 44 44 #endif 45 45 … … 47 47 #include <kernel/syscall/syscall.h> 48 48 49 #define __syscall0 50 #define __syscall1 51 #define __syscall2 52 #define __syscall3 53 #define __syscall4 54 #define __syscall5 55 #define __syscall6 49 #define __syscall0 __syscall 50 #define __syscall1 __syscall 51 #define __syscall2 __syscall 52 #define __syscall3 __syscall 53 #define __syscall4 __syscall 54 #define __syscall5 __syscall 55 #define __syscall6 __syscall 56 56 57 57 extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, -
uspace/lib/c/include/thread.h
r197ef43 r6aef742 36 36 #define LIBC_THREAD_H_ 37 37 38 #include <kernel/proc/uarg.h> 38 39 #include <libarch/thread.h> 39 40 #include <sys/types.h> … … 41 42 typedef uint64_t thread_id_t; 42 43 44 extern void __thread_entry(void); 45 extern void __thread_main(uspace_arg_t *); 46 43 47 extern int thread_create(void (*)(void *), void *, const char *, thread_id_t *); 44 extern void thread_exit(int) __attribute__ ((noreturn));48 extern void thread_exit(int) __attribute__ ((noreturn)); 45 49 extern void thread_detach(thread_id_t); 46 50 extern int thread_join(thread_id_t); -
uspace/lib/c/include/tls.h
r197ef43 r6aef742 57 57 extern void tls_free_variant_1(tcb_t *, size_t); 58 58 #endif 59 60 59 #ifdef CONFIG_TLS_VARIANT_2 61 60 extern tcb_t *tls_alloc_variant_2(void **, size_t); -
uspace/lib/c/include/unistd.h
r197ef43 r6aef742 41 41 42 42 #ifndef NULL 43 #define NULL 43 #define NULL ((void *) 0) 44 44 #endif 45 45 … … 74 74 extern int chdir(const char *); 75 75 76 extern void exit(int) __attribute__((noreturn));76 extern void _exit(int) __attribute__((noreturn)); 77 77 extern int usleep(useconds_t); 78 78 extern unsigned int sleep(unsigned int); -
uspace/lib/c/include/vfs/vfs.h
r197ef43 r6aef742 57 57 extern int unmount(const char *); 58 58 59 extern void __stdio_init(int filc, fdi_node_t *filv[]); 60 extern void __stdio_done(void); 61 59 62 extern int open_node(fdi_node_t *, int); 60 63 extern int fd_phone(int); -
uspace/srv/bd/ata_bd/ata_bd.c
r197ef43 r6aef742 265 265 sysarg_t method; 266 266 devmap_handle_t dh; 267 unsignedint flags;267 int flags; 268 268 int retval; 269 269 uint64_t ba; -
uspace/srv/bd/file_bd/file_bd.c
r197ef43 r6aef742 177 177 sysarg_t method; 178 178 size_t comm_size; 179 unsignedint flags;179 int flags; 180 180 int retval; 181 181 uint64_t ba; -
uspace/srv/bd/gxe_bd/gxe_bd.c
r197ef43 r6aef742 160 160 sysarg_t method; 161 161 devmap_handle_t dh; 162 unsignedint flags;162 int flags; 163 163 int retval; 164 164 uint64_t ba; -
uspace/srv/bd/part/guid_part/guid_part.c
r197ef43 r6aef742 315 315 sysarg_t method; 316 316 devmap_handle_t dh; 317 unsignedint flags;317 int flags; 318 318 int retval; 319 319 aoff64_t ba; -
uspace/srv/bd/part/mbr_part/mbr_part.c
r197ef43 r6aef742 393 393 sysarg_t method; 394 394 devmap_handle_t dh; 395 unsignedint flags;395 int flags; 396 396 int retval; 397 397 uint64_t ba; -
uspace/srv/bd/rd/rd.c
r197ef43 r6aef742 102 102 * Now we wait for the client to send us its communication as_area. 103 103 */ 104 unsignedint flags;104 int flags; 105 105 if (async_share_out_receive(&callid, &comm_size, &flags)) { 106 106 fs_va = as_get_mappable_page(comm_size);
Note:
See TracChangeset
for help on using the changeset viewer.