Subversion Repositories HelenOS

Rev

Rev 2615 | Rev 2619 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2615 Rev 2618
Line 187... Line 187...
187
 *
187
 *
188
 * @return      Hash of the call or an error code.
188
 * @return      Hash of the call or an error code.
189
 */
189
 */
190
static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
190
static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
191
{
191
{
192
    return __SYSCALL2(SYS_IPC_CALL_ASYNC, phoneid, (sysarg_t) data);
192
    return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
193
}
193
}
194
 
194
 
195
/** Prolog to ipc_call_async_*() functions.
195
/** Prolog to ipc_call_async_*() functions.
196
 *
196
 *
197
 * @param private   Argument for the answer/error callback.
197
 * @param private   Argument for the answer/error callback.
Line 266... Line 266...
266
   
266
   
267
}
267
}
268
 
268
 
269
/** Make a fast asynchronous call.
269
/** Make a fast asynchronous call.
270
 *
270
 *
271
 * This function can only handle two arguments of payload. It is, however,
271
 * This function can only handle four arguments of payload. It is, however,
272
 * faster than the more generic ipc_call_async_3().
272
 * faster than the more generic ipc_call_async_slow().
273
 *
273
 *
274
 * Note that this function is a void function.
274
 * Note that this function is a void function.
275
 * During normal opertation, answering this call will trigger the callback.
275
 * During normal opertation, answering this call will trigger the callback.
276
 * In case of fatal error, call the callback handler with the proper error code.
276
 * In case of fatal error, call the callback handler with the proper error code.
277
 * If the call cannot be temporarily made, queue it.
277
 * If the call cannot be temporarily made, queue it.
278
 *
278
 *
279
 * @param phoneid   Phone handle for the call.
279
 * @param phoneid   Phone handle for the call.
280
 * @param method    Requested method.
280
 * @param method    Requested method.
281
 * @param arg1      Service-defined payload argument.
281
 * @param arg1      Service-defined payload argument.
282
 * @param arg2      Service-defined payload argument.
282
 * @param arg2      Service-defined payload argument.
-
 
283
 * @param arg3      Service-defined payload argument.
-
 
284
 * @param arg4      Service-defined payload argument.
283
 * @param private   Argument to be passed to the answer/error callback.
285
 * @param private   Argument to be passed to the answer/error callback.
284
 * @param callback  Answer or error callback.
286
 * @param callback  Answer or error callback.
285
 * @param can_preempt   If non-zero, the current fibril will be preempted in
287
 * @param can_preempt   If non-zero, the current fibril will be preempted in
286
 *          case the kernel temporarily refuses to accept more
288
 *          case the kernel temporarily refuses to accept more
287
 *          asynchronous calls.
289
 *          asynchronous calls.
288
 */
290
 */
289
void ipc_call_async_2(int phoneid, ipcarg_t method, ipcarg_t arg1,
291
void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
290
    ipcarg_t arg2, void *private, ipc_async_callback_t callback,
292
    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
291
    int can_preempt)
293
    ipc_async_callback_t callback, int can_preempt)
