Changeset 5f62ef9 in mainline for generic/src/syscall/syscall.c


Ignore:
Timestamp:
2006-03-14T23:47:04Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d99d8c8
Parents:
1065603e
Message:

Completed asynchronous ipc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/syscall/syscall.c

    r1065603e r5f62ef9  
    5757}
    5858
     59static phone_t * get_phone(__native phoneid)
     60{
     61        phone_t *phone;
     62
     63        if (phoneid >= IPC_MAX_PHONES)
     64                return NULL;
     65
     66        phone = &TASK->phones[phoneid];
     67        if (!phone->callee)
     68                return NULL;
     69        return phone;
     70}
     71
    5972/** Send a call over IPC, wait for reply, return to user
    6073 *
     
    6275           -2 on 'Too many async request, handle answers first
    6376 */
    64 static __native sys_ipc_call_sync(__native phoneid, __native method,
    65                                    __native arg1, __native *data)
     77static __native sys_ipc_call_sync_fast(__native phoneid, __native method,
     78                                       __native arg1, __native *data)
    6679{
    6780        call_t call;
     
    6982        /* Special answerbox for synchronous messages */
    7083
    71         if (phoneid >= IPC_MAX_PHONES)
    72                 return IPC_CALLRET_FATAL;
    73 
    74         phone = &TASK->phones[phoneid];
    75         if (!phone->callee)
     84        phone = get_phone(phoneid);
     85        if (!phone)
    7686                return IPC_CALLRET_FATAL;
    7787
     
    8797}
    8898
    89 static __native sys_ipc_call_sync_medium(__native phoneid, __native *data)
     99/** Synchronous IPC call allowing to send whole message */
     100static __native sys_ipc_call_sync(__native phoneid, __native *data)
    90101{
    91102        call_t call;
     
    93104        /* Special answerbox for synchronous messages */
    94105
    95         if (phoneid >= IPC_MAX_PHONES)
    96                 return IPC_CALLRET_FATAL;
    97 
    98         phone = &TASK->phones[phoneid];
    99         if (!phone->callee)
     106        phone = get_phone(phoneid);
     107        if (!phone)
    100108                return IPC_CALLRET_FATAL;
    101109
     
    110118}
    111119
     120/** Check that the task did not exceed allowed limit
     121 *
     122 * @return 0 - Limit OK,   -1 - limit exceeded
     123 */
     124static int check_call_limit(void)
     125{
     126        if (atomic_inc_post(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) {
     127                atomic_dec(&TASK->active_calls);
     128                return -1;
     129        }
     130        return 0;
     131}
    112132
    113133/** Send an asynchronous call over ipc
     
    116136           -2 on 'Too many async request, handle answers first
    117137 */
    118 static __native sys_ipc_call_async(__native phoneid, __native method,
    119                                    __native arg1, __native arg2)
    120 {
    121         call_t *call;
    122         phone_t *phone;
    123 
    124         if (phoneid >= IPC_MAX_PHONES)
    125                 return IPC_CALLRET_FATAL;
    126 
    127         phone = &TASK->phones[phoneid];
    128         if (!phone->callee)
    129                 return IPC_CALLRET_FATAL;
    130 
    131         /* TODO: Check that we did not exceed system imposed maximum
    132          * of asynchrnously sent messages
    133          * - the userspace should be able to handle it correctly
    134          */
     138static __native sys_ipc_call_async_fast(__native phoneid, __native method,
     139                                        __native arg1, __native arg2)
     140{
     141        call_t *call;
     142        phone_t *phone;
     143
     144        phone = get_phone(phoneid);
     145        if (!phone)
     146                return IPC_CALLRET_FATAL;
     147
     148        if (check_call_limit())
     149                return IPC_CALLRET_TEMPORARY;
     150
    135151        call = ipc_call_alloc();
    136152        IPC_SET_METHOD(call->data, method);
     
    143159}
    144160
     161/** Synchronous IPC call allowing to send whole message
     162 *
     163 * @return The same as sys_ipc_call_async
     164 */
     165static __native sys_ipc_call_async(__native phoneid, __native *data)
     166{
     167        call_t *call;
     168        phone_t *phone;
     169
     170        phone = get_phone(phoneid);
     171        if (!phone)
     172                return IPC_CALLRET_FATAL;
     173
     174        if (check_call_limit())
     175                return IPC_CALLRET_TEMPORARY;
     176
     177        call = ipc_call_alloc();
     178        copy_from_uspace(&call->data, data, sizeof(call->data));
     179       
     180        ipc_call(phone, call);
     181
     182        return (__native) call;
     183}
     184
     185
    145186/** Send IPC answer */
    146187static __native sys_ipc_answer(__native callid, __native retval, __native arg1,
     
    175216
    176217        copy_to_uspace(calldata, &call->data, sizeof(call->data));
     218
    177219        if (call->flags & IPC_CALL_ANSWERED) {
    178220                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
    179221                ipc_call_free(call);
     222                atomic_dec(&TASK->active_calls);
    180223                return ((__native)call) | IPC_CALLID_ANSWERED;
    181224        }
     
    192235        sys_io,
    193236        sys_mremap,
     237        sys_ipc_call_sync_fast,
    194238        sys_ipc_call_sync,
    195         sys_ipc_call_sync_medium,
     239        sys_ipc_call_async_fast,
    196240        sys_ipc_call_async,
    197241        sys_ipc_answer,
Note: See TracChangeset for help on using the changeset viewer.