Changeset 5f62ef9 in mainline


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.

Location:
generic
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • generic/include/ipc/ipc.h

    r1065603e r5f62ef9  
    3333/* - the uspace may not be able to utilize full length */
    3434#define IPC_CALL_LEN    4
     35
     36/** Maximum active async calls per thread */
     37#define IPC_MAX_ASYNC_CALLS  4
    3538
    3639/* Flags for calls */
  • generic/include/proc/task.h

    r1065603e r5f62ef9  
    4141        link_t tasks_link;      /**< Link to other tasks within the system. */
    4242        as_t *as;               /**< Address space. */
     43        /* IPC stuff */
    4344        answerbox_t answerbox;  /**< Communication endpoint */
    4445        phone_t phones[IPC_MAX_PHONES];
     46        atomic_t active_calls;  /**< Active asynchronous messages */
    4547};
    4648
  • generic/include/syscall/syscall.h

    r1065603e r5f62ef9  
    3434        SYS_IO,
    3535        SYS_MREMAP,
     36        SYS_IPC_CALL_SYNC_FAST,
    3637        SYS_IPC_CALL_SYNC,
    37         SYS_IPC_CALL_SYNC_MEDIUM,
     38        SYS_IPC_CALL_ASYNC_FAST,
    3839        SYS_IPC_CALL_ASYNC,
    3940        SYS_IPC_ANSWER,
  • generic/src/ipc/ns.c

    r1065603e r5f62ef9  
    4646                switch (IPC_GET_METHOD(call->data)) {
    4747                case NS_PING:
    48                         printf("Ping.\n");
     48                        printf("Ping - %X, %X\n", IPC_GET_ARG1(call->data),
     49                               IPC_GET_ARG2(call->data));
    4950                        IPC_SET_RETVAL(call->data, 0);
     51                        IPC_SET_ARG1(call->data, 0xdeaddead);
     52                        IPC_SET_ARG2(call->data, 0xdeaddea2);
    5053                        break;
    5154                default:
  • generic/src/proc/task.c

    r1065603e r5f62ef9  
    8282        if (ipc_phone_0)
    8383                ipc_phone_init(&ta->phones[0], ipc_phone_0);
     84        atomic_set(&ta->active_calls, 0);
    8485       
    8586        ipl = interrupts_disable();
  • 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.