292
{
294
{
293
    async_call_t *call = NULL;
295
    async_call_t *call = NULL;
294
    ipc_callid_t callid;
296
    ipc_callid_t callid;
295
 
297
 
296
    if (callback) {
298
    if (callback) {
Line 302... Line 304...
302
    /*
304
    /*
303
     * We need to make sure that we get callid before another thread
305
     * We need to make sure that we get callid before another thread
304
     * accesses the queue again.
306
     * accesses the queue again.
305
     */
307
     */
306
    futex_down(&ipc_futex);
308
    futex_down(&ipc_futex);
307
    callid = __SYSCALL4(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
309
    callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
308
        arg2);
310
        arg2, arg3, arg4);
309
 
311
 
310
    if (callid == IPC_CALLRET_TEMPORARY) {
312
    if (callid == IPC_CALLRET_TEMPORARY) {
311
        if (!call) {
313
        if (!call) {
312
            call = ipc_prepare_async(private, callback);
314
            call = ipc_prepare_async(private, callback);
313
            if (!call)
315
            if (!call)
314
                return;
316
                return;
315
        }
317
        }
316
        IPC_SET_METHOD(call->u.msg.data, method);
318
        IPC_SET_METHOD(call->u.msg.data, method);
317
        IPC_SET_ARG1(call->u.msg.data, arg1);
319
        IPC_SET_ARG1(call->u.msg.data, arg1);
318
        IPC_SET_ARG2(call->u.msg.data, arg2);
320
        IPC_SET_ARG2(call->u.msg.data, arg2);
-
 
321
        IPC_SET_ARG3(call->u.msg.data, arg3);
-
 
322
        IPC_SET_ARG4(call->u.msg.data, arg4);
319
    }
323
    }
320
    ipc_finish_async(callid, phoneid, call, can_preempt);
324
    ipc_finish_async(callid, phoneid, call, can_preempt);
321
}
325
}
322
 
326
 
323
/** Make an asynchronous call transmitting the entire payload.
327
/** Make an asynchronous call transmitting the entire payload.
Line 330... Line 334...
330
 * @param phoneid   Phone handle for the call.
334
 * @param phoneid   Phone handle for the call.
331
 * @param method    Requested method.
335
 * @param method    Requested method.
332
 * @param arg1      Service-defined payload argument.
336
 * @param arg1      Service-defined payload argument.
333
 * @param arg2      Service-defined payload argument.
337
 * @param arg2      Service-defined payload argument.
334
 * @param arg3      Service-defined payload argument.
338
 * @param arg3      Service-defined payload argument.
-
 
339
 * @param arg4      Service-defined payload argument.
-
 
340
 * @param arg5      Service-defined payload argument.
335
 * @param private   Argument to be passed to the answer/error callback.
341
 * @param private   Argument to be passed to the answer/error callback.
336
 * @param callback  Answer or error callback.
342
 * @param callback  Answer or error callback.
337
 * @param can_preempt   If non-zero, the current fibril will be preempted in
343
 * @param can_preempt   If non-zero, the current fibril will be preempted in
338
 *          case the kernel temporarily refuses to accept more
344
 *          case the kernel temporarily refuses to accept more
339
 *          asynchronous calls.
345
 *          asynchronous calls.
340
 *
346
 *
341
 */
347
 */
342
void ipc_call_async_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
348
void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
343
    ipcarg_t arg2, ipcarg_t arg3, void *private, ipc_async_callback_t callback,
349
    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private,
344
    int can_preempt)
350
    ipc_async_callback_t callback, int can_preempt)
345
{
351
{
346
    async_call_t *call;
352
    async_call_t *call;
347
    ipc_callid_t callid;
353
    ipc_callid_t callid;
348
 
354
 
349
    call = ipc_prepare_async(private, callback);
355
    call = ipc_prepare_async(private, callback);
Line 352... Line 358...
352
 
358
 
353
    IPC_SET_METHOD(call->u.msg.data, method);
359
    IPC_SET_METHOD(call->u.msg.data, method);
354
    IPC_SET_ARG1(call->u.msg.data, arg1);
360
    IPC_SET_ARG1(call->u.msg.data, arg1);
355
    IPC_SET_ARG2(call->u.msg.data, arg2);
361
    IPC_SET_ARG2(call->u.msg.data, arg2);
356
    IPC_SET_ARG3(call->u.msg.data, arg3);
362
    IPC_SET_ARG3(call->u.msg.data, arg3);
-
 
363
    IPC_SET_ARG4(call->u.msg.data, arg4);
-
 
364
    IPC_SET_ARG5(call->u.msg.data, arg5);
357
    /*
365
    /*
358
     * We need to make sure that we get callid before another thread accesses
366
     * We need to make sure that we get callid before another thread
359
     * the queue again.
367
     * accesses the queue again.
360
     */
368
     */
361
    futex_down(&ipc_futex);
369
    futex_down(&ipc_futex);
362
    callid = _ipc_call_async(phoneid, &call->u.msg.data);
370
    callid = _ipc_call_async(phoneid, &call->u.msg.data);
363
 
371
 
364
    ipc_finish_async(callid, phoneid, call, can_preempt);
372
    ipc_finish_async(callid, phoneid, call, can_preempt);