Changeset 7c0e1f5 in mainline
- Timestamp:
- 2017-11-23T22:20:17Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b1f36e3
- Parents:
- 40e5d66
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
r40e5d66 r7c0e1f5 106 106 /** Phone which made or last masqueraded this call. */ 107 107 phone_t *phone; 108 /** User-defined label */ 109 sysarg_t label; 108 110 } ipc_data_t; 109 111 -
kernel/generic/include/ipc/sysipc.h
r40e5d66 r7c0e1f5 44 44 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 45 45 sysarg_t, sysarg_t, sysarg_t); 46 extern sysarg_t sys_ipc_call_async_slow(sysarg_t, ipc_data_t * );46 extern sysarg_t sys_ipc_call_async_slow(sysarg_t, ipc_data_t *, sysarg_t); 47 47 extern sysarg_t sys_ipc_answer_fast(sysarg_t, sysarg_t, sysarg_t, sysarg_t, 48 48 sysarg_t, sysarg_t); -
kernel/generic/src/ipc/sysipc.c
r40e5d66 r7c0e1f5 347 347 /** Make a fast asynchronous call over IPC. 348 348 * 349 * This function can only handle fourarguments of payload, but is faster than349 * This function can only handle three arguments of payload, but is faster than 350 350 * the generic function sys_ipc_call_async_slow(). 351 351 * … … 355 355 * @param arg2 Service-defined payload argument. 356 356 * @param arg3 Service-defined payload argument. 357 * @param arg4 Service-defined payload argument.357 * @param label User-defined label. 358 358 * 359 359 * @return Call hash on success. … … 362 362 */ 363 363 sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod, 364 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)364 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t label) 365 365 { 366 366 kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE); … … 378 378 IPC_SET_ARG2(call->data, arg2); 379 379 IPC_SET_ARG3(call->data, arg3); 380 IPC_SET_ARG4(call->data, arg4);381 380 382 381 /* … … 385 384 */ 386 385 IPC_SET_ARG5(call->data, 0); 386 387 /* Set the user-defined label */ 388 call->data.label = label; 387 389 388 390 int res = request_preprocess(call, kobj->phone); … … 401 403 * @param handle Phone capability for the call. 402 404 * @param data Userspace address of call data with the request. 405 * @param label User-defined label. 403 406 * 404 407 * @return See sys_ipc_call_async_fast(). 405 408 * 406 409 */ 407 sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data) 410 sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data, 411 sysarg_t label) 408 412 { 409 413 kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE); … … 424 428 return (sysarg_t) rc; 425 429 } 430 431 /* Set the user-defined label */ 432 call->data.label = label; 426 433 427 434 int res = request_preprocess(call, kobj->phone); -
uspace/app/trace/syscalls.c
r40e5d66 r7c0e1f5 54 54 55 55 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH },56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 3, V_HASH }, 57 57 58 58 [SYS_IPC_ANSWER_FAST] = { "ipc_answer_fast", 6, V_ERRNO }, -
uspace/lib/c/generic/ipc.c
r40e5d66 r7c0e1f5 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2017 Jakub Jermar 3 4 * All rights reserved. 4 5 * … … 52 53 * Structures of this type are used for keeping track of sent asynchronous calls. 53 54 */ 54 typedef struct { 55 link_t list; 56 55 typedef struct async_call { 57 56 ipc_async_callback_t callback; 58 57 void *private; 59 58 60 union { 61 ipc_callid_t callid; 62 struct { 63 ipc_call_t data; 64 int phoneid; 65 } msg; 66 } u; 59 struct { 60 ipc_call_t data; 61 int phoneid; 62 } msg; 67 63 } async_call_t; 68 69 LIST_INITIALIZE(dispatched_calls);70 71 static futex_t ipc_futex = FUTEX_INITIALIZER;72 73 /** Send asynchronous message via syscall.74 *75 * @param phoneid Phone handle for the call.76 * @param data Call data with the request.77 *78 * @return Hash of the call or an error code.79 *80 */81 static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)82 {83 return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);84 }85 64 86 65 /** Prologue for ipc_call_async_*() functions. … … 121 100 if (!call) { 122 101 /* Nothing to do regardless if failed or not */ 123 futex_unlock(&ipc_futex);124 102 return; 125 103 } 126 104 127 105 if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { 128 futex_unlock(&ipc_futex);129 130 106 /* Call asynchronous handler with error code */ 131 107 if (call->callback) … … 135 111 return; 136 112 } 137 138 call->u.callid = callid;139 140 /* Add call to the list of dispatched calls */141 list_append(&call->list, &dispatched_calls);142 futex_unlock(&ipc_futex);143 113 } 144 114 145 115 /** Fast asynchronous call. 146 116 * 147 * This function can only handle fourarguments of payload. It is, however,117 * This function can only handle three arguments of payload. It is, however, 148 118 * faster than the more generic ipc_call_async_slow(). 149 119 * … … 159 129 * @param arg2 Service-defined payload argument. 160 130 * @param arg3 Service-defined payload argument. 161 * @param arg4 Service-defined payload argument.162 131 * @param private Argument to be passed to the answer/error callback. 163 132 * @param callback Answer or error callback. 164 133 */ 165 134 void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1, 166 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private, 167 ipc_async_callback_t callback) 135 sysarg_t arg2, sysarg_t arg3, void *private, ipc_async_callback_t callback) 168 136 { 169 137 async_call_t *call = NULL; … … 175 143 } 176 144 177 /*178 * We need to make sure that we get callid179 * before another thread accesses the queue again.180 */181 182 futex_lock(&ipc_futex);183 145 ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, 184 imethod, arg1, arg2, arg3, arg4);146 imethod, arg1, arg2, arg3, (sysarg_t) call); 185 147 186 148 ipc_finish_async(callid, phoneid, call); … … 213 175 return; 214 176 215 IPC_SET_IMETHOD(call->u.msg.data, imethod); 216 IPC_SET_ARG1(call->u.msg.data, arg1); 217 IPC_SET_ARG2(call->u.msg.data, arg2); 218 IPC_SET_ARG3(call->u.msg.data, arg3); 219 IPC_SET_ARG4(call->u.msg.data, arg4); 220 IPC_SET_ARG5(call->u.msg.data, arg5); 221 222 /* 223 * We need to make sure that we get callid 224 * before another threadaccesses the queue again. 225 */ 226 227 futex_lock(&ipc_futex); 228 ipc_callid_t callid = 229 ipc_call_async_internal(phoneid, &call->u.msg.data); 177 IPC_SET_IMETHOD(call->msg.data, imethod); 178 IPC_SET_ARG1(call->msg.data, arg1); 179 IPC_SET_ARG2(call->msg.data, arg2); 180 IPC_SET_ARG3(call->msg.data, arg3); 181 IPC_SET_ARG4(call->msg.data, arg4); 182 IPC_SET_ARG5(call->msg.data, arg5); 183 184 ipc_callid_t callid = __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, phoneid, 185 (sysarg_t) &call->msg.data, (sysarg_t) call); 230 186 231 187 ipc_finish_async(callid, phoneid, call); … … 286 242 /** Handle received answer. 287 243 * 288 * Find the hash of the answer and call the answer callback.289 *290 * The answer has the same hash as the request OR'ed with291 * the IPC_CALLID_ANSWERED bit.292 *293 * @todo Use hash table.294 *295 244 * @param callid Hash of the received answer. 296 245 * @param data Call data of the answer. 297 *298 246 */ 299 247 static void handle_answer(ipc_callid_t callid, ipc_call_t *data) 300 248 { 301 callid &= ~IPC_CALLID_ANSWERED; 302 303 futex_lock(&ipc_futex); 304 305 link_t *item; 306 for (item = dispatched_calls.head.next; item != &dispatched_calls.head; 307 item = item->next) { 308 async_call_t *call = 309 list_get_instance(item, async_call_t, list); 310 311 if (call->u.callid == callid) { 312 list_remove(&call->list); 313 314 futex_unlock(&ipc_futex); 315 316 if (call->callback) 317 call->callback(call->private, 318 IPC_GET_RETVAL(*data), data); 319 320 free(call); 321 return; 322 } 323 } 324 325 futex_unlock(&ipc_futex); 249 async_call_t *call = data->label; 250 251 if (!call) 252 return; 253 254 if (call->callback) 255 call->callback(call->private, IPC_GET_RETVAL(*data), data); 256 free(call); 326 257 } 327 258 -
uspace/lib/c/include/ipc/common.h
r40e5d66 r7c0e1f5 43 43 #define IPC_FLAG_BLOCKING 0x01 44 44 45 struct async_call; 46 45 47 typedef struct { 46 48 sysarg_t args[IPC_CALL_LEN]; 47 49 task_id_t in_task_id; 48 50 sysarg_t in_phone_hash; 51 struct async_call *label; 49 52 } ipc_call_t; 50 53 -
uspace/lib/c/include/ipc/ipc.h
r40e5d66 r7c0e1f5 89 89 90 90 #define ipc_call_async_0(phoneid, method, private, callback) \ 91 ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ 92 (callback)) 91 ipc_call_async_fast((phoneid), (method), 0, 0, 0, (private), (callback)) 93 92 #define ipc_call_async_1(phoneid, method, arg1, private, callback) \ 94 ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, 0,(private), \93 ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, (private), \ 95 94 (callback)) 96 95 #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback) \ 97 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, 0,\96 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, \ 98 97 (private), (callback)) 99 98 #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback) \ 100 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), 0,\99 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 101 100 (private), (callback)) 102 101 #define ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, private, \ 103 102 callback) \ 104 ipc_call_async_ fast((phoneid), (method), (arg1), (arg2), (arg3), \105 (arg4), (private), (callback))103 ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 104 (arg4), 0, (private), (callback)) 106 105 #define ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, \ 107 106 private, callback) \ … … 110 109 111 110 extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 112 sysarg_t,void *, ipc_async_callback_t);111 void *, ipc_async_callback_t); 113 112 extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 114 113 sysarg_t, sysarg_t, void *, ipc_async_callback_t);
Note:
See TracChangeset
for help on using the changeset viewer.