Changeset ba81cab in mainline for generic/src/ipc/ipc.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/ipc.c

    r81c4c6da rba81cab  
    5050static slab_cache_t *ipc_call_slab;
    5151
     52/* Initialize new call */
     53static void _ipc_call_init(call_t *call)
     54{
     55        memsetb((__address)call, sizeof(*call), 0);
     56        call->callerbox = &TASK->answerbox;
     57        call->sender = TASK;
     58}
     59
    5260/** Allocate & initialize call structure
    5361 *
     
    6068
    6169        call = slab_alloc(ipc_call_slab, 0);
    62         memsetb((__address)call, sizeof(*call), 0);
    63         call->callerbox = &TASK->answerbox;
    64         call->sender = TASK;
     70        _ipc_call_init(call);
    6571
    6672        return call;
     
    6874
    6975/** Initialize allocated call */
    70 void ipc_call_init(call_t *call)
    71 {
    72         call->callerbox = &TASK->answerbox;
    73         call->flags = IPC_CALL_STATIC_ALLOC;
    74         call->sender = TASK;
     76void ipc_call_static_init(call_t *call)
     77{
     78        _ipc_call_init(call);
     79        call->flags |= IPC_CALL_STATIC_ALLOC;
    7580}
    7681
     
    97102void ipc_phone_connect(phone_t *phone, answerbox_t *box)
    98103{
     104        spinlock_lock(&phone->lock);
     105
    99106        ASSERT(!phone->callee);
    100107        phone->busy = 1;
     
    104111        list_append(&phone->list, &box->connected_phones);
    105112        spinlock_unlock(&box->lock);
     113
     114        spinlock_unlock(&phone->lock);
    106115}
    107116
     
    115124}
    116125
    117 /** Disconnect phone from answerbox */
     126/** Disconnect phone from answerbox
     127 *
     128 * It is allowed to call disconnect on already disconnected phone\
     129 */
    118130void ipc_phone_destroy(phone_t *phone)
    119131{
     
    122134        ASSERT(box);
    123135
    124         spinlock_lock(&box->lock);
    125         list_remove(&phone->list);
    126         spinlock_unlock(&box->lock);
     136        spinlock_lock(&phone->lock);
     137        spinlock_lock(&box->lock);
     138
     139        if (phone->callee) {
     140                list_remove(&phone->list);
     141                phone->callee = NULL;
     142        }
     143
     144        spinlock_unlock(&box->lock);
     145        spinlock_unlock(&phone->lock);
    127146}
    128147
     
    141160}
    142161
     162/** Answer message that was not dispatched and is not entered in
     163 * any queue
     164 */
     165static void _ipc_answer_free_call(call_t *call)
     166{
     167        answerbox_t *callerbox = call->callerbox;
     168
     169        call->flags &= ~IPC_CALL_DISPATCHED;
     170        call->flags |= IPC_CALL_ANSWERED;
     171
     172        spinlock_lock(&callerbox->lock);
     173        list_append(&call->list, &callerbox->answers);
     174        spinlock_unlock(&callerbox->lock);
     175        waitq_wakeup(&callerbox->wq, 0);
     176}
     177
     178/** Answer message, that is in callee queue
     179 *
     180 * @param box Answerbox that is answering the message
     181 * @param call Modified request that is being sent back
     182 */
     183void ipc_answer(answerbox_t *box, call_t *call)
     184{
     185        /* Remove from active box */
     186        spinlock_lock(&box->lock);
     187        list_remove(&call->list);
     188        spinlock_unlock(&box->lock);
     189        /* Send back answer */
     190        _ipc_answer_free_call(call);
     191}
     192
    143193/** Send a asynchronous request using phone to answerbox
    144194 *
     
    148198void ipc_call(phone_t *phone, call_t *call)
    149199{
    150         answerbox_t *box = phone->callee;
    151 
    152         ASSERT(box);
     200        answerbox_t *box;
     201
     202        spinlock_lock(&phone->lock);
     203        box = phone->callee;
     204        if (!box) {
     205                /* Trying to send over disconnected phone */
     206                IPC_SET_RETVAL(call->data, ENOENT);
     207                _ipc_answer_free_call(call);
     208                return;
     209        }
    153210
    154211        spinlock_lock(&box->lock);
     
    156213        spinlock_unlock(&box->lock);
    157214        waitq_wakeup(&box->wq, 0);
     215       
     216        spinlock_unlock(&phone->lock);
    158217}
    159218
     
    164223 * @param oldbox Old answerbox
    165224 */
    166 void ipc_forward(call_t *call, answerbox_t *newbox, answerbox_t *oldbox)
     225void ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox)
    167226{
    168227        spinlock_lock(&oldbox->lock);
     
    170229        spinlock_unlock(&oldbox->lock);
    171230
    172         spinlock_lock(&newbox->lock);
    173         list_append(&call->list, &newbox->calls);
    174         spinlock_lock(&newbox->lock);
    175         waitq_wakeup(&newbox->wq, 0);
    176 }
    177 
    178 /** Answer message back to phone
    179  *
    180  * @param box Answerbox that is answering the message
    181  * @param request Modified request that is being sent back
    182  */
    183 void ipc_answer(answerbox_t *box, call_t *request)
    184 {
    185         answerbox_t *callerbox = request->callerbox;
    186 
    187         request->flags &= ~IPC_CALL_DISPATCHED;
    188         request->flags |= IPC_CALL_ANSWERED;
    189 
    190         spinlock_lock(&box->lock);
    191         list_remove(&request->list);
    192         spinlock_unlock(&box->lock);
    193 
    194         spinlock_lock(&callerbox->lock);
    195         list_append(&request->list, &callerbox->answers);
    196         spinlock_unlock(&callerbox->lock);
    197         waitq_wakeup(&callerbox->wq, 0);
    198 }
     231        ipc_call(newphone, call);
     232}
     233
    199234
    200235/** Wait for phone call
Note: See TracChangeset for help on using the changeset viewer.