Changes in / [2a7ba5e:0a981e3] in mainline
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/main.c
r2a7ba5e r0a981e3 43 43 #include <ddf/log.h> 44 44 #include <stdio.h> 45 #include <async.h> 45 46 #include "i8042.h" 46 47 … … 151 152 ddf_log_init(NAME); 152 153 154 /* 155 * Alleviate the virtual memory / page table pressure caused by 156 * interrupt storms when the default large stacks are used. 157 */ 158 async_set_notification_handler_stack_size(PAGE_SIZE); 159 153 160 return ddf_driver_main(&i8042_driver); 154 161 } -
uspace/lib/c/generic/async.c
r2a7ba5e r0a981e3 493 493 } 494 494 495 static size_t notification_handler_stksz = FIBRIL_DFLT_STK_SIZE; 496 497 /** Set the stack size for the notification handler notification fibrils. 498 * 499 * @param size Stack size in bytes. 500 */ 501 void async_set_notification_handler_stack_size(size_t size) 502 { 503 notification_handler_stksz = size; 504 } 505 495 506 /** Mutex protecting inactive_exch_list and avail_phone_cv. 496 507 * … … 987 998 } 988 999 989 /** Process notification. 990 * 991 * @param callid Hash of the incoming call. 992 * @param call Data of the incoming call. 993 */ 994 static void process_notification(ipc_callid_t callid, ipc_call_t *call) 995 { 1000 /** Notification fibril. 1001 * 1002 * When a notification arrives, a fibril with this implementing function is 1003 * created. It calls the corresponding notification handler and does the final 1004 * cleanup. 1005 * 1006 * @param arg Message structure pointer. 1007 * 1008 * @return Always zero. 1009 * 1010 */ 1011 static int notification_fibril(void *arg) 1012 { 1013 assert(arg); 1014 1015 msg_t *msg = (msg_t *) arg; 996 1016 async_notification_handler_t handler = NULL; 997 1017 void *data = NULL; 998 999 assert(call);1000 1018 1001 1019 futex_down(&async_futex); 1002 1020 1003 1021 ht_link_t *link = hash_table_find(¬ification_hash_table, 1004 &IPC_GET_IMETHOD( *call));1022 &IPC_GET_IMETHOD(msg->call)); 1005 1023 if (link) { 1006 1024 notification_t *notification = … … 1013 1031 1014 1032 if (handler) 1015 handler(callid, call, data); 1033 handler(msg->callid, &msg->call, data); 1034 1035 free(msg); 1036 return 0; 1037 } 1038 1039 /** Process notification. 1040 * 1041 * A new fibril is created which would process the notification. 1042 * 1043 * @param callid Hash of the incoming call. 1044 * @param call Data of the incoming call. 1045 * 1046 * @return False if an error occured. 1047 * True if the call was passed to the notification fibril. 1048 * 1049 */ 1050 static bool process_notification(ipc_callid_t callid, ipc_call_t *call) 1051 { 1052 assert(call); 1053 1054 futex_down(&async_futex); 1055 1056 msg_t *msg = malloc(sizeof(*msg)); 1057 if (!msg) { 1058 futex_up(&async_futex); 1059 return false; 1060 } 1061 1062 msg->callid = callid; 1063 msg->call = *call; 1064 1065 fid_t fid = fibril_create_generic(notification_fibril, msg, 1066 notification_handler_stksz); 1067 if (fid == 0) { 1068 free(msg); 1069 futex_up(&async_futex); 1070 return false; 1071 } 1072 1073 fibril_add_ready(fid); 1074 1075 futex_up(&async_futex); 1076 return true; 1016 1077 } 1017 1078 … … 1314 1375 /* Kernel notification */ 1315 1376 if ((callid & IPC_CALLID_NOTIFICATION)) { 1316 fibril_t *fibril = (fibril_t *) __tcb_get()->fibril_data;1317 unsigned oldsw = fibril->switches;1318 1319 1377 process_notification(callid, call); 1320 1321 if (oldsw != fibril->switches) {1322 /*1323 * The notification handler did not execute atomically1324 * and so the current manager fibril assumed the role of1325 * a notification fibril. While waiting for its1326 * resources, it switched to another manager fibril that1327 * had already existed or it created a new one. We1328 * therefore know there is at least yet another1329 * manager fibril that can take over. We now kill the1330 * current 'notification' fibril to prevent fibril1331 * population explosion.1332 */1333 futex_down(&async_futex);1334 fibril_switch(FIBRIL_FROM_DEAD);1335 }1336 1378 return; 1337 1379 } … … 1508 1550 void async_create_manager(void) 1509 1551 { 1510 fid_t fid = fibril_create _generic(async_manager_fibril, NULL, PAGE_SIZE);1552 fid_t fid = fibril_create(async_manager_fibril, NULL); 1511 1553 if (fid != 0) 1512 1554 fibril_add_manager(fid); … … 1632 1674 1633 1675 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg, 1634 reply_received );1676 reply_received, true); 1635 1677 1636 1678 return (aid_t) msg; … … 1670 1712 1671 1713 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5, 1672 msg, reply_received );1714 msg, reply_received, true); 1673 1715 1674 1716 return (aid_t) msg; … … 1959 2001 { 1960 2002 if (exch != NULL) 1961 ipc_call_async_0(exch->phone, imethod, NULL, NULL );2003 ipc_call_async_0(exch->phone, imethod, NULL, NULL, true); 1962 2004 } 1963 2005 … … 1965 2007 { 1966 2008 if (exch != NULL) 1967 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL );2009 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true); 1968 2010 } 1969 2011 … … 1972 2014 { 1973 2015 if (exch != NULL) 1974 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL); 2016 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL, 2017 true); 1975 2018 } 1976 2019 … … 1980 2023 if (exch != NULL) 1981 2024 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL, 1982 NULL );2025 NULL, true); 1983 2026 } 1984 2027 … … 1988 2031 if (exch != NULL) 1989 2032 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, 1990 NULL, NULL );2033 NULL, NULL, true); 1991 2034 } 1992 2035 … … 1996 2039 if (exch != NULL) 1997 2040 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, 1998 arg5, NULL, NULL );2041 arg5, NULL, NULL, true); 1999 2042 } 2000 2043 … … 2119 2162 2120 2163 ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg, 2121 reply_received );2164 reply_received, true); 2122 2165 2123 2166 sysarg_t rc; … … 2168 2211 2169 2212 ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4, 2170 msg, reply_received );2213 msg, reply_received, true); 2171 2214 2172 2215 sysarg_t rc; -
uspace/lib/c/generic/fibril.c
r2a7ba5e r0a981e3 113 113 114 114 fibril->waits_for = NULL; 115 116 fibril->switches = 0;117 115 118 116 /* … … 218 216 assert(stype == FIBRIL_TO_MANAGER); 219 217 220 srcf->switches++;221 222 218 /* 223 219 * Don't put the current fibril into any list, it should -
uspace/lib/c/generic/ipc.c
r2a7ba5e r0a981e3 96 96 } 97 97 98 /** Prolog uefor ipc_call_async_*() functions.98 /** Prolog for ipc_call_async_*() functions. 99 99 * 100 100 * @param private Argument for the answer/error callback. … … 122 122 } 123 123 124 /** Epilog uefor ipc_call_async_*() functions.124 /** Epilog for ipc_call_async_*() functions. 125 125 * 126 126 * @param callid Value returned by the SYS_IPC_CALL_ASYNC_* syscall. 127 127 * @param phoneid Phone handle through which the call was made. 128 128 * @param call Structure returned by ipc_prepare_async(). 129 * @param can_preempt If true, the current fibril can be preempted 130 * in this call. 131 * 129 132 */ 130 133 static inline void ipc_finish_async(ipc_callid_t callid, int phoneid, 131 async_call_t *call )134 async_call_t *call, bool can_preempt) 132 135 { 133 136 if (!call) { … … 156 159 list_append(&call->list, &queued_calls); 157 160 158 call->fid = fibril_get_id(); 159 fibril_switch(FIBRIL_TO_MANAGER); 160 /* Async futex unlocked by previous call */ 161 if (can_preempt) { 162 call->fid = fibril_get_id(); 163 fibril_switch(FIBRIL_TO_MANAGER); 164 /* Async futex unlocked by previous call */ 165 } else { 166 call->fid = 0; 167 futex_up(&async_futex); 168 } 161 169 162 170 return; … … 189 197 * @param private Argument to be passed to the answer/error callback. 190 198 * @param callback Answer or error callback. 199 * @param can_preempt If true, the current fibril will be preempted in 200 * case the kernel temporarily refuses to accept more 201 * asynchronous calls. 202 * 191 203 */ 192 204 void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1, 193 205 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private, 194 ipc_async_callback_t callback )206 ipc_async_callback_t callback, bool can_preempt) 195 207 { 196 208 async_call_t *call = NULL; … … 234 246 } 235 247 236 ipc_finish_async(callid, phoneid, call );248 ipc_finish_async(callid, phoneid, call, can_preempt); 237 249 } 238 250 … … 254 266 * @param private Argument to be passed to the answer/error callback. 255 267 * @param callback Answer or error callback. 268 * @param can_preempt If true, the current fibril will be preempted in 269 * case the kernel temporarily refuses to accept more 270 * asynchronous calls. 271 * 256 272 */ 257 273 void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, 258 274 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private, 259 ipc_async_callback_t callback )275 ipc_async_callback_t callback, bool can_preempt) 260 276 { 261 277 async_call_t *call = ipc_prepare_async(private, callback); … … 279 295 ipc_call_async_internal(phoneid, &call->u.msg.data); 280 296 281 ipc_finish_async(callid, phoneid, call );297 ipc_finish_async(callid, phoneid, call, can_preempt); 282 298 } 283 299 … … 359 375 futex_up(&async_futex); 360 376 361 assert(call->fid);362 fibril_add_ready(call->fid);377 if (call->fid) 378 fibril_add_ready(call->fid); 363 379 364 380 if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { -
uspace/lib/c/include/async.h
r2a7ba5e r0a981e3 165 165 extern int async_create_callback_port(async_exch_t *, iface_t, sysarg_t, 166 166 sysarg_t, async_port_handler_t, void *, port_id_t *); 167 168 extern void async_set_notification_handler_stack_size(size_t); 167 169 168 170 extern int async_irq_subscribe(int, int, async_notification_handler_t, void *, -
uspace/lib/c/include/fibril.h
r2a7ba5e r0a981e3 78 78 79 79 fibril_owner_info_t *waits_for; 80 81 unsigned switches;82 80 } fibril_t; 83 81 -
uspace/lib/c/include/ipc/ipc.h
r2a7ba5e r0a981e3 89 89 */ 90 90 91 #define ipc_call_async_0(phoneid, method, private, callback ) \91 #define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \ 92 92 ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ 93 (callback)) 94 #define ipc_call_async_1(phoneid, method, arg1, private, callback) \ 93 (callback), (can_preempt)) 94 #define ipc_call_async_1(phoneid, method, arg1, private, callback, \ 95 can_preempt) \ 95 96 ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, 0, (private), \ 96 (callback)) 97 #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback) \ 97 (callback), (can_preempt)) 98 #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback, \ 99 can_preempt) \ 98 100 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 99 (private), (callback)) 100 #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback) \ 101 (private), (callback), (can_preempt)) 102 #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback, \ 103 can_preempt) \ 101 104 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 102 (private), (callback) )105 (private), (callback), (can_preempt)) 103 106 #define ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, private, \ 104 callback ) \107 callback, can_preempt) \ 105 108 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 106 (arg4), (private), (callback) )109 (arg4), (private), (callback), (can_preempt)) 107 110 #define ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, \ 108 private, callback ) \111 private, callback, can_preempt) \ 109 112 ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 110 (arg4), (arg5), (private), (callback) )113 (arg4), (arg5), (private), (callback), (can_preempt)) 111 114 112 115 extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 113 sysarg_t, void *, ipc_async_callback_t );116 sysarg_t, void *, ipc_async_callback_t, bool); 114 117 extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 115 sysarg_t, sysarg_t, void *, ipc_async_callback_t );118 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 116 119 117 120 extern int ipc_hangup(int); -
uspace/srv/hw/bus/cuda_adb/cuda_adb.c
r2a7ba5e r0a981e3 47 47 #include <errno.h> 48 48 #include <ipc/adb.h> 49 #include <async.h> 49 50 #include <assert.h> 50 51 #include "cuda_adb.h" … … 157 158 printf(NAME ": VIA-CUDA Apple Desktop Bus driver\n"); 158 159 160 /* 161 * Alleviate the virtual memory / page table pressure caused by 162 * interrupt storms when the default large stacks are used. 163 */ 164 async_set_notification_handler_stack_size(PAGE_SIZE); 165 159 166 for (i = 0; i < ADB_MAX_ADDR; ++i) { 160 167 adb_dev[i].client_sess = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.