Ignore:
File:
1 edited

Legend:

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

    rbe06914 r170332d  
    6666/** Initialize a call structure.
    6767 *
    68  * @param call Call structure to be initialized.
    69  *
     68 * @param call          Call structure to be initialized.
    7069 */
    7170static void _ipc_call_init(call_t *call)
     
    7877
    7978/** Allocate and initialize a call structure.
    80  *
     79 * 
    8180 * The call is initialized, so that the reply will be directed to
    8281 * TASK->answerbox.
    8382 *
    84  * @param flags Parameters for slab_alloc (e.g FRAME_ATOMIC).
    85  *
    86  * @return If flags permit it, return NULL, or initialized kernel
    87  *         call structure.
    88  *
    89  */
    90 call_t *ipc_call_alloc(unsigned int flags)
    91 {
    92         call_t *call = slab_alloc(ipc_call_slab, flags);
     83 * @param flags         Parameters for slab_alloc (e.g FRAME_ATOMIC).
     84 *
     85 * @return              If flags permit it, return NULL, or initialized kernel
     86 *                      call structure.
     87 */
     88call_t *ipc_call_alloc(int flags)
     89{
     90        call_t *call;
     91
     92        call = slab_alloc(ipc_call_slab, flags);
    9393        if (call)
    9494                _ipc_call_init(call);
    95        
     95
    9696        return call;
    9797}
     
    9999/** Deallocate a call structure.
    100100 *
    101  * @param call Call structure to be freed.
    102  *
     101 * @param call          Call structure to be freed.
    103102 */
    104103void ipc_call_free(call_t *call)
     
    112111/** Initialize an answerbox structure.
    113112 *
    114  * @param box  Answerbox structure to be initialized.
    115  * @param task Task to which the answerbox belongs.
    116  *
     113 * @param box           Answerbox structure to be initialized.
     114 * @param task          Task to which the answerbox belongs.
    117115 */
    118116void ipc_answerbox_init(answerbox_t *box, task_t *task)
    119117{
    120         irq_spinlock_initialize(&box->lock, "ipc.box.lock");
    121         irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
     118        spinlock_initialize(&box->lock, "ipc_box_lock");
     119        spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
    122120        waitq_initialize(&box->wq);
    123121        link_initialize(&box->sync_box_link);
     
    133131/** Connect a phone to an answerbox.
    134132 *
    135  * @param phone Initialized phone structure.
    136  * @param box   Initialized answerbox structure.
    137  *
     133 * @param phone         Initialized phone structure.
     134 * @param box           Initialized answerbox structure.
    138135 */
    139136void ipc_phone_connect(phone_t *phone, answerbox_t *box)
    140137{
    141138        mutex_lock(&phone->lock);
    142        
     139
    143140        phone->state = IPC_PHONE_CONNECTED;
    144141        phone->callee = box;
    145        
    146         irq_spinlock_lock(&box->lock, true);
     142
     143        spinlock_lock(&box->lock);
    147144        list_append(&phone->link, &box->connected_phones);
    148         irq_spinlock_unlock(&box->lock, true);
    149        
     145        spinlock_unlock(&box->lock);
     146
    150147        mutex_unlock(&phone->lock);
    151148}
     
    153150/** Initialize a phone structure.
    154151 *
    155  * @param phone Phone structure to be initialized.
    156  *
     152 * @param phone         Phone structure to be initialized.
    157153 */
    158154void ipc_phone_init(phone_t *phone)
     
    166162/** Helper function to facilitate synchronous calls.
    167163 *
    168  * @param phone   Destination kernel phone structure.
    169  * @param request Call structure with request.
    170  *
    171  * @return EOK on success or EINTR if the sleep was interrupted.
    172  *
     164 * @param phone         Destination kernel phone structure.
     165 * @param request       Call structure with request.
     166 *
     167 * @return              EOK on success or EINTR if the sleep was interrupted.
    173168 */
    174169int ipc_call_sync(phone_t *phone, call_t *request)
    175170{
    176         answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
     171        answerbox_t *sync_box;
     172        ipl_t ipl;
     173
     174        sync_box = slab_alloc(ipc_answerbox_slab, 0);
    177175        ipc_answerbox_init(sync_box, TASK);
    178        
     176
    179177        /*
    180178         * Put the answerbox on the TASK's list of synchronous answerboxes so
    181179         * that it can be cleaned up if the call is interrupted.
    182180         */
    183         irq_spinlock_lock(&TASK->lock, true);
     181        ipl = interrupts_disable();
     182        spinlock_lock(&TASK->lock);
    184183        list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
    185         irq_spinlock_unlock(&TASK->lock, true);
    186        
     184        spinlock_unlock(&TASK->lock);
     185        interrupts_restore(ipl);
     186
    187187        /* We will receive data in a special box. */
    188188        request->callerbox = sync_box;
    189        
     189
    190190        ipc_call(phone, request);
    191191        if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    192192            SYNCH_FLAGS_INTERRUPTIBLE)) {
    193                 /* The answerbox and the call will be freed by ipc_cleanup(). */
     193                /* The answerbox and the call will be freed by ipc_cleanup(). */
    194194                return EINTR;
    195195        }
    196        
     196
    197197        /*
    198198         * The answer arrived without interruption so we can remove the
    199199         * answerbox from the TASK's list of synchronous answerboxes.
    200200         */
    201         irq_spinlock_lock(&TASK->lock, true);
     201        (void) interrupts_disable();
     202        spinlock_lock(&TASK->lock);
    202203        list_remove(&sync_box->sync_box_link);
    203         irq_spinlock_unlock(&TASK->lock, true);
    204        
     204        spinlock_unlock(&TASK->lock);
     205        interrupts_restore(ipl);
     206
    205207        slab_free(ipc_answerbox_slab, sync_box);
    206208        return EOK;
     
    209211/** Answer a message which was not dispatched and is not listed in any queue.
    210212 *
    211  * @param call       Call structure to be answered.
    212  * @param selflocked If true, then TASK->answebox is locked.
    213  *
     213 * @param call          Call structure to be answered.
     214 * @param selflocked    If true, then TASK->answebox is locked.
    214215 */
    215216static void _ipc_answer_free_call(call_t *call, bool selflocked)
     
    217218        answerbox_t *callerbox = call->callerbox;
    218219        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    219        
     220        ipl_t ipl;
     221
    220222        /* Count sent answer */
    221         irq_spinlock_lock(&TASK->lock, true);
     223        ipl = interrupts_disable();
     224        spinlock_lock(&TASK->lock);
    222225        TASK->ipc_info.answer_sent++;
    223         irq_spinlock_unlock(&TASK->lock, true);
    224        
     226        spinlock_unlock(&TASK->lock);
     227        interrupts_restore(ipl);
     228
    225229        call->flags |= IPC_CALL_ANSWERED;
    226        
     230
    227231        if (call->flags & IPC_CALL_FORWARDED) {
    228232                if (call->caller_phone) {
     
    231235                }
    232236        }
    233        
     237
    234238        if (do_lock)
    235                 irq_spinlock_lock(&callerbox->lock, true);
    236        
     239                spinlock_lock(&callerbox->lock);
    237240        list_append(&call->link, &callerbox->answers);
    238        
    239241        if (do_lock)
    240                 irq_spinlock_unlock(&callerbox->lock, true);
    241        
     242                spinlock_unlock(&callerbox->lock);
    242243        waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
    243244}
     
    245246/** Answer a message which is in a callee queue.
    246247 *
    247  * @param box  Answerbox that is answering the message.
    248  * @param call Modified request that is being sent back.
    249  *
     248 * @param box           Answerbox that is answering the message.
     249 * @param call          Modified request that is being sent back.
    250250 */
    251251void ipc_answer(answerbox_t *box, call_t *call)
    252252{
    253253        /* Remove from active box */
    254         irq_spinlock_lock(&box->lock, true);
     254        spinlock_lock(&box->lock);
    255255        list_remove(&call->link);
    256         irq_spinlock_unlock(&box->lock, true);
    257        
     256        spinlock_unlock(&box->lock);
    258257        /* Send back answer */
    259258        _ipc_answer_free_call(call, false);
     
    265264 * message and sending it as a normal answer.
    266265 *
    267  * @param phone Phone structure the call should appear to come from.
    268  * @param call  Call structure to be answered.
    269  * @param err   Return value to be used for the answer.
    270  *
     266 * @param phone         Phone structure the call should appear to come from.
     267 * @param call          Call structure to be answered.
     268 * @param err           Return value to be used for the answer.
    271269 */
    272270void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err)
     
    280278/** Unsafe unchecking version of ipc_call.
    281279 *
    282  * @param phone Phone structure the call comes from.
    283  * @param box   Destination answerbox structure.
    284  * @param call  Call structure with request.
    285  *
     280 * @param phone         Phone structure the call comes from.
     281 * @param box           Destination answerbox structure.
     282 * @param call          Call structure with request.
    286283 */
    287284static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
    288285{
     286        ipl_t ipl;
     287
    289288        /* Count sent ipc call */
    290         irq_spinlock_lock(&TASK->lock, true);
     289        ipl = interrupts_disable();
     290        spinlock_lock(&TASK->lock);
    291291        TASK->ipc_info.call_sent++;
    292         irq_spinlock_unlock(&TASK->lock, true);
    293        
     292        spinlock_unlock(&TASK->lock);
     293        interrupts_restore(ipl);
     294
    294295        if (!(call->flags & IPC_CALL_FORWARDED)) {
    295296                atomic_inc(&phone->active_calls);
    296297                call->data.phone = phone;
    297298        }
    298        
    299         irq_spinlock_lock(&box->lock, true);
     299
     300        spinlock_lock(&box->lock);
    300301        list_append(&call->link, &box->calls);
    301         irq_spinlock_unlock(&box->lock, true);
    302        
     302        spinlock_unlock(&box->lock);
    303303        waitq_wakeup(&box->wq, WAKEUP_FIRST);
    304304}
     
    306306/** Send an asynchronous request using a phone to an answerbox.
    307307 *
    308  * @param phone Phone structure the call comes from and which is
    309  *              connected to the destination answerbox.
    310  * @param call  Call structure with request.
    311  *
    312  * @return Return 0 on success, ENOENT on error.
    313  *
     308 * @param phone         Phone structure the call comes from and which is
     309 *                      connected to the destination answerbox.
     310 * @param call          Call structure with request.
     311 *
     312 * @return              Return 0 on success, ENOENT on error.
    314313 */
    315314int ipc_call(phone_t *phone, call_t *call)
    316315{
     316        answerbox_t *box;
     317
    317318        mutex_lock(&phone->lock);
    318319        if (phone->state != IPC_PHONE_CONNECTED) {
     
    327328                                ipc_backsend_err(phone, call, ENOENT);
    328329                }
    329                
    330330                return ENOENT;
    331331        }
    332        
    333         answerbox_t *box = phone->callee;
     332        box = phone->callee;
    334333        _ipc_call(phone, box, call);
    335334       
     
    343342 * lazily later.
    344343 *
    345  * @param phone Phone structure to be hung up.
    346  *
    347  * @return 0 if the phone is disconnected.
    348  * @return -1 if the phone was already disconnected.
    349  *
     344 * @param phone         Phone structure to be hung up.
     345 *             
     346 * @return              Return 0 if the phone is disconnected.
     347 *                      Return -1 if the phone was already disconnected.
    350348 */
    351349int ipc_phone_hangup(phone_t *phone)
    352350{
     351        answerbox_t *box;
     352        call_t *call;
     353       
    353354        mutex_lock(&phone->lock);
    354355        if (phone->state == IPC_PHONE_FREE ||
     
    358359                return -1;
    359360        }
    360        
    361         answerbox_t *box = phone->callee;
     361        box = phone->callee;
    362362        if (phone->state != IPC_PHONE_SLAMMED) {
    363363                /* Remove myself from answerbox */
    364                 irq_spinlock_lock(&box->lock, true);
     364                spinlock_lock(&box->lock);
    365365                list_remove(&phone->link);
    366                 irq_spinlock_unlock(&box->lock, true);
    367                
    368                 call_t *call = ipc_call_alloc(0);
     366                spinlock_unlock(&box->lock);
     367
     368                call = ipc_call_alloc(0);
    369369                IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
    370370                call->flags |= IPC_CALL_DISCARD_ANSWER;
    371371                _ipc_call(phone, box, call);
    372372        }
    373        
     373
    374374        phone->state = IPC_PHONE_HUNGUP;
    375375        mutex_unlock(&phone->lock);
    376        
     376
    377377        return 0;
    378378}
     
    380380/** Forwards call from one answerbox to another one.
    381381 *
    382  * @param call     Call structure to be redirected.
    383  * @param newphone Phone structure to target answerbox.
    384  * @param oldbox   Old answerbox structure.
    385  * @param mode     Flags that specify mode of the forward operation.
    386  *
    387  * @return 0 if forwarding succeeded or an error code if
    388  *         there was an error.
    389  *
     382 * @param call          Call structure to be redirected.
     383 * @param newphone      Phone structure to target answerbox.
     384 * @param oldbox        Old answerbox structure.
     385 * @param mode          Flags that specify mode of the forward operation.
     386 *
     387 * @return              Return 0 if forwarding succeeded or an error code if
     388 *                      there was error.
     389 * 
    390390 * The return value serves only as an information for the forwarder,
    391391 * the original caller is notified automatically with EFORWARD.
    392  *
    393  */
    394 int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox,
    395     unsigned int mode)
    396 {
     392 */
     393int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox, int mode)
     394{
     395        ipl_t ipl;
     396
    397397        /* Count forwarded calls */
    398         irq_spinlock_lock(&TASK->lock, true);
     398        ipl = interrupts_disable();
     399        spinlock_lock(&TASK->lock);
    399400        TASK->ipc_info.forwarded++;
    400         irq_spinlock_pass(&TASK->lock, &oldbox->lock);
     401        spinlock_unlock(&TASK->lock);
     402        interrupts_restore(ipl);
     403
     404        spinlock_lock(&oldbox->lock);
    401405        list_remove(&call->link);
    402         irq_spinlock_unlock(&oldbox->lock, true);
    403        
     406        spinlock_unlock(&oldbox->lock);
     407
    404408        if (mode & IPC_FF_ROUTE_FROM_ME) {
    405409                if (!call->caller_phone)
     
    407411                call->data.phone = newphone;
    408412        }
    409        
     413
    410414        return ipc_call(newphone, call);
    411415}
     
    414418/** Wait for a phone call.
    415419 *
    416  * @param box   Answerbox expecting the call.
    417  * @param usec  Timeout in microseconds. See documentation for
    418  *              waitq_sleep_timeout() for decription of its special
    419  *              meaning.
    420  * @param flags Select mode of sleep operation. See documentation for
    421  *              waitq_sleep_timeout() for description of its special
    422  *              meaning.
    423  *
    424  * @return Recived call structure or NULL.
    425  *
     420 * @param box           Answerbox expecting the call.
     421 * @param usec          Timeout in microseconds. See documentation for
     422 *                      waitq_sleep_timeout() for decription of its special
     423 *                      meaning.
     424 * @param flags         Select mode of sleep operation. See documentation for
     425 *                      waitq_sleep_timeout() for description of its special
     426 *                      meaning.
     427 * @return              Recived call structure or NULL.
     428 *
    426429 * To distinguish between a call and an answer, have a look at call->flags.
    427  *
    428  */
    429 call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, unsigned int flags)
     430 */
     431call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags)
    430432{
    431433        call_t *request;
     434        ipl_t ipl;
    432435        uint64_t irq_cnt = 0;
    433436        uint64_t answer_cnt = 0;
    434437        uint64_t call_cnt = 0;
    435438        int rc;
    436        
     439
    437440restart:
    438441        rc = waitq_sleep_timeout(&box->wq, usec, flags);
     
    440443                return NULL;
    441444       
    442         irq_spinlock_lock(&box->lock, true);
     445        spinlock_lock(&box->lock);
    443446        if (!list_empty(&box->irq_notifs)) {
    444                 /* Count received IRQ notification */
    445                 irq_cnt++;
    446                
    447                 irq_spinlock_lock(&box->irq_lock, false);
    448                
     447                /* Count recieved IRQ notification */
     448                irq_cnt++;     
     449
     450                ipl = interrupts_disable();
     451                spinlock_lock(&box->irq_lock);
     452
    449453                request = list_get_instance(box->irq_notifs.next, call_t, link);
    450454                list_remove(&request->link);
    451                
    452                 irq_spinlock_unlock(&box->irq_lock, false);
     455
     456                spinlock_unlock(&box->irq_lock);
     457                interrupts_restore(ipl);
    453458        } else if (!list_empty(&box->answers)) {
    454                 /* Count received answer */
     459                /* Count recieved answer */
    455460                answer_cnt++;
    456                
     461
    457462                /* Handle asynchronous answers */
    458463                request = list_get_instance(box->answers.next, call_t, link);
     
    460465                atomic_dec(&request->data.phone->active_calls);
    461466        } else if (!list_empty(&box->calls)) {
    462                 /* Count received call */
     467                /* Count recieved call */
    463468                call_cnt++;
    464                
     469
    465470                /* Handle requests */
    466471                request = list_get_instance(box->calls.next, call_t, link);
    467472                list_remove(&request->link);
    468                
    469473                /* Append request to dispatch queue */
    470474                list_append(&request->link, &box->dispatched_calls);
    471475        } else {
    472476                /* This can happen regularly after ipc_cleanup */
    473                 irq_spinlock_unlock(&box->lock, true);
     477                spinlock_unlock(&box->lock);
    474478                goto restart;
    475479        }
     480        spinlock_unlock(&box->lock);
    476481       
    477         irq_spinlock_pass(&box->lock, &TASK->lock);
    478        
    479         TASK->ipc_info.irq_notif_received += irq_cnt;
    480         TASK->ipc_info.answer_received += answer_cnt;
    481         TASK->ipc_info.call_received += call_cnt;
    482        
    483         irq_spinlock_unlock(&TASK->lock, true);
    484        
     482        ipl = interrupts_disable();
     483        spinlock_lock(&TASK->lock);
     484        TASK->ipc_info.irq_notif_recieved += irq_cnt;
     485        TASK->ipc_info.answer_recieved += answer_cnt;
     486        TASK->ipc_info.call_recieved += call_cnt;
     487        spinlock_unlock(&TASK->lock);
     488        interrupts_restore(ipl);
     489
    485490        return request;
    486491}
     
    488493/** Answer all calls from list with EHANGUP answer.
    489494 *
    490  * @param lst Head of the list to be cleaned up.
    491  *
     495 * @param lst           Head of the list to be cleaned up.
    492496 */
    493497void ipc_cleanup_call_list(link_t *lst)
    494498{
     499        call_t *call;
     500
    495501        while (!list_empty(lst)) {
    496                 call_t *call = list_get_instance(lst->next, call_t, link);
     502                call = list_get_instance(lst->next, call_t, link);
    497503                if (call->buffer)
    498504                        free(call->buffer);
    499                
    500505                list_remove(&call->link);
    501                
     506
    502507                IPC_SET_RETVAL(call->data, EHANGUP);
    503508                _ipc_answer_free_call(call, true);
     
    507512/** Disconnects all phones connected to an answerbox.
    508513 *
    509  * @param box        Answerbox to disconnect phones from.
    510  * @param notify_box If true, the answerbox will get a hangup message for
    511  *                   each disconnected phone.
    512  *
     514 * @param box           Answerbox to disconnect phones from.
     515 * @param notify_box    If true, the answerbox will get a hangup message for
     516 *                      each disconnected phone.
    513517 */
    514518void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
     
    516520        phone_t *phone;
    517521        DEADLOCK_PROBE_INIT(p_phonelck);
    518        
    519         call_t *call = notify_box ? ipc_call_alloc(0) : NULL;
    520        
     522        ipl_t ipl;
     523        call_t *call;
     524
     525        call = notify_box ? ipc_call_alloc(0) : NULL;
     526
    521527        /* Disconnect all phones connected to our answerbox */
    522528restart_phones:
    523         irq_spinlock_lock(&box->lock, true);
     529        ipl = interrupts_disable();
     530        spinlock_lock(&box->lock);
    524531        while (!list_empty(&box->connected_phones)) {
    525532                phone = list_get_instance(box->connected_phones.next,
    526533                    phone_t, link);
    527534                if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
    528                         irq_spinlock_unlock(&box->lock, true);
     535                        spinlock_unlock(&box->lock);
     536                        interrupts_restore(ipl);
    529537                        DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
    530538                        goto restart_phones;
     
    533541                /* Disconnect phone */
    534542                ASSERT(phone->state == IPC_PHONE_CONNECTED);
    535                
     543
    536544                list_remove(&phone->link);
    537545                phone->state = IPC_PHONE_SLAMMED;
    538                
     546
    539547                if (notify_box) {
    540548                        mutex_unlock(&phone->lock);
    541                         irq_spinlock_unlock(&box->lock, true);
    542                        
     549                        spinlock_unlock(&box->lock);
     550                        interrupts_restore(ipl);
     551
    543552                        /*
    544553                         * Send one message to the answerbox for each
     
    550559                        call->flags |= IPC_CALL_DISCARD_ANSWER;
    551560                        _ipc_call(phone, box, call);
    552                        
     561
    553562                        /* Allocate another call in advance */
    554563                        call = ipc_call_alloc(0);
    555                        
     564
    556565                        /* Must start again */
    557566                        goto restart_phones;
    558567                }
    559                
     568
    560569                mutex_unlock(&phone->lock);
    561570        }
    562        
    563         irq_spinlock_unlock(&box->lock, true);
    564        
     571
     572        spinlock_unlock(&box->lock);
     573        interrupts_restore(ipl);
     574
    565575        /* Free unused call */
    566576        if (call)
     
    568578}
    569579
    570 /** Clean up all IPC communication of the current task.
     580/** Cleans up all IPC communication of the current task.
    571581 *
    572582 * Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
    573583 * have to change it as well if you want to cleanup other tasks than TASK.
    574  *
    575584 */
    576585void ipc_cleanup(void)
    577586{
     587        int i;
     588        call_t *call;
     589        ipl_t ipl;
     590
    578591        /* Disconnect all our phones ('ipc_phone_hangup') */
    579         size_t i;
    580592        for (i = 0; i < IPC_MAX_PHONES; i++)
    581593                ipc_phone_hangup(&TASK->phones[i]);
    582        
     594
    583595        /* Unsubscribe from any event notifications. */
    584596        event_cleanup_answerbox(&TASK->answerbox);
    585        
     597
    586598        /* Disconnect all connected irqs */
    587599        ipc_irq_cleanup(&TASK->answerbox);
    588        
     600
    589601        /* Disconnect all phones connected to our regular answerbox */
    590602        ipc_answerbox_slam_phones(&TASK->answerbox, false);
    591        
     603
    592604#ifdef CONFIG_UDEBUG
    593605        /* Clean up kbox thread and communications */
    594606        ipc_kbox_cleanup();
    595607#endif
    596        
     608
    597609        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    598         irq_spinlock_lock(&TASK->answerbox.lock, true);
     610        spinlock_lock(&TASK->answerbox.lock);
    599611        ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
    600612        ipc_cleanup_call_list(&TASK->answerbox.calls);
    601         irq_spinlock_unlock(&TASK->answerbox.lock, true);
     613        spinlock_unlock(&TASK->answerbox.lock);
    602614       
    603615        /* Wait for all answers to interrupted synchronous calls to arrive */
    604         ipl_t ipl = interrupts_disable();
     616        ipl = interrupts_disable();
    605617        while (!list_empty(&TASK->sync_box_head)) {
    606618                answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
    607619                    answerbox_t, sync_box_link);
    608                
     620
    609621                list_remove(&box->sync_box_link);
    610                 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
     622                call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    611623                    SYNCH_FLAGS_NONE);
    612624                ipc_call_free(call);
     
    614626        }
    615627        interrupts_restore(ipl);
    616        
     628
    617629        /* Wait for all answers to asynchronous calls to arrive */
    618         while (true) {
    619                 /*
    620                  * Go through all phones, until they are all FREE
    621                  * Locking is not needed, no one else should modify
    622                  * it when we are in cleanup
    623                  */
     630        while (1) {
     631                /* Go through all phones, until all are FREE... */
     632                /* Locking not needed, no one else should modify
     633                 * it, when we are in cleanup */
    624634                for (i = 0; i < IPC_MAX_PHONES; i++) {
    625635                        if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
     
    629639                        }
    630640                       
    631                         /*
    632                          * Just for sure, we might have had some
    633                          * IPC_PHONE_CONNECTING phones
    634                          */
     641                        /* Just for sure, we might have had some
     642                         * IPC_PHONE_CONNECTING phones */
    635643                        if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
    636644                                ipc_phone_hangup(&TASK->phones[i]);
    637                        
    638                         /*
    639                          * If the hangup succeeded, it has sent a HANGUP
     645                        /* If the hangup succeeded, it has sent a HANGUP
    640646                         * message, the IPC is now in HUNGUP state, we
    641                          * wait for the reply to come
    642                          */
     647                         * wait for the reply to come */
    643648                       
    644649                        if (TASK->phones[i].state != IPC_PHONE_FREE)
    645650                                break;
    646651                }
    647                
    648                 /* Got into cleanup */
     652                /* Voila, got into cleanup */
    649653                if (i == IPC_MAX_PHONES)
    650654                        break;
    651655               
    652                 call_t *call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
     656                call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
    653657                    SYNCH_FLAGS_NONE);
    654658                ASSERT((call->flags & IPC_CALL_ANSWERED) ||
     
    662666                if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
    663667                        atomic_dec(&TASK->active_calls);
    664                
    665668                ipc_call_free(call);
    666669        }
    667670}
    668671
    669 /** Initilize IPC subsystem
    670  *
    671  */
     672
     673/** Initilize IPC subsystem */
    672674void ipc_init(void)
    673675{
     
    678680}
    679681
     682
    680683/** List answerbox contents.
    681684 *
    682  * @param taskid Task ID.
    683  *
     685 * @param taskid        Task ID.
    684686 */
    685687void ipc_print_task(task_id_t taskid)
    686688{
    687         irq_spinlock_lock(&tasks_lock, true);
    688         task_t *task = task_find_by_id(taskid);
     689        task_t *task;
     690        int i;
     691        call_t *call;
     692        link_t *tmp;
     693        ipl_t ipl;
    689694       
     695        ipl = interrupts_disable();
     696        spinlock_lock(&tasks_lock);
     697        task = task_find_by_id(taskid);
     698        if (task)
     699                spinlock_lock(&task->lock);
     700        spinlock_unlock(&tasks_lock);
    690701        if (!task) {
    691                 irq_spinlock_unlock(&tasks_lock, true);
     702                interrupts_restore(ipl);
    692703                return;
    693704        }
    694        
    695         /* Hand-over-hand locking */
    696         irq_spinlock_exchange(&tasks_lock, &task->lock);
    697        
     705
    698706        /* Print opened phones & details */
    699707        printf("PHONE:\n");
    700        
    701         size_t i;
    702708        for (i = 0; i < IPC_MAX_PHONES; i++) {
    703709                if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
     
    705711                        continue;
    706712                }
    707                
    708713                if (task->phones[i].state != IPC_PHONE_FREE) {
    709                         printf("%" PRIs ": ", i);
    710                        
     714                        printf("%d: ", i);
    711715                        switch (task->phones[i].state) {
    712716                        case IPC_PHONE_CONNECTING:
     
    714718                                break;
    715719                        case IPC_PHONE_CONNECTED:
    716                                 printf("connected to: %p ",
    717                                     task->phones[i].callee);
     720                                printf("connected to: %p ", 
     721                                       task->phones[i].callee);
    718722                                break;
    719723                        case IPC_PHONE_SLAMMED:
    720724                                printf("slammed by: %p ",
    721                                     task->phones[i].callee);
     725                                       task->phones[i].callee);
    722726                                break;
    723727                        case IPC_PHONE_HUNGUP:
    724728                                printf("hung up - was: %p ",
    725                                     task->phones[i].callee);
     729                                       task->phones[i].callee);
    726730                                break;
    727731                        default:
    728732                                break;
    729733                        }
    730                        
    731                         printf("active: %" PRIun "\n",
     734                        printf("active: %ld\n",
    732735                            atomic_get(&task->phones[i].active_calls));
    733736                }
    734                
    735737                mutex_unlock(&task->phones[i].lock);
    736738        }
    737        
    738         irq_spinlock_lock(&task->answerbox.lock, false);
    739        
    740         link_t *cur;
    741        
     739
     740
    742741        /* Print answerbox - calls */
     742        spinlock_lock(&task->answerbox.lock);
    743743        printf("ABOX - CALLS:\n");
    744         for (cur = task->answerbox.calls.next; cur != &task->answerbox.calls;
    745             cur = cur->next) {
    746                 call_t *call = list_get_instance(cur, call_t, link);
     744        for (tmp = task->answerbox.calls.next; tmp != &task->answerbox.calls;
     745            tmp = tmp->next) {
     746                call = list_get_instance(tmp, call_t, link);
    747747                printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    748748                    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
     
    754754                    call->flags);
    755755        }
    756        
    757         /* Print answerbox - dispatched calls */
     756        /* Print answerbox - calls */
    758757        printf("ABOX - DISPATCHED CALLS:\n");
    759         for (cur = task->answerbox.dispatched_calls.next;
    760             cur != &task->answerbox.dispatched_calls;
    761             cur = cur->next) {
    762                 call_t *call = list_get_instance(cur, call_t, link);
     758        for (tmp = task->answerbox.dispatched_calls.next;
     759            tmp != &task->answerbox.dispatched_calls;
     760            tmp = tmp->next) {
     761                call = list_get_instance(tmp, call_t, link);
    763762                printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    764763                    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
     
    770769                    call->flags);
    771770        }
    772        
    773         /* Print answerbox - answers */
     771        /* Print answerbox - calls */
    774772        printf("ABOX - ANSWERS:\n");
    775         for (cur = task->answerbox.answers.next;
    776             cur != &task->answerbox.answers;
    777             cur = cur->next) {
    778                 call_t *call = list_get_instance(cur, call_t, link);
     773        for (tmp = task->answerbox.answers.next;
     774            tmp != &task->answerbox.answers;
     775            tmp = tmp->next) {
     776                call = list_get_instance(tmp, call_t, link);
    779777                printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun
    780778                    " A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n",
     
    784782                    call->flags);
    785783        }
    786        
    787         irq_spinlock_unlock(&task->answerbox.lock, false);
    788         irq_spinlock_unlock(&task->lock, true);
     784
     785        spinlock_unlock(&task->answerbox.lock);
     786        spinlock_unlock(&task->lock);
     787        interrupts_restore(ipl);
    789788}
    790789
Note: See TracChangeset for help on using the changeset viewer.