Changeset 51ec40f in mainline


Ignore:
Timestamp:
2007-05-18T10:27:01Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f6d2c81
Parents:
ddf1255
Message:

Improve comments for the IPC subsystem.
Fix formatting and indentation.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/ipcrsc.c

    rddf1255 r51ec40f  
    3535/* IPC resources management
    3636 *
    37  * The goal of this source code is to properly manage IPC resources
    38  * and allow straight and clean clean-up procedure upon task termination.
     37 * The goal of this source code is to properly manage IPC resources and allow
     38 * straight and clean clean-up procedure upon task termination.
    3939 *
    4040 * The pattern of usage of the resources is:
     
    4848 * Locking strategy
    4949 *
    50  * - To use a phone, disconnect a phone etc., the phone must be
    51  *   first locked and then checked that it is connected
    52  * - To connect an allocated phone it need not be locked (assigning
    53  *   pointer is atomic on all platforms)
     50 * - To use a phone, disconnect a phone etc., the phone must be first locked and
     51 *   then checked that it is connected
     52 * - To connect an allocated phone it need not be locked (assigning pointer is
     53 *   atomic on all platforms)
    5454 *
    5555 * - To find an empty phone slot, the TASK must be locked
    5656 * - To answer a message, the answerbox must be locked
    5757 * - The locking of phone and answerbox is done at the ipc_ level.
    58  *   It is perfectly correct to pass unconnected phone to these functions
    59  *   and proper reply will be generated.
     58 *   It is perfectly correct to pass unconnected phone to these functions and
     59 *   proper reply will be generated.
    6060 *
    6161 * Locking order
     
    6363 * - first phone, then answerbox
    6464 *   + Easy locking on calls
    65  *   - Very hard traversing list of phones when disconnecting because
    66  *     the phones may disconnect during traversal of list of connected phones.
    67  *     The only possibility is try_lock with restart of list traversal.
     65 *   - Very hard traversing list of phones when disconnecting because the phones
     66 *     may disconnect during traversal of list of connected phones. The only
     67 *     possibility is try_lock with restart of list traversal.
    6868 *
    6969 * Destroying is less frequent, this approach is taken.
     
    7272 *
    7373 * *** Connect_me_to ***
    74  * The caller sends IPC_M_CONNECT_ME_TO to an answerbox. The server
    75  * receives 'phoneid' of the connecting phone as an ARG3. If it answers
    76  * with RETVAL=0, the phonecall is accepted, otherwise it is refused.
     74 * The caller sends IPC_M_CONNECT_ME_TO to an answerbox. The server receives
     75 * 'phoneid' of the connecting phone as an ARG3. If it answers with RETVAL=0,
     76 * the phonecall is accepted, otherwise it is refused.
    7777 *
    7878 * *** Connect_to_me ***
    79  * The caller sends IPC_M_CONNECT_TO_ME, with special
    80  * The server receives an automatically
    81  * opened phoneid. If it accepts (RETVAL=0), it can use the phoneid
    82  * immediately.
    83  * Possible race condition can arise, when the client receives messages
    84  * from new connection before getting response for connect_to_me message.
    85  * Userspace should implement handshake protocol that would control it.
     79 * The caller sends IPC_M_CONNECT_TO_ME.
     80 * The server receives an automatically opened phoneid. If it accepts
     81 * (RETVAL=0), it can use the phoneid immediately.
     82 * Possible race condition can arise, when the client receives messages from new
     83 * connection before getting response for connect_to_me message. Userspace
     84 * should implement handshake protocol that would control it.
    8685 *
    8786 * Phone hangup
     
    8988 * *** The caller hangs up (sys_ipc_hangup) ***
    9089 * - The phone is disconnected (no more messages can be sent over this phone),
    91  *   all in-progress messages are correctly handled. The anwerbox receives
     90 *   all in-progress messages are correctly handled. The answerbox receives
    9291 *   IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async
    9392 *   calls are answered, the phone is deallocated.
  • kernel/generic/src/ipc/sysipc.c

    rddf1255 r51ec40f  
    5050#include <print.h>
    5151
    52 #define GET_CHECK_PHONE(phone,phoneid,err) { \
     52#define GET_CHECK_PHONE(phone, phoneid, err) { \
    5353      if (phoneid > IPC_MAX_PHONES) { err; } \
    5454      phone = &TASK->phones[phoneid]; \
    5555}
    5656
    57 #define STRUCT_TO_USPACE(dst,src) copy_to_uspace(dst,src,sizeof(*(src)))
     57#define STRUCT_TO_USPACE(dst, src) copy_to_uspace(dst, src, sizeof(*(src)))
    5858
    5959/** Return true if the method is a system method */
     
    7272static inline int is_forwardable(unative_t method)
    7373{
    74         if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND \
    75             || method == IPC_M_AS_AREA_RECV)
     74        if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND ||
     75            method == IPC_M_AS_AREA_RECV)
    7676                return 0; /* This message is meant only for the receiver */
    7777        return 1;
     
    131131                } else {
    132132                        /* The connection was accepted */
    133                         phone_connect(phoneid,&answer->sender->answerbox);
     133                        phone_connect(phoneid, &answer->sender->answerbox);
    134134                        /* Set 'phone identification' as arg3 of response */
    135                         IPC_SET_ARG3(answer->data, (unative_t)&TASK->phones[phoneid]);
     135                        IPC_SET_ARG3(answer->data,
     136                            (unative_t) &TASK->phones[phoneid]);
    136137                }
    137138        } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
    138139                /* If the users accepted call, connect */
    139140                if (!IPC_GET_RETVAL(answer->data)) {
    140                         ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
    141                                           &TASK->answerbox);
     141                        ipc_phone_connect((phone_t *) IPC_GET_ARG3(*olddata),
     142                            &TASK->answerbox);
    142143                }
    143144        } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
    144                 if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle as_area receipt */
     145                if (!IPC_GET_RETVAL(answer->data)) {
     146                        /* Accepted, handle as_area receipt */
    145147                        ipl_t ipl;
    146148                        int rc;
     
    153155                        interrupts_restore(ipl);
    154156                       
    155                         rc = as_area_share(as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(*olddata),
    156                                            AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
     157                        rc = as_area_share(as, IPC_GET_ARG1(*olddata),
     158                            IPC_GET_ARG2(*olddata), AS,
     159                            IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
    157160                        IPC_SET_RETVAL(answer->data, rc);
    158161                        return rc;
     
    170173                        interrupts_restore(ipl);
    171174                       
    172                         rc = as_area_share(AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG2(*olddata),
    173                                            as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(answer->data));
     175                        rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
     176                            IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
     177                            IPC_GET_ARG2(answer->data));
    174178                        IPC_SET_RETVAL(answer->data, rc);
    175179                }
     
    193197                        return ELIMIT;
    194198                /* Set arg3 for server */
    195                 IPC_SET_ARG3(call->data, (unative_t)&TASK->phones[newphid]);
     199                IPC_SET_ARG3(call->data, (unative_t) &TASK->phones[newphid]);
    196200                call->flags |= IPC_CALL_CONN_ME_TO;
    197201                call->priv = newphid;
     
    218222static void process_answer(call_t *call)
    219223{
    220         if (IPC_GET_RETVAL(call->data) == EHANGUP && \
    221             call->flags & IPC_CALL_FORWARDED)
     224        if (IPC_GET_RETVAL(call->data) == EHANGUP &&
     225            (call->flags & IPC_CALL_FORWARDED))
    222226                IPC_SET_RETVAL(call->data, EFORWARD);
    223227
     
    234238 * @return 0 - the call should be passed to userspace, 1 - ignore call
    235239 */
    236 static int process_request(answerbox_t *box,call_t *call)
     240static int process_request(answerbox_t *box, call_t *call)
    237241{
    238242        int phoneid;
     
    255259           -2 on 'Too many async request, handle answers first
    256260 */
    257 unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method, 
    258                                 unative_t arg1, ipc_data_t *data)
     261unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method,
     262    unative_t arg1, ipc_data_t *data)
    259263{
    260264        call_t call;
     
    279283
    280284/** Synchronous IPC call allowing to send whole message */
    281 unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question, 
    282                            ipc_data_t *reply)
     285unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
     286    ipc_data_t *reply)
    283287{
    284288        call_t call;
     
    288292
    289293        ipc_call_static_init(&call);
    290         rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
     294        rc = copy_from_uspace(&call.data.args, &question->args,
     295            sizeof(call.data.args));
    291296        if (rc != 0)
    292297                return (unative_t) rc;
     
    325330           -2 on 'Too many async request, handle answers first
    326331 */
    327 unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method, 
    328                                 unative_t arg1, unative_t arg2)
     332unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method,
     333    unative_t arg1, unative_t arg2)
    329334{
    330335        call_t *call;
     
    343348        IPC_SET_ARG3(call->data, 0);
    344349
    345         if (!(res=request_preprocess(call)))
     350        if (!(res = request_preprocess(call)))
    346351                ipc_call(phone, call);
    347352        else
     
    368373
    369374        call = ipc_call_alloc(0);
    370         rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
     375        rc = copy_from_uspace(&call->data.args, &data->args,
     376            sizeof(call->data.args));
    371377        if (rc != 0) {
    372378                ipc_call_free(call);
    373379                return (unative_t) rc;
    374380        }
    375         if (!(res=request_preprocess(call)))
     381        if (!(res = request_preprocess(call)))
    376382                ipc_call(phone, call);
    377383        else
     
    389395 */
    390396unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
    391                               unative_t method, unative_t arg1)
     397    unative_t method, unative_t arg1)
    392398{
    393399        call_t *call;
     
    430436
    431437/** Send IPC answer */
    432 unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval, 
    433                              unative_t arg1, unative_t arg2)
     438unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval,
     439    unative_t arg1, unative_t arg2)
    434440{
    435441        call_t *call;
     
    481487        }
    482488        rc = copy_from_uspace(&call->data.args, &data->args,
    483                         sizeof(call->data.args));
     489            sizeof(call->data.args));
    484490        if (rc != 0)
    485491                return rc;
     
    509515/** Wait for incoming ipc call or answer
    510516 *
    511  * @param calldata Pointer to buffer where the call/answer data is stored
    512  * @param usec Timeout. See waitq_sleep_timeout() for explanation.
    513  * @param flags Select mode of sleep operation. See waitq_sleep_timeout() for explanation.
     517 * @param calldata      Pointer to buffer where the call/answer data is stored.
     518 * @param usec          Timeout. See waitq_sleep_timeout() for explanation.
     519 * @param flags         Select mode of sleep operation. See waitq_sleep_timeout()
     520 *                      for explanation.
    514521 *
    515522 * @return Callid, if callid & 1, then the call is answer
     
    520527
    521528restart:       
    522         call = ipc_wait_for_call(&TASK->answerbox, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
     529        call = ipc_wait_for_call(&TASK->answerbox, usec,
     530            flags | SYNCH_FLAGS_INTERRUPTIBLE);
    523531        if (!call)
    524532                return 0;
     
    575583 * @return EPERM or a return code returned by ipc_irq_register().
    576584 */
    577 unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, irq_code_t *ucode)
     585unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
     586    irq_code_t *ucode)
    578587{
    579588        if (!(cap_get(TASK) & CAP_IRQ_REG))
  • uspace/libc/generic/ipc.c

    rddf1255 r51ec40f  
    418418}
    419419
    420 /** Ask destination to do a callback connection
    421  *
    422  * @return 0 - OK, error code
    423  */
    424 int ipc_connect_to_me(int phoneid, int arg1, int arg2, ipcarg_t *phone)
    425 {
    426         return ipc_call_sync_3(phoneid, IPC_M_CONNECT_TO_ME, arg1,
    427                                arg2, 0, 0, 0, phone);
    428 }
    429 
    430 /** Ask through phone for a new connection to some service
    431  *
    432  * @return new phoneid - OK, error code
     420/** Ask destination to do a callback connection.
     421 *
     422 * @param phoneid       Phone ID used for contacting the other side.
     423 * @param arg1          User defined argument.
     424 * @param arg2          User defined argument.
     425 * @param phonehash     Pointer to a place where the library will store an opaque
     426 *                      identifier of the phone that will be used for incoming
     427 *                      calls.
     428 * @return Zero on success or a negative error code.
     429 */
     430int ipc_connect_to_me(int phoneid, int arg1, int arg2, ipcarg_t *phonehash)
     431{
     432        return ipc_call_sync_3(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 0, 0, 0,
     433            phonehash);
     434}
     435
     436/** Ask through phone for a new connection to some service.
     437 *
     438 * @param phoneid       Phone ID used for contacting the other side.
     439 * @param arg1          User defined argument.
     440 * @param arg2          User defined argument.
     441 *
     442 * @return New phone ID on success or a negative error code.
    433443 */
    434444int ipc_connect_me_to(int phoneid, int arg1, int arg2)
     
    437447        int res;
    438448
    439         res =  ipc_call_sync_3(phoneid, IPC_M_CONNECT_ME_TO, arg1,
    440                                arg2, 0, 0, 0, &newphid);
     449        res =  ipc_call_sync_3(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, 0, 0, 0,
     450            &newphid);
    441451        if (res)
    442452                return res;
Note: See TracChangeset for help on using the changeset viewer.