Changeset ba81cab in mainline for generic/src/ipc/ipcrsc.c


Ignore:
Timestamp:
2006-03-18T01:06:13Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fbcfd458
Parents:
81c4c6da
Message:

Better IPC implementation with regard to locking and final cleanup.

File:
1 edited

Legend:

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

    r81c4c6da rba81cab  
    3838 * - answer message to phone
    3939 *
     40 * Locking strategy
     41 *
     42 * - To use a phone, disconnect a phone etc., the phone must be
     43 *   first locked and then checked that it is connected
     44 * - To connect an allocated phone it need not be locked (assigning
     45 *   pointer is atomic on all platforms)
     46 *
     47 * - To find an empty phone slot, the TASK must be locked
     48 * - To answer a message, the answerbox must be locked
     49 * - The locking of phone and answerbox is done at the ipc_ level.
     50 *   It is perfectly correct to pass unconnected phone to these functions
     51 *   and proper reply will be generated.
     52 *
     53 * - There may be objection that a race may occur when the syscall finds
     54 *   an appropriate call and before executing ipc_send, the phone call might
     55 *   be disconnected and connected elsewhere. As there is no easy solution,
     56 *   the application will be notified by an  'PHONE_DISCONNECTED' message
     57 *   and the phone will not be allocated before the application notifies
     58 *   the kernel subsystem that it does not have any pending calls regarding
     59 *   this phone call.
     60 *
     61 * Locking order
     62 *
     63 * There are 2 possibilities
     64 * - first phone, then answerbox
     65 *   + Easy locking on calls
     66 *   - Very hard traversing list of phones when disconnecting because
     67 *     the phones may disconnect during traversal of list of connected phones.
     68 *     The only possibility is try_lock with restart of list traversal.
     69 *
     70 * - first answerbox, then phone(s)
     71 *   + Easy phone disconnect
     72 *   - Multiple checks needed when sending message
     73 *
     74 * Because the answerbox destroyal is much less frequent operation,
     75 * the first method is chosen.
     76 *
     77 * Cleanup strategy
     78 *
     79 * 1) Disconnect all phones.
     80 *    * Send message 'PHONE_DISCONNECTED' to the target application
     81 * - Once all phones are disconnected, no further calls can arrive
     82 *
     83 * 2) Answer all messages in 'calls' and 'dispatched_calls' queues with
     84 *    appropriate error code.
     85 *
     86 * 3) Wait for all async answers to arrive
     87 * Alternatively - we might try to invalidate all messages by setting some
     88 * flag, that would dispose of the message once it is answered. This
     89 * would need to link all calls in one big list, which we don't currently
     90 * do.
     91 *
    4092 *
    4193 */
     
    57109        /* TODO: locking of call, ripping it from dispatched calls etc.  */
    58110        return (call_t *) callid;
    59 }
    60 
    61 /** Return pointer to phone identified by phoneid or NULL if non-existent */
    62 phone_t * get_phone_and_lock(__native phoneid)
    63 {
    64         phone_t *phone;
    65 
    66         if (phoneid >= IPC_MAX_PHONES)
    67                 return NULL;
    68 
    69         phone = &TASK->phones[phoneid];
    70         spinlock_lock(&phone->lock);
    71         if (!phone->callee) {
    72                 spinlock_unlock(&phone->lock);
    73                 return NULL;
    74         }
    75         /* TODO... */
    76         spinlock_unlock(&phone->lock);
    77         return phone;
    78111}
    79112
     
    112145}
    113146
     147/** Connect phone to a given answerbox
     148 *
     149 * @param phoneid The slot that will be connected
     150 *
     151 * The procedure _enforces_ that the user first marks the phone
     152 * busy (e.g. via phone_alloc) and then connects the phone, otherwise
     153 * race condition may appear.
     154 */
    114155void phone_connect(int phoneid, answerbox_t *box)
    115156{
    116157        phone_t *phone = &TASK->phones[phoneid];
    117158       
     159        ASSERT(phone->busy);
    118160        ipc_phone_connect(phone, box);
    119161}
Note: See TracChangeset for help on using the changeset viewer.