Changeset 9db9b10 in mainline
- Timestamp:
- 2009-06-03T19:16:07Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 937aeee
- Parents:
- e77994dd
- Location:
- uspace/lib/libc
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/async.c
re77994dd r9db9b10 179 179 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); 180 180 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); 181 static void default_pending(void); 181 182 182 183 /** … … 191 192 static async_client_conn_t interrupt_received = default_interrupt_received; 192 193 194 /** 195 * Pointer to a fibril function that will be used to handle pending 196 * operations. 197 */ 198 static async_pending_t pending = default_pending; 193 199 194 200 static hash_table_t conn_hash_table; 195 201 static LIST_INITIALIZE(timeout_list); 196 197 202 198 203 #define CONN_HASH_TABLE_CHAINS 32 … … 371 376 372 377 fid_t fid = fibril_create(notification_fibril, msg); 378 fibril_add_ready(fid); 379 380 futex_up(&async_futex); 381 return true; 382 } 383 384 /** Pending fibril. 385 * 386 * After each call the pending operations are executed in a separate 387 * fibril. The function pending() is c. 388 * 389 * @param arg Unused. 390 * 391 * @return Always zero. 392 * 393 */ 394 static int pending_fibril(void *arg) 395 { 396 pending(); 397 398 return 0; 399 } 400 401 /** Process pending actions. 402 * 403 * A new fibril is created which would process the pending operations. 404 * 405 * @return False if an error occured. 406 * True if the execution was passed to the pending fibril. 407 * 408 */ 409 static bool process_pending(void) 410 { 411 futex_down(&async_futex); 412 413 fid_t fid = fibril_create(pending_fibril, NULL); 373 414 fibril_add_ready(fid); 374 415 … … 473 514 } 474 515 516 /** Default fibril function that gets called to handle pending operations. 517 * 518 * This function is defined as a weak symbol - to be redefined in user code. 519 * 520 */ 521 static void default_pending(void) 522 { 523 } 524 475 525 /** Wrapper for client connection fibril. 476 526 * … … 564 614 565 615 /* Add connection to the connection hash table */ 566 ipcarg_tkey = conn->in_phone_hash;616 unsigned long key = conn->in_phone_hash; 567 617 568 618 futex_down(&async_futex); … … 589 639 if ((callid & IPC_CALLID_NOTIFICATION)) { 590 640 process_notification(callid, call); 591 return;641 goto out; 592 642 } 593 643 … … 598 648 async_new_connection(IPC_GET_ARG5(*call), callid, call, 599 649 client_connection); 600 return;650 goto out; 601 651 } 602 652 603 653 /* Try to route the call through the connection hash table */ 604 654 if (route_call(callid, call)) 605 return;655 goto out; 606 656 607 657 /* Unknown call from unknown phone - hang it up */ 608 658 ipc_answer_0(callid, EHANGUP); 659 return; 660 661 out: 662 process_pending(); 609 663 } 610 664 … … 760 814 static void reply_received(void *arg, int retval, ipc_call_t *data) 761 815 { 816 futex_down(&async_futex); 817 762 818 amsg_t *msg = (amsg_t *) arg; 763 819 msg->retval = retval; 764 820 765 futex_down(&async_futex);766 767 821 /* Copy data after futex_down, just in case the call was detached */ 768 if ( msg->dataptr)822 if ((msg->dataptr) && (data)) 769 823 *msg->dataptr = *data; 770 824 … … 993 1047 { 994 1048 interrupt_received = intr; 1049 } 1050 1051 /** Setter for pending function pointer. 1052 * 1053 * @param pend Function that will implement a new pending 1054 * operations fibril. 1055 */ 1056 void async_set_pending(async_pending_t pend) 1057 { 1058 pending = pend; 995 1059 } 996 1060 -
uspace/lib/libc/include/async.h
re77994dd r9db9b10 44 44 typedef ipc_callid_t aid_t; 45 45 typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call); 46 typedef void (*async_pending_t)(void); 47 48 extern atomic_t async_futex; 46 49 47 50 static inline void async_manager(void) … … 50 53 } 51 54 52 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); 55 extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); 56 53 57 static inline ipc_callid_t async_get_call(ipc_call_t *data) 54 58 { … … 64 68 65 69 #define async_send_0(phoneid, method, dataptr) \ 66 70 async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr)) 67 71 #define async_send_1(phoneid, method, arg1, dataptr) \ 68 72 async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr)) 69 73 #define async_send_2(phoneid, method, arg1, arg2, dataptr) \ 70 74 async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr)) 71 75 #define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \ 72 76 async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr)) 73 77 #define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \ 74 75 78 async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 79 (dataptr)) 76 80 #define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \ 77 78 81 async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 82 (arg5), (dataptr)) 79 83 80 84 extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, … … 87 91 suseconds_t timeout); 88 92 89 fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,93 extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, 90 94 ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *)); 91 void async_usleep(suseconds_t timeout);92 void async_create_manager(void);93 void async_destroy_manager(void);94 int _async_init(void);95 extern void async_usleep(suseconds_t timeout); 96 extern void async_create_manager(void); 97 extern void async_destroy_manager(void); 98 extern int _async_init(void); 95 99 96 100 extern void async_set_client_connection(async_client_conn_t conn); 97 101 extern void async_set_interrupt_received(async_client_conn_t conn); 102 extern void async_set_pending(async_pending_t pend); 98 103 99 104 /* Wrappers for simple communication */ 100 105 #define async_msg_0(phone, method) \ 101 106 ipc_call_async_0((phone), (method), NULL, NULL, true) 102 107 #define async_msg_1(phone, method, arg1) \ 103 104 108 ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \ 109 true) 105 110 #define async_msg_2(phone, method, arg1, arg2) \ 106 107 111 ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \ 112 true) 108 113 #define async_msg_3(phone, method, arg1, arg2, arg3) \ 109 110 114 ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \ 115 true) 111 116 #define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \ 112 113 117 ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ 118 NULL, true) 114 119 #define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \ 115 116 120 ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \ 121 (arg5), NULL, NULL, true) 117 122 118 123 /* … … 123 128 */ 124 129 #define async_req_0_0(phoneid, method) \ 125 126 NULL)130 async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \ 131 NULL) 127 132 #define async_req_0_1(phoneid, method, r1) \ 128 129 NULL)133 async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \ 134 NULL) 130 135 #define async_req_0_2(phoneid, method, r1, r2) \ 131 132 NULL)136 async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \ 137 NULL) 133 138 #define async_req_0_3(phoneid, method, r1, r2, r3) \ 134 135 NULL)139 async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \ 140 NULL) 136 141 #define async_req_0_4(phoneid, method, r1, r2, r3, r4) \ 137 138 NULL)142 async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ 143 NULL) 139 144 #define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \ 140 141 (r5))145 async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ 146 (r5)) 142 147 #define async_req_1_0(phoneid, method, arg1) \ 143 144 NULL, NULL)148 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \ 149 NULL, NULL) 145 150 #define async_req_1_1(phoneid, method, arg1, rc1) \ 146 147 NULL, NULL)151 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \ 152 NULL, NULL) 148 153 #define async_req_1_2(phoneid, method, arg1, rc1, rc2) \ 149 150 NULL, NULL)154 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \ 155 NULL, NULL) 151 156 #define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \ 152 153 NULL, NULL)157 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ 158 NULL, NULL) 154 159 #define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \ 155 156 (rc4), NULL)160 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ 161 (rc4), NULL) 157 162 #define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \ 158 159 (rc4), (rc5))163 async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ 164 (rc4), (rc5)) 160 165 #define async_req_2_0(phoneid, method, arg1, arg2) \ 161 162 NULL, NULL, NULL)166 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \ 167 NULL, NULL, NULL) 163 168 #define async_req_2_1(phoneid, method, arg1, arg2, rc1) \ 164 165 NULL, NULL, NULL)169 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \ 170 NULL, NULL, NULL) 166 171 #define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \ 167 168 NULL, NULL, NULL)172 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ 173 NULL, NULL, NULL) 169 174 #define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \ 170 171 (rc3), NULL, NULL)175 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ 176 (rc3), NULL, NULL) 172 177 #define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \ 173 174 (rc3), (rc4), NULL)178 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ 179 (rc3), (rc4), NULL) 175 180 #define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \ 176 177 (rc3), (rc4), (rc5))181 async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ 182 (rc3), (rc4), (rc5)) 178 183 #define async_req_3_0(phoneid, method, arg1, arg2, arg3) \ 179 180 NULL, NULL, NULL)184 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \ 185 NULL, NULL, NULL) 181 186 #define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \ 182 183 NULL, NULL, NULL, NULL)187 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ 188 NULL, NULL, NULL, NULL) 184 189 #define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \ 185 186 (rc2), NULL, NULL, NULL)190 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ 191 (rc2), NULL, NULL, NULL) 187 192 #define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \ 188 189 (rc2), (rc3), NULL, NULL)193 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ 194 (rc2), (rc3), NULL, NULL) 190 195 #define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \ 191 192 (rc2), (rc3), (rc4), NULL)196 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ 197 (rc2), (rc3), (rc4), NULL) 193 198 #define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \ 194 199 rc5) \ … … 196 201 (rc2), (rc3), (rc4), (rc5)) 197 202 #define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \ 198 199 NULL, NULL, NULL, NULL)203 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ 204 NULL, NULL, NULL, NULL) 200 205 #define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \ 201 202 NULL, NULL, NULL, NULL)206 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ 207 NULL, NULL, NULL, NULL) 203 208 #define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \ 204 205 (rc2), NULL, NULL, NULL)209 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ 210 (rc2), NULL, NULL, NULL) 206 211 #define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \ 207 208 (rc2), (rc3), NULL, NULL)212 async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ 213 (rc2), (rc3), NULL, NULL) 209 214 #define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \ 210 215 rc4) \ … … 216 221 (rc1), (rc2), (rc3), (rc4), (rc5)) 217 222 #define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \ 218 219 223 async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 224 (arg5), NULL, NULL, NULL, NULL, NULL) 220 225 #define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \ 221 222 (arg5), (rc1), NULL, NULL, NULL, NULL)226 async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 227 (arg5), (rc1), NULL, NULL, NULL, NULL) 223 228 #define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \ 224 225 (arg5), (rc1), (rc2), NULL, NULL, NULL)229 async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 230 (arg5), (rc1), (rc2), NULL, NULL, NULL) 226 231 #define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \ 227 232 rc3) \ … … 254 259 } 255 260 256 extern atomic_t async_futex;257 258 261 #endif 259 262
Note:
See TracChangeset
for help on using the changeset viewer.