Changeset fbcfd458 in mainline for generic/src/ipc/ipc.c


Ignore:
Timestamp:
2006-03-18T23:02:08Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b4b45210
Parents:
ba81cab
Message:

Untested better IPC functions.

  • There is some bug in MIPS, unpredicatbly sometimes the thread gets mapped

different frame for stack.

File:
1 edited

Legend:

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

    rba81cab rfbcfd458  
    124124}
    125125
    126 /** Disconnect phone from answerbox
    127  *
    128  * It is allowed to call disconnect on already disconnected phone\
    129  */
    130 void ipc_phone_destroy(phone_t *phone)
    131 {
    132         answerbox_t *box = phone->callee;
    133        
    134         ASSERT(box);
    135 
    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);
    146 }
    147 
    148126/** Helper function to facilitate synchronous calls */
    149127void ipc_call_sync(phone_t *phone, call_t *request)
     
    191169}
    192170
     171/* Unsafe unchecking ipc_call */
     172static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
     173{
     174        atomic_inc(&phone->active_calls);
     175        call->data.phone = phone;
     176
     177        spinlock_lock(&box->lock);
     178        list_append(&call->list, &box->calls);
     179        spinlock_unlock(&box->lock);
     180        waitq_wakeup(&box->wq, 0);
     181}
     182
    193183/** Send a asynchronous request using phone to answerbox
    194184 *
     
    201191
    202192        spinlock_lock(&phone->lock);
     193
    203194        box = phone->callee;
    204195        if (!box) {
    205196                /* Trying to send over disconnected phone */
     197                spinlock_unlock(&phone->lock);
     198
     199                call->data.phone = phone;
    206200                IPC_SET_RETVAL(call->data, ENOENT);
    207201                _ipc_answer_free_call(call);
    208202                return;
    209203        }
    210 
    211         spinlock_lock(&box->lock);
    212         list_append(&call->list, &box->calls);
    213         spinlock_unlock(&box->lock);
    214         waitq_wakeup(&box->wq, 0);
     204        _ipc_call(phone, box, call);
    215205       
    216206        spinlock_unlock(&phone->lock);
     207}
     208
     209/** Disconnect phone from answerbox
     210 *
     211 * It is allowed to call disconnect on already disconnected phone
     212 *
     213 * @return 0 - phone disconnected, -1 - the phone was already disconnected
     214 */
     215int ipc_phone_hangup(phone_t *phone)
     216{
     217        answerbox_t *box;
     218        call_t *call;
     219       
     220        spinlock_lock(&phone->lock);
     221        box = phone->callee;
     222        if (!box) {
     223                spinlock_unlock(&phone->lock);
     224                return -1;
     225        }
     226
     227        spinlock_lock(&box->lock);
     228        list_remove(&phone->list);
     229        phone->callee = NULL;
     230        spinlock_unlock(&box->lock);
     231
     232        call = ipc_call_alloc();
     233        IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
     234        call->flags |= IPC_CALL_DISCARD_ANSWER;
     235        _ipc_call(phone, box, call);
     236
     237        phone->busy = 0;
     238
     239        spinlock_unlock(&phone->lock);
     240
     241        return 0;
    217242}
    218243
     
    226251{
    227252        spinlock_lock(&oldbox->lock);
     253        atomic_dec(&call->data.phone->active_calls);
    228254        list_remove(&call->list);
    229255        spinlock_unlock(&oldbox->lock);
     
    242268        call_t *request;
    243269
    244         spinlock_lock(&box->lock);
    245         while (1) {
    246                 if (!list_empty(&box->answers)) {
    247                         /* Handle asynchronous answers */
    248                         request = list_get_instance(box->answers.next, call_t, list);
    249                         list_remove(&request->list);
    250                 } else if (!list_empty(&box->calls)) {
    251                         /* Handle requests */
    252                         request = list_get_instance(box->calls.next, call_t, list);
    253                         list_remove(&request->list);
    254                         /* Append request to dispatch queue */
    255                         list_append(&request->list, &box->dispatched_calls);
    256                         request->flags |= IPC_CALL_DISPATCHED;
    257                 } else {
    258                         if (!(flags & IPC_WAIT_NONBLOCKING)) {
    259                                 /* Wait for event to appear */
    260                                 spinlock_unlock(&box->lock);
    261                                 waitq_sleep(&box->wq);
    262                                 spinlock_lock(&box->lock);
    263                                 continue;
    264                         }
    265                         request = NULL;
    266                 }
    267                 break;
     270restart:     
     271        if (flags & IPC_WAIT_NONBLOCKING) {
     272                if (waitq_sleep_timeout(&box->wq,0,1) == ESYNCH_WOULD_BLOCK)
     273                        return NULL;
     274        } else
     275                waitq_sleep(&box->wq);
     276       
     277        spinlock_lock(&box->lock);
     278        if (!list_empty(&box->answers)) {
     279                /* Handle asynchronous answers */
     280                request = list_get_instance(box->answers.next, call_t, list);
     281                list_remove(&request->list);
     282                printf("%d %P\n", IPC_GET_METHOD(request->data),
     283                       request->data.phone);
     284                atomic_dec(&request->data.phone->active_calls);
     285        } else if (!list_empty(&box->calls)) {
     286                /* Handle requests */
     287                request = list_get_instance(box->calls.next, call_t, list);
     288                list_remove(&request->list);
     289                /* Append request to dispatch queue */
     290                list_append(&request->list, &box->dispatched_calls);
     291                request->flags |= IPC_CALL_DISPATCHED;
     292        } else {
     293                printf("WARNING: Spurious IPC wakeup.\n");
     294                spinlock_unlock(&box->lock);
     295                goto restart;
    268296        }
    269297        spinlock_unlock(&box->lock);
Note: See TracChangeset for help on using the changeset viewer.