Changeset 197ef43 in mainline for uspace/lib/c/generic/ipc.c


Ignore:
Timestamp:
2011-01-29T23:52:07Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
12573db, 40fb017
Parents:
6aef742 (diff), 47b7006 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge various cosmetic run-time support improvements

  • coding style cleanups, comments cleanups, unsigned types for bit flags, indentation, etc.
  • SYS_TASK_EXIT for proper termination of a task (optionally with udebug notification)
    • get rid of exit(), _exit(), core()
    • reimplement robust main(), exit() and abort()
    • call abort() if some part of libc initialization fails
  • add more private libc headers to reduce the namespace pollution
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/ipc.c

    r6aef742 r197ef43  
    4949
    5050/**
    51  * Structures of this type are used for keeping track of sent asynchronous calls
    52  * and queing unsent calls.
     51 * Structures of this type are used for keeping track
     52 * of sent asynchronous calls and queing unsent calls.
    5353 */
    5454typedef struct {
    5555        link_t list;
    56 
     56       
    5757        ipc_async_callback_t callback;
    5858        void *private;
     59       
    5960        union {
    6061                ipc_callid_t callid;
     
    6465                } msg;
    6566        } u;
    66         fid_t fid;      /**< Fibril waiting for sending this call. */
     67       
     68        /** Fibril waiting for sending this call. */
     69        fid_t fid;
    6770} async_call_t;
    6871
     
    7174/** List of asynchronous calls that were not accepted by kernel.
    7275 *
    73  * It is protected by async_futex, because if the call cannot be sent into the
    74  * kernel, the async framework is used automatically.
     76 * Protected by async_futex, because if the call is not accepted
     77 * by the kernel, the async framework is used automatically.
     78 *
    7579 */
    7680LIST_INITIALIZE(queued_calls);
     
    7882static atomic_t ipc_futex = FUTEX_INITIALIZER;
    7983
    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)
     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() because
     88 * the payload is passed directly in registers.
     89 *
     90 * @param phoneid Phone handle for the call.
     91 * @param method  Requested method.
     92 * @param arg1    Service-defined payload argument.
     93 * @param arg2    Service-defined payload argument.
     94 * @param arg3    Service-defined payload argument.
     95 * @param result1 If non-NULL, the return ARG1 will be stored there.
     96 * @param result2 If non-NULL, the return ARG2 will be stored there.
     97 * @param result3 If non-NULL, the return ARG3 will be stored there.
     98 * @param result4 If non-NULL, the return ARG4 will be stored there.
     99 * @param result5 If non-NULL, the return ARG5 will be stored there.
     100 *
     101 * @return Negative values representing IPC errors.
     102 * @return Otherwise the RETVAL of the answer.
     103 *
     104 */
     105int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     106    sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,
     107    sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
    104108{
    105109        ipc_call_t resdata;
    106         int callres;
    107        
    108         callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     110        int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    109111            arg2, arg3, (sysarg_t) &resdata);
    110112        if (callres)
    111113                return callres;
     114       
    112115        if (result1)
    113116                *result1 = IPC_GET_ARG1(resdata);
     
    120123        if (result5)
    121124                *result5 = IPC_GET_ARG5(resdata);
    122 
     125       
    123126        return IPC_GET_RETVAL(resdata);
    124127}
    125128
    126 /** Make a synchronous call transmitting 5 arguments of payload.
     129/** Synchronous call transmitting 5 arguments of payload.
    127130 *
    128131 * @param phoneid Phone handle for the call.
     
    139142 * @param result5 If non-NULL, storage for the fifth return argument.
    140143 *
    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)
     144 * @return Negative values representing IPC errors.
     145 * @return Otherwise the RETVAL of the answer.
     146 *
     147 */
     148int 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 *result5)
    149152{
    150153        ipc_call_t data;
     
    176179}
    177180
    178 /** Syscall to send asynchronous message.
     181/** Send asynchronous message via syscall.
    179182 *
    180183 * @param phoneid Phone handle for the call.
     
    184187 *
    185188 */
    186 static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
     189static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)
    187190{
    188191        return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
    189192}
    190193
    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.
     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 *
    197201 */
    198202static inline async_call_t *ipc_prepare_async(void *private,
    199203    ipc_async_callback_t callback)
    200204{
    201         async_call_t *call;
    202 
    203         call = malloc(sizeof(*call));
     205        async_call_t *call =
     206            (async_call_t *) malloc(sizeof(async_call_t));
    204207        if (!call) {
    205208                if (callback)
    206209                        callback(private, ENOMEM, NULL);
     210               
    207211                return NULL;
    208212        }
     213       
    209214        call->callback = callback;
    210215        call->private = private;
    211 
     216       
    212217        return call;
    213218}
    214219
    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.
     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 *
    222228 */
    223229static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    224     async_call_t *call, int can_preempt)
    225 {
    226         if (!call) { /* Nothing to do regardless if failed or not */
     230    async_call_t *call, bool can_preempt)
     231{
     232        if (!call) {
     233                /* Nothing to do regardless if failed or not */
    227234                futex_up(&ipc_futex);
    228235                return;
    229236        }
    230 
     237       
    231238        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    232239                futex_up(&ipc_futex);
     240               
    233241                /* Call asynchronous handler with error code */
    234242                if (call->callback)
    235243                        call->callback(call->private, ENOENT, NULL);
     244               
    236245                free(call);
    237246                return;
    238247        }
    239 
     248       
    240249        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    241250                futex_up(&ipc_futex);
    242 
     251               
    243252                call->u.msg.phoneid = phoneid;
    244253               
    245254                futex_down(&async_futex);
    246255                list_append(&call->list, &queued_calls);
    247 
     256               
    248257                if (can_preempt) {
    249258                        call->fid = fibril_get_id();
     
    254263                        futex_up(&async_futex);
    255264                }
     265               
    256266                return;
    257267        }
     268       
    258269        call->u.callid = callid;
     270       
    259271        /* Add call to the list of dispatched calls */
    260272        list_append(&call->list, &dispatched_calls);
    261273        futex_up(&ipc_futex);
    262        
    263 }
    264 
    265 /** Make a fast asynchronous call.
     274}
     275
     276/** Fast asynchronous call.
    266277 *
    267278 * This function can only handle four arguments of payload. It is, however,
     
    269280 *
    270281 * Note that this function is a void function.
    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.
     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.
    274286 *
    275287 * @param phoneid     Phone handle for the call.
     
    281293 * @param private     Argument to be passed to the answer/error callback.
    282294 * @param callback    Answer or error callback.
    283  * @param can_preempt If non-zero, the current fibril will be preempted in
     295 * @param can_preempt If true, the current fibril will be preempted in
    284296 *                    case the kernel temporarily refuses to accept more
    285297 *                    asynchronous calls.
     
    288300void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
    289301    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
    290     ipc_async_callback_t callback, int can_preempt)
     302    ipc_async_callback_t callback, bool can_preempt)
    291303{
    292304        async_call_t *call = NULL;
     
    299311       
    300312        /*
    301          * We need to make sure that we get callid before another thread
    302          * accesses the queue again.
     313         * We need to make sure that we get callid
     314         * before another thread accesses the queue again.
    303315         */
     316       
    304317        futex_down(&ipc_futex);
    305318        ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
     
    312325                                return;
    313326                }
     327               
    314328                IPC_SET_IMETHOD(call->u.msg.data, imethod);
    315329                IPC_SET_ARG1(call->u.msg.data, arg1);
     
    317331                IPC_SET_ARG3(call->u.msg.data, arg3);
    318332                IPC_SET_ARG4(call->u.msg.data, arg4);
     333               
    319334                /*
    320335                 * To achieve deterministic behavior, we always zero out the
    321336                 * arguments that are beyond the limits of the fast version.
    322337                 */
     338               
    323339                IPC_SET_ARG5(call->u.msg.data, 0);
    324340        }
     341       
    325342        ipc_finish_async(callid, phoneid, call, can_preempt);
    326343}
    327344
    328 /** Make an asynchronous call transmitting the entire payload.
     345/** Asynchronous call transmitting the entire payload.
    329346 *
    330347 * Note that this function is a void function.
    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.
     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.
    334352 *
    335353 * @param phoneid     Phone handle for the call.
     
    342360 * @param private     Argument to be passed to the answer/error callback.
    343361 * @param callback    Answer or error callback.
    344  * @param can_preempt If non-zero, the current fibril will be preempted in
     362 * @param can_preempt If true, the current fibril will be preempted in
    345363 *                    case the kernel temporarily refuses to accept more
    346364 *                    asynchronous calls.
     
    349367void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    350368    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
    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);
     369    ipc_async_callback_t callback, bool can_preempt)
     370{
     371        async_call_t *call = ipc_prepare_async(private, callback);
    357372        if (!call)
    358373                return;
    359 
     374       
    360375        IPC_SET_IMETHOD(call->u.msg.data, imethod);
    361376        IPC_SET_ARG1(call->u.msg.data, arg1);
     
    364379        IPC_SET_ARG4(call->u.msg.data, arg4);
    365380        IPC_SET_ARG5(call->u.msg.data, arg5);
     381       
    366382        /*
    367          * We need to make sure that we get callid before another thread
    368          * accesses the queue again.
     383         * We need to make sure that we get callid
     384         * before another threadaccesses the queue again.
    369385         */
     386       
    370387        futex_down(&ipc_futex);
    371         callid = _ipc_call_async(phoneid, &call->u.msg.data);
    372 
     388        ipc_callid_t callid =
     389            ipc_call_async_internal(phoneid, &call->u.msg.data);
     390       
    373391        ipc_finish_async(callid, phoneid, call, can_preempt);
    374392}
    375393
    376 
    377 /** Answer a received call - fast version.
     394/** Answer received call (fast version).
    378395 *
    379396 * The fast answer makes use of passing retval and first four arguments in
    380397 * registers. If you need to return more, use the ipc_answer_slow() instead.
    381398 *
    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.
     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 *
    390409 */
    391410sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    396415}
    397416
    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.
     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 *
    409430 */
    410431sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    412433{
    413434        ipc_call_t data;
    414 
     435       
    415436        IPC_SET_RETVAL(data, retval);
    416437        IPC_SET_ARG1(data, arg1);
     
    419440        IPC_SET_ARG4(data, arg4);
    420441        IPC_SET_ARG5(data, arg5);
    421 
     442       
    422443        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
    423444}
    424445
    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 
     446/** Try to dispatch queued calls from the async queue.
     447 *
     448 */
     449static void dispatch_queued_calls(void)
     450{
    432451        /** @todo
    433          * Integrate intelligently ipc_futex, so that it is locked during
    434          * ipc_call_async_*(), until it is added to dispatched_calls.
     452         * Integrate intelligently ipc_futex so that it is locked during
     453         * ipc_call_async_*() until it is added to dispatched_calls.
    435454         */
     455       
    436456        futex_down(&async_futex);
     457       
    437458        while (!list_empty(&queued_calls)) {
    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) {
     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)
    442465                        break;
    443                 }
     466               
    444467                list_remove(&call->list);
    445 
     468               
    446469                futex_up(&async_futex);
     470               
    447471                if (call->fid)
    448472                        fibril_add_ready(call->fid);
     
    451475                        if (call->callback)
    452476                                call->callback(call->private, ENOENT, NULL);
     477                       
    453478                        free(call);
    454479                } else {
    455480                        call->u.callid = callid;
     481                       
    456482                        futex_down(&ipc_futex);
    457483                        list_append(&call->list, &dispatched_calls);
    458484                        futex_up(&ipc_futex);
    459485                }
     486               
    460487                futex_down(&async_futex);
    461488        }
     489       
    462490        futex_up(&async_futex);
    463491}
    464492
    465 /** Handle a received answer.
     493/** Handle received answer.
    466494 *
    467495 * Find the hash of the answer and call the answer callback.
    468496 *
    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.
     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 *
    475505 */
    476506static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
    477507{
     508        callid &= ~IPC_CALLID_ANSWERED;
     509       
     510        futex_down(&ipc_futex);
     511       
    478512        link_t *item;
    479         async_call_t *call;
    480 
    481         callid &= ~IPC_CALLID_ANSWERED;
    482        
    483         futex_down(&ipc_futex);
    484513        for (item = dispatched_calls.next; item != &dispatched_calls;
    485514            item = item->next) {
    486                 call = list_get_instance(item, async_call_t, list);
     515                async_call_t *call =
     516                    list_get_instance(item, async_call_t, list);
     517               
    487518                if (call->u.callid == callid) {
    488519                        list_remove(&call->list);
     520                       
    489521                        futex_up(&ipc_futex);
     522                       
    490523                        if (call->callback)
    491                                 call->callback(call->private, 
     524                                call->callback(call->private,
    492525                                    IPC_GET_RETVAL(*data), data);
     526                       
    493527                        free(call);
    494528                        return;
    495529                }
    496530        }
     531       
    497532        futex_up(&ipc_futex);
    498533}
    499534
    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);
     535/** Wait for first IPC call to come.
     536 *
     537 * @param call  Incoming call storage.
     538 * @param usec  Timeout in microseconds
     539 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
     540 *
     541 * @return Hash of the call. Note that certain bits have special
     542 *         meaning: IPC_CALLID_ANSWERED is set in an answer
     543 *         and IPC_CALLID_NOTIFICATION is used for notifications.
     544 *
     545 */
     546ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec,
     547    unsigned int flags)
     548{
     549        ipc_callid_t callid =
     550            __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     551       
    517552        /* Handle received answers */
    518553        if (callid & IPC_CALLID_ANSWERED) {
    519554                handle_answer(callid, call);
    520                 try_dispatch_queued_calls();
     555                dispatch_queued_calls();
    521556        }
    522 
     557       
    523558        return callid;
    524559}
    525560
    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)
     561/** Interrupt one thread of this task from waiting for IPC.
     562 *
     563 */
     564void 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 */
     579ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
    536580{
    537581        ipc_callid_t callid;
    538 
     582       
    539583        do {
    540584                callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    541585        } while (callid & IPC_CALLID_ANSWERED);
    542 
     586       
    543587        return callid;
    544588}
     
    546590/** Check if there is an IPC call waiting to be picked up.
    547591 *
    548  * @param call          Storage where the incoming call will be stored.
    549  * @return              Hash of the answer.
     592 * Only requests are returned, answers are processed internally.
     593 *
     594 * @param call Incoming call storage.
     595 *
     596 * @return Hash of the call.
     597 *
    550598 */
    551599ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    552600{
    553601        ipc_callid_t callid;
    554 
     602       
    555603        do {
    556604                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    557605                    SYNCH_FLAGS_NON_BLOCKING);
    558606        } while (callid & IPC_CALLID_ANSWERED);
    559 
     607       
    560608        return callid;
    561609}
    562610
    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,
     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 */
     627int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    585628    sysarg_t *taskhash, sysarg_t *phonehash)
    586629{
     
    589632}
    590633
    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)
     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 */
     644int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    601645{
    602646        sysarg_t newphid;
    603         int res;
    604 
    605         res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     647        int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    606648            NULL, NULL, NULL, NULL, &newphid);
    607649        if (res)
    608650                return res;
     651       
    609652        return newphid;
    610653}
    611654
    612 /** Ask through phone for a new connection to some service.
     655/** Request new connection (blocking)
    613656 *
    614657 * If the connection is not available at the moment, the
    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)
     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 */
     669int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     670    sysarg_t arg3)
    625671{
    626672        sysarg_t newphid;
    627         int res;
    628 
    629         res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     673        int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    630674            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    631675        if (res)
    632676                return res;
     677       
    633678        return newphid;
    634679}
     
    636681/** Hang up a phone.
    637682 *
    638  * @param phoneid       Handle of the phone to be hung up.
    639  *
    640  * @return              Zero on success or a negative error code.
     683 * @param phoneid Handle of the phone to be hung up.
     684 *
     685 * @return Zero on success or a negative error code.
     686 *
    641687 */
    642688int ipc_hangup(int phoneid)
     
    646692
    647693/** Forward a received call to another destination.
     694 *
     695 * For non-system methods, the old method, arg1 and arg2 are rewritten
     696 * by the new values. For system methods, the new method, arg1 and arg2
     697 * are written to the old arg1, arg2 and arg3, respectivelly. Calls with
     698 * immutable methods are forwarded verbatim.
    648699 *
    649700 * @param callid  Hash of the call to forward.
     
    656707 * @return Zero on success or an error code.
    657708 *
    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)
     709 */
     710int ipc_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     711    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    665712{
    666713        return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
     
    668715}
    669716
    670 
    671 int ipc_forward_slow(ipc_callid_t callid, int phoneid, int imethod,
     717int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    672718    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    673     int mode)
     719    unsigned int mode)
    674720{
    675721        ipc_call_t data;
     
    682728        IPC_SET_ARG5(data, arg5);
    683729       
    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.
     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 *
    697744 */
    698745int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    699     int *flags)
     746    unsigned int *flags)
    700747{
    701748        sysarg_t tmp_flags = 0;
     
    704751       
    705752        if (flags)
    706                 *flags = tmp_flags;
     753                *flags = (unsigned int) tmp_flags;
    707754       
    708755        return res;
     
    711758/** Wrapper for answering the IPC_M_SHARE_IN calls.
    712759 *
    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)
     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 */
     771int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    723772{
    724773        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
    725774}
    726775
    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)
     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 */
     785int ipc_share_out_start(int phoneid, void *src, unsigned int flags)
    736786{
    737787        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    741791/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    742792 *
    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.
     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 *
    750802 */
    751803int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
     
    754806}
    755807
    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.
     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    Size of the destination buffer.
     813 *
     814 * @return Zero on success or a negative error code from errno.h.
     815 *
    764816 */
    765817int ipc_data_read_start(int phoneid, void *dst, size_t size)
     
    771823/** Wrapper for answering the IPC_M_DATA_READ calls.
    772824 *
    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.
     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 *
    782836 */
    783837int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    786840}
    787841
    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.
     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 *
    795850 */
    796851int ipc_data_write_start(int phoneid, const void *src, size_t size)
     
    802857/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    803858 *
    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.
     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 *
    812869 */
    813870int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
Note: See TracChangeset for help on using the changeset viewer